How to make two Kubernetes Services talk to each other?

8/16/2017

Currently, I have working K8s API pods in a K8s service that connects to a K8s Redis service, with K8s pods of it's own. The problem is, I am using NodePort meaning BOTH are exposed to the public. I only want the API accessable to the public. The issue is that if I make the Redis service not public, the API can't see it. Is there a way to connect two Services without exposing one to the public?

This is my API service yaml:

apiVersion: v1
kind: Service
metadata:
   name: app-api-svc
spec:
   selector:
     app: app-api
     tier: api
   ports:
     - protocol: TCP
       port: 5000
       nodePort: 30400
   type: NodePort

And this is my Redis service yaml:

apiVersion: v1
kind: Service
metadata:
   name: app-api-redis-svc
spec:
   selector:
     app: app-api-redis
     tier: celery_broker
   ports:
     - protocol: TCP
       port: 6379
       nodePort: 30537
   type: NodePort
-- Will Parzybok
cluster-computing
kubectl
kubernetes

4 Answers

8/16/2017

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: v1
kind: Service
metadata:
   name: app-api-redis-svc
spec:
   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.

-- Mario S
Source: StackOverflow

9/19/2017

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: Service
apiVersion: v1
metadata:
  name: redis
  labels:
    app: redis
    role: master
    tier: backend
spec:
  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:

gt; describe
service redis Name: redis Namespace: default Labels: app=redis role=master tier=backend Annotations: <none> Selector: app=redis,role=master,tier=backend Type: ClusterIP IP: 10.47.250.121 Port: <unset> 6379/TCP Endpoints: 10.44.0.16:6379 Session Affinity: None Events: <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

-- newUserNameHere
Source: StackOverflow

8/16/2017

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/v1beta1
    kind: Deployment
    metadata:
      name: empappdepl
      labels:
        name: empapp
    spec:
      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: v1
kind: Service
metadata:
  labels:
    name: empwhatever
  name: empservice
spec:
  ports:
   - port: 8080
     targetPort: 8080
     protocol: TCP
     name: http
     nodePort: 30062
  type: NodePort
  selector:
    name: empapp
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: mongodbdepl
      labels:
        name: mongodb
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            name: mongodb
        spec:
          containers:
          - resources:
              limits:
                cpu: 0.3
            image: mongo
            imagePullPolicy: IfNotPresent
            name: mongodb
            ports:
                  - containerPort: 27017
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: mongowhatever
      name: mongoservice
    spec:
      ports:
       - port: 27017
         targetPort: 27017
         protocol: TCP
      selector:
        name: mongodb

Note that the mongodb service doesnt need to be exposed as a NodePort.

-- Vikram
Source: StackOverflow

8/18/2017

Kubernetes enables inter service communication by allowing services communicate with other services using their service name.

In your scenario, redis service should be accessible from other services on http://app-api-redis-svc.default:6379. Here default is the namespace under which your service is running.

This internally routes your requests to your redis pod running on the target container port

Checkout this link for different modes of service discovery options provided by kubernetes

Hope it helps

-- Karthik Venkateswaran
Source: StackOverflow