Basically, i have a Deployment that creates 3 containers which scale automatically: PHP-FPM, NGINX and the container that contains the application, all set up with secrets, services and ingress. The application also share the project between PHP-FPM and NGINX, so it's all set up.
Since i want to explore more with K8s, i decided to create a pod with Redis that also mounts a persistent disk (but that's not important). I have also created a service for redis and all works perfectly fine if i SSH into the Redis container and run redis-cli
.
The fun part is that the project can't connect to the pod on which Redis is on. I understand that the containers between pods share the same "local" network and they can be accessed using localhost
.
How do i connect my project to the redis server that is running in other pod, that scales independently? What's wrong with the Redis service?
My Redis service is this:
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
My Redis pod is powered by a deployment configuration file (i don't necessarily scale it, but i'll look forward into it):
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
strategy:
type: Recreate
template:
metadata:
labels:
app: redis
spec:
volumes:
- name: redis-persistent-volume
persistentVolumeClaim:
claimName: redis-pvc
containers:
- image: redis:4.0.11
command: ['redis-server']
name: redis
imagePullPolicy: Always
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
ports:
- containerPort: 6379
name: redis
volumeMounts:
- name: redis-persistent-volume
mountPath: /data
Also, when i tap into the kubectl get service
, the Redis server has a Cluster IP:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h
nginx-service NodePort 10.100.111.16 <none> 80:30312/TCP 21h
redis-service ClusterIP 10.99.80.141 <none> 6379/TCP 6s
If you are using MicroK8s, then see their documentation
I struggled to communicate with a pod from another, and the other thing that also didn't work as expected was communicating with services by using their name (the DNS lookup seemed to not be able to translate the service name to an IP).
In any case, there was some relevant steps inside the MicroK8s documentation that I needed to execute and then everything suddenly started working.
Also make sure you actually installed the MicroK8s DNS service:
microk8s.enable dns
Please refer to the MicroK8s documentation for the latest, but here are the steps as of today:
How do i connect my project to the redis server that is running in other pod, that scales independently?
You have three possible states here:
To connect to Redis pod from within any other pod running in the same namespace as Redis pod is running. In this case you will use service name redis-service
and designates service port 6379
to reach it over it's current ClusterIP (kube-dns is making DNS resolution for you there). I'm guessing that you are asking for this scenario.
Here is just an example of accessing one pod from within another pod (in your case). First run:
kubectl run -it --rm test --image=busybox --restart=Never -- sh
this will run new test pod and give you sh
within that pod. Now if you type nslookup redis-service
there (within test pod) you will check that DNS is working correctly between pods. You can also try to see if redis port is actually open with nc -zv redis-service 6379
. If your kube-dns is working properly you should see that port is opened.
To connect to Redis pod from within any other pod running in the same kubernetes cluster but in different namespace. In this case you will use FQDN consisting of service name and namespace name like it is given in the documentation.
To connect to Redis pod from outside of the kubernetes cluster. In this case you will need some king of ingress, or nodePort of similar mechanism to expose redis service to outside world. More on this you can read in the official documentation.
Indeed, using the service name as hostname worked. I didn't know that Kubernetes's DNS also manages to do this. I have used it before in Docker Composer, and in my containerized application i have used it to connect to the services (ie: MySQL, Redis, Elasticsearch).
To clarify this, in my app, i set the hostname to the service name, like redis-service
. If i'd like to connect to the Postgres, i can do using pgsql-service
or whatever the name of that service is.
THANK YOU!