Kubernetes: Automatically determine IP Address of another pod/container

7/20/2018

I'm using minikube to test out a local Kubernetes scenario. I have 2 Python Flask applications named 'frontend.py' and 'interceptor.py'. Basically I want to do a GET to the frontend application which will then perform a POST to the interceptor application, and receive a response back from the interceptor. I have this working if I manually find the interceptor application's IP and provide it in my 'frontend.py' script.

My question: Is there a recommended way to automatically determine the IP address of an application running in one pod's container from an application inside another pod's container?

I'm wondering if I might not even need to gather the IP in the application themselves if there is some other way to expose the pods' info to each other via the Kubernetes Service that I create, but I haven't had any luck yet.

Below are my services, and deployments.

flask-frontend-deployment.yaml

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: frontend-deployment
  labels:
    app: flask
spec:
  selector:
    matchLabels:
      app: flask
  replicas: 1
  template:
    metadata:
      labels:
        app: flask
        tier: frontend
    spec:
      containers:
      - name: flask-frontend
        image: alec/flask/frontend:1.0
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 5001

flask-frontend-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  type: NodePort
  selector:
    app: flask
  ports:
  - protocol: TCP
    port: 5001
    targetPort: 5001

flask-interceptor-deployment.yaml

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: interceptor-deployment
  labels:
    app: flask
spec:
  selector:
    matchLabels:
      app: inter
      role: mid
      tier: middle
  replicas: 1
  template:
    metadata:
      labels:
        app: inter
        role: mid
        tier: middle
    spec:
      containers:
      - name: flask-interceptor
        image: alec/flask/interceptor:1.0
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: env
        ports:
        - containerPort: 5002

flask-interceptor-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: interceptor-service
spec:
  ports:
  - protocol: TCP
    port: 5002

frontend.py

from flask import Flask
from flask import request
import requests

app = Flask(__name__)

@app.route("/")
def hello():
    address = 'http://172.17.0.5:5002/' #<--- this is the IP I want to get automatically 
    r = requests.post(address, data="---[Token]---")
    return "Frontend Here. Response from Backend = "+str(r.content)

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0',port=5001)

interceptor.py

from flask import Flask
from flask import request
import requests

app = Flask(__name__)

content = ""

@app.route("/", methods=['POST'])
def testPost():
    if request.method == 'POST':
        return "Received POST --->>> " + str(request.data)
    else:
        return "Post didnt work"

@app.route("/", methods=['GET'])
def hello():
    return "Hello from the interceptor!"

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0',port=5002)
-- Cheen
flask
kubernetes
minikube

1 Answer

7/20/2018

As long as you have the kube-dns add-on enabled in minikube you should be able to perform DNS-based service discovery. I would say that this is the recommended way of getting hold of the IP addresses of your resources.

To double check that you have kube-dns enabled run minikube addons list, it should be enabled by default.

The DNS names created for you will default be derived from the metadata: name field of your resource(s). Assuming you'll be using the default namespace then your Services DNS-names would be:

interceptor-service.default.svc.cluster.local

and

frontend-service.default.svc.cluster.local

You could use these fully qualified domain-names within your application to reach your Services or use a shorter version e.g. frontend-service as-is. This is possible since your Pods resolv.conf will be configured to look in default.svc.cluster.local when querying for frontend-service.

To test this (and noted in the comments), you should now be able to change this line:

address = 'http://172.17.0.5:5002/'

to

address = 'http://interceptor-service:5002/'

in your Flask app code.

Please see this page for more detailed information about DNS for Services and Pods in Kubernetes.

-- mikejoh
Source: StackOverflow