I have two Docker containers running Flask
and redis
each that communicate well when linked using Docker container linking.
I am trying to deploy the same on Kubernetes using services and pods but, it's not working. I am learning Kubernetes so I must be doing something wrong here.
Below are the Docker commands that work well:
$ docker run -d --name=redis -v /opt/redis:/redis -p 6379 redis_image redis-server
$ docker run -d -p 5000:5000 --link redis:redis --name flask flask_image
The kubernetes pod and services files are as below:
pod-redis.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
name: redis
app: redis
spec:
containers:
- name: redis
image: dharmit/redis
command:
- "redis-server"
volumeMounts:
- mountPath: /redis
name: redis-store
volumes:
- name: redis-store
hostPath:
path: /opt/redis
service-redis.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
name: redis
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
pod-flask.yaml
apiVersion: v1
kind: Pod
metadata:
name: flask
labels:
name: flask
app: flask
spec:
containers:
- name: flask
image: dharmit/flask
ports:
- containerPort: 5000
service-flask.yaml
apiVersion: v1
kind: Service
metadata:
name: flask
labels:
name: flask
spec:
ports:
- port: 5000
selector:
app: flask
When I do kubectl create -f /path/to/dir/
all services and pods start up fine and get listed by kubectl
commands. But when I try to access the port 5000, Flask app complains that it cannot communicate with redis container. Below are the service related outputs:
flask service
Name: flask
Namespace: default
Labels: name=flask
Selector: app=flask
Type: ClusterIP
IP: 10.254.155.179
Port: <unnamed> 5000/TCP
Endpoints: 172.17.0.2:5000
Session Affinity: None
No events.
redis service
Name: redis
Namespace: default
Labels: name=redis
Selector: app=redis
Type: ClusterIP
IP: 10.254.153.217
Port: <unnamed> 6379/TCP
Endpoints: 172.17.0.1:6379
Session Affinity: None
No events.
And the output of curl
command:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/app/app/views.py", line 9, in index
if r.get("count") == None:
File "/usr/lib/python2.7/site-packages/redis/client.py", line 863, in get
return self.execute_command('GET', name)
File "/usr/lib/python2.7/site-packages/redis/client.py", line 570, in execute_command
connection.send_command(*args)
File "/usr/lib/python2.7/site-packages/redis/connection.py", line 556, in send_command
self.send_packed_command(self.pack_command(*args))
File "/usr/lib/python2.7/site-packages/redis/connection.py", line 532, in send_packed_command
self.connect()
File "/usr/lib/python2.7/site-packages/redis/connection.py", line 436, in connect
raise ConnectionError(self._error_message(e))
ConnectionError: Error -2 connecting to redis:6379. Name or service not known.
What am I doing wrong here?
You are trying to connect to redis:6379. But who is hostname redis? Probably not the pod that you just launched.
In order to use hostnames with pods and services, check if you can deploy sky-dns also in your cluster. For your case I presume that you only need to use the hostname of the redis service.
You don't want to connect to the pods directly, you want to use the service ip address for that.
So, you can use for connectivity the ip address of you service.
Or you can have hostnames for your services in order to connect to your pods.
For this the easiest way is to use kube-skydns. Read the documentation on how to deploy it and how to use it.
You need to add containerPort
in your pod-redis.yaml
- name: redis
image: dharmit/redis
command:
- "redis-server"
ports:
- containerPort: 6379
hostPort: 6379