Search code examples
kubectlportforwarding

kubernetes pod talking to a localhost port


I have a celery instance running inside a pod in local kubernetes cluster whereas the redis server/broker it connects to is started on my localhost:6379 without kubernetes . How can i get my k8 pod to talk to locally deployed redis?


Solution

  • You can create a Headless Service and an Endpoint with statically defined IP address of the node where the redis server is running.


    I've created an example to illustrate you how it works.

    First, I created a Headless Service and an Endpoint.
    NOTE: Endpoint has the IP address of the node where redis server is running:

    # example.yml
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis
      namespace: default
    spec:
      clusterIP: None
      ports:
      - name: redis
        port: 6379
        protocol: TCP
    ---
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: redis
      namespace: default
    subsets:
      - addresses:
          - ip: 10.156.0.58 # your node's IP address
        ports:
          - port: 6379
            name: redis
            protocol: TCP
    

    After creating above resources, we are able to resolve the redis service name to the IP address:

    # kubectl get svc,ep redis
    NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
    service/redis   ClusterIP   None         <none>        6379/TCP   28m
    
    NAME              ENDPOINTS          AGE
    endpoints/redis   10.156.0.58:6379   28m
    
    # kubectl run dnsutils --image=gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 -it --rm
    / # nslookup redis
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   redis.default.svc.cluster.local
    Address: 10.156.0.58
    

    Additionally, if your redis server is only listening on localhost, you need to modify the iptables rules. To configure port forwarding from port 6379 (default redis port) to localhost you can use:
    NOTE: Instead of 10.156.0.58 use the IP address of the node where your redis server is running.

    # iptables -t nat -A PREROUTING -p tcp -d 10.156.0.58 --dport 6379 -j DNAT --to-destination 127.0.0.1:6379
    

    As you can see, it is easier if redis is listening not only on the localhost, as we don't have to modify the iptables rules then.

    Finally, let's see if we can connect from Pod to the redis server on the host machine:

    # kubectl exec -it redis-client -- bash
    root@redis-client:/# redis-cli -h redis
    redis:6379> SET key1 "value1"
    OK