0

A docker container with a small Python app inside it is deployed to a Kubernetes cluster that has a redis master and a redis slave service running in the cluster. The Python app inside the Docker container is not able to connect to the redis across the cluster because the Python app is not configured properly to find redis on the network.

What specific changes need to be made to the code below in order for the Python app in app.py to be able to communicate successfully with the redis running in the same cluster?

PYTHON APP CODE

Here is app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
        "<b>Hostname:</b> {hostname}<br/>" \
        "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)


REDIS SERVICES IN THE SAME KUBERNETES CLUSTER

The redis master and redis slave running in the cluster are from public registries and are brought into the cluster by running kubectl apply -f with the following JSON:

Redis Master replication controller JSON from this link.
Redis Master service JSON from this link.
Redis Slave replication controller JSON from this link.
Redis Slave service JSON from this link.

2 Answers 2

5

What specific changes need to be made to the code below in order for the python app in app.py to be able to communicate successfully with the redis running in the same cluster?

redis = Redis(host="redis-master", db=0, socket_connect_timeout=2, socket_timeout=2)

because the Service you installed is named redis-master, although that simple change I proposed above assumes that the flask app is running in the same kubernetes namespace as the redis-master Service. If that isn't true, you'll need to switch it to read:

redis = Redis(host="redis-master.whatever-namespace.svc.cluster.local",

and replace whatever-namespace with the actual, correct, namespace. If you don't remember or know, kubectl get --all-namespaces=true svc | grep redis-master will remind you.

Sign up to request clarification or add additional context in comments.

2 Comments

This works, so I am marking it has the accepted answer. Thank you. But for the education of other readers including me, can you please elaborate on all four arguments in the redis = Redis(host="redis-master", db=0, socket_connect_timeout=2, socket_timeout=2) command? I would like to understand what that is actually doing, and you only explain the host name in your current answer version.
well, not all 4 arguments, no; there is plenty of documentation for that. But the host= part is because kubernetes has its own DNS server, in which every Service is registered under its fully-qualified "cluster name", meaning the name: of the Service, and its namespace:, followed by svc.cluster.local (which one can customize, but I've never seen such a thing happen). Due to the way resolv.conf works, as long as the DNS search path matches, you can just use the Service name, which is apparently what works in your case.
0

if the service of redis-master is in the same namespace of flask app deployment or pod whatever use this redis-master as env variable inside the deployment file of your flask app, if not the same namespace use redis-master.whatever-namespace.svc.cluster.local but sure while dockerizing your app use .env file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.