Kubernetes Pods intercommunication with internal/external IP addresses

4/14/2018

Lets say I have a Python code on my local machine that listens on localhost and port 8000 as below:

import waitress
app = hug.API(__name__)
app.http.add_middleware(CORSMiddleware(app))
waitress.serve(__hug_wsgi__, host='127.0.0.1', port=8000)

This code accepts requests on 127.0.0.1:8000 and send back some response.

Now I want to move this application (with two more related apps) into Docker, and use Kubernetes to orchestrate the communication between them.

But for simplicity, I will take this Python node (app) only.

First I built the docker image using:

docker build -t gcr.io/${PROJECT_ID}/python-app:v1 .

Then I pushed it into gcloud docker ( I am using google cloud not docker hub):

gcloud docker -- push gcr.io/${PROJECT_ID}/python-app:v1

Now I created the container cluster:

gcloud container clusters create my-cluster

Deployed the app into kubernates:

kubectl run python-app --image=gcr.io/${PROJECT_ID}/python-app:v1 --port 8000

And finally exposed it to internet via:

kubectl expose deployment python-app --type=LoadBalancer --port 80 --target-port 8000

Now the output of the command kubectl get services is:

kubectl get services

Ok, my question is, I want to send a request from another application (lets say a node js app).

  1. How can I do that externally? i.e. from any machine.
  2. How can I do that internally? i.e. from another container pod.

How can I let my Python app use those IP addresses and listen on them?

This is the Dockerfile of the Python app:

FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./app.py" ]

Thanks in advance!

-- Ahmad Hijazi
docker
gcloud
google-cloud-platform
kubectl
kubernetes

1 Answer

4/14/2018

Externally

By running:

kubectl run python-app --image=gcr.io/${PROJECT_ID}/python-app:v1 --port 8000

You are specifying that your pod listen on port 8000.

By running:

kubectl expose deployment python-app --type=LoadBalancer --port 80 --target-port 8000

You are specifying that your service listens on port 80, and the service sends traffic to TargetPort 8000 (the port the pod listens on).

So it could be summarised that with your configuration traffic follows the following path:

traffic (port 80) > Load Balancer > Service (Port 80) > TargetPort/Pod (port 8000)

Using a service of type Load Balancer (rather than the alternative 'Ingress', which creates a service of type Nodeport, and a HTTP(s) Load Balancer rather than a TCP Load Balancer) you are specifying that traffic that targets the pods should arrive at the LoadBalancer on port 80, and then the service directs this traffic to port 8000 on your App. So if you want to direct traffic to your App from an external source, based on the addresses in your screen shot, you would send traffic to 35.197.94.202:80.

Internally

As others have pointed out in the comments, the cluster IP can be used to target pods internally. The port you specify as the service port (in your case 80, although this could be any number you choose for the service) can be used alongside the cluster IP to target the pods on that cluster targeted by the service. For example, you could target:

10.3.254.16:80

However, to target specific pods, you can use the pod IP address and the port the pod listens on. You can discover this by either running a describe command on the pod:

kubectl describe pod

Or by running:

kubectl get endpoints 

Which generates the pod IP and port it is listing on.

-- neilH
Source: StackOverflow