How to make two Kubernetes Services talk to each other?
First, configure the Redis service as a ClusterIP
service. It will be private, visible only for other services. This is could be done removing the line with the option type
.
apiVersion: v1kind: Servicemetadata: name: app-api-redis-svcspec: selector: app: app-api-redis tier: celery_broker ports: - protocol: TCP port: 6379 targetPort: [the port exposed by the Redis pod]
Finally, when you configure the API to reach Redis, the address should be app-api-redis-svc:6379
And that's all. I have a lot of services communicating each other in this way. If this doesn't work for you, let me know in the comments.
I'm going to try to take the best from all answers and my own research and make a short guide that I hope you will find helpful:
1. Test connectivity
Connect to a different pod, eg ruby pod:
kubectl exec -it some-pod-name -- /bin/sh
Verify it can ping to the service in question:
ping redis
Can it connect to the port? (I found telnet did not work for this)
nc -zv redis 6379
2. Verify your service selectors are correct
If your service config looks like this:
kind: ServiceapiVersion: v1metadata: name: redis labels: app: redis role: master tier: backendspec: ports: - port: 6379 targetPort: 6379 selector: app: redis role: master tier: backend
verify those selectors are also set on your pods?
get pods --selector=app=redis,role=master,tier=backend
Confirm that your service is tied to your pods by running:
$> describe service redisName: redisNamespace: defaultLabels: app=redis role=master tier=backendAnnotations: <none>Selector: app=redis,role=master,tier=backendType: ClusterIPIP: 10.47.250.121Port: <unset> 6379/TCPEndpoints: 10.44.0.16:6379Session Affinity: NoneEvents: <none>
check the Endpoints:
field and confirm it's not blank
More info can be found at:https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/#my-service-is-missing-endpoints
I'm not sure about redis, but I have a similar application. I have a Java web application running as a pod that is exposed to the outside world through a nodePort. I have a mongodb container running as a pod.
In the webapp deployment specifications, I map it to the mongodb service through its name by passing the service name as parameter, I have pasted the specification below. You can modify accordingly.There should be a similar mapping parameter in Redis also where you would have to use the service name which is "mongoservice" in my case.
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: empappdepl labels: name: empappspec: replicas: 1 template: metadata: labels: name: empapp spec: containers: - resources: limits: cpu: 0.2 image: registryip:5000/employee:1 imagePullPolicy: IfNotPresent name: wsemp ports: - containerPort: 8080 name: wsemp command: ["java","-Dspring.data.mongodb.uri=mongodb://mongoservice/microservices", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] imagePullSecrets: - name: myregistrykey---apiVersion: v1kind: Servicemetadata: labels: name: empwhatever name: empservicespec: ports: - port: 8080 targetPort: 8080 protocol: TCP name: http nodePort: 30062 type: NodePort selector: name: empapp---apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: mongodbdepl labels: name: mongodbspec: replicas: 1 template: metadata: labels: name: mongodbspec: containers: - resources: limits: cpu: 0.3 image: mongo imagePullPolicy: IfNotPresent name: mongodb ports: - containerPort: 27017---apiVersion: v1kind: Servicemetadata: labels: name: mongowhatever name: mongoservicespec: ports: - port: 27017 targetPort: 27017 protocol: TCP selector: name: mongodb
Note that the mongodb service doesnt need to be exposed as a NodePort.