Setting environment variables based on services in Kubernetes

4/5/2019

I am running a simple app based on an api and web interface in Kubernetes. However, I can't seem to get the api to talk to the web interface. In my local environment, I just define a variable API_URL in the web interface with eg. localhost:5001 and the web interface correctly connects to the api. As api and web are running in different pods I need to make them talk to each other via services in Kubernetes. So far, this is what I am doing, but without any luck.

I set-up a deployment for the API

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: api
  template:
    metadata:
      labels:
        component: api
    spec:
      containers:
      - name: api
        image: gcr.io/myproject-22edwx23/api:latest
      ports:
      - containerPort: 5001

I attach a service to it:

apiVersion: v1
kind: Service
metadata:
  name: api-cluster-ip-service
spec:
  type: NodePort
  selector:
    component: api
  ports:
    - port: 5001
      targetPort: 5001

and then create a web deployment that should connect to this api.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: web
  template:
    metadata:
      labels:
        component: web
    spec:
      containers:
      - name: web
        image: gcr.io/myproject-22edwx23/web:latest
        ports:
        - containerPort: 5000
        env:
          - name: API_URL
            value: http://api-cluster-ip-service:5001

afterwards, I add a service for the web interface + ingress etc but that seems irrelevant for the issues. I am wondering if the setting of API_URL correctly picks up the host of the api via http://api-cluster-ip-service:5001?

Or can I not rely on Kubernetes getting the appropriate dns for the api and should the web app call the api via the public internet.

-- Mike
google-kubernetes-engine
kubernetes

2 Answers

4/5/2019

If you want to use environment variables you can do the following:

Example in Python:

import os
API_URL = os.environ['API_CLUSTER_IP_SERVICE_SERVICE_HOST'] + ":" + os.environ['API_CLUSTER_IP_SERVICE_SERVICE_PORT']

Notice that the environment variable is based on your service name. If you want to check all environment variables available in a Pod:

kubectl get pods #get {pod name}
kubectl exec -it {pod_name} printenv

P.S. Be careful that a Pod gets its environment variables during its creation and it will not be able to get it from services created after it.

-- victortv
Source: StackOverflow

4/5/2019

If you want to check API_URL variable value, simply run

kubectl exec -it web-deployment-pod env | grep API_URL

The kube-dns service listens for service and endpoint events from the Kubernetes API and updates its DNS records as needed. These events are triggered when you create, update or delete Kubernetes services and their associated pods.

kubelet sets each new pod's search option in /etc/resolv.conf

Still, if you want to http from one pod to another via cluster service it is recommended to refer service's ClusterIP as follows

api-cluster-ip-service.default.svc.cluster.local

You should have service IP assigned to env variable within your web pod, so there's no need to re-invent it:

sukhoversha@sukhoversha:~/GCP$ kk exec -it web-deployment-675f8fcf69-xmqt8 env | grep -i service
API_CLUSTER_IP_SERVICE_PORT=tcp://10.31.253.149:5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP=tcp://10.31.253.149:5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP_PORT=5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP_ADDR=10.31.253.149

To read more about DNS for Services

-- A_Suh
Source: StackOverflow