Kubernetes service as env var to frontend usage

2/27/2017

I'm trying to configure kubernetes and in my project I've separeted UI and API. I created one Pod and I exposed both as services.

How can I set API_URL inside pod.yaml configuration in order to send requests from user's browser?

I can't use localhost because the communication isn't between containers.

pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: project
  labels:
    name: project
spec:
  containers:
  - image: 'ui:v1'
    name: ui
    ports:
    - name: ui
      containerPort: 5003
      hostPort: 5003
    env:
    - name: API_URL
      value: <how can I set the API address here?>
  - image: 'api:v1'
    name: api
    ports:
    - name: api
      containerPort: 5000
      hostPort: 5000
    env:
    - name: DATABASE_URL
      valueFrom:
      secretKeyRef:
        name: postgres-url
        key: url

services.yaml

apiVersion: v1
kind: Service
metadata:
  name: api
  labels:
    name: api
spec:
  type: NodePort
  ports:
  - name: 'http'
    protocol: 'TCP'
    port: 5000
    targetPort: 5000
    nodePort: 30001
  selector:
    name: project
---
apiVersion: v1
kind: Service
metadata:
  name: ui
  labels:
    name: ui
spec:
  type: NodePort
  ports:
  - name: 'http'
    protocol: 'TCP'
    port: 80
    targetPort: 5003
    nodePort: 30003
  selector:
    name: project
-- Celso Marques
kubernetes

2 Answers

3/9/2017

I created an Ingress to solve this issue and point to DNS instead of IP.

ingres.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: project
spec:
  tls:
  - secretName: tls
  backend:
    serviceName: ui
    servicePort: 5003
  rules:
  - host: www.project.com
    http:
      paths:
      - backend:
          serviceName: ui
          servicePort: 5003
  - host: api.project.com
    http:
      paths:
      - backend:
          serviceName: api
          servicePort: 5000

deployment.yaml

apiVersion: v1
kind: Pod
metadata:
  name: project
  labels:
    name: project
spec:
  containers:
  - image: 'ui:v1'
    name: ui
    ports:
    - name: ui
      containerPort: 5003
      hostPort: 5003
    env:
    - name: API_URL
      value: https://api.project.com
  - image: 'api:v1'
    name: api
    ports:
    - name: api
      containerPort: 5000
      hostPort: 5000
    env:
    - name: DATABASE_URL
      valueFrom:
      secretKeyRef:
        name: postgres-url
        key: url
-- Celso Marques
Source: StackOverflow

2/27/2017

The service IP is already available in a environment variable inside the pod, because Kubernetes initializes a set of environment variables for each service that exists at that moment.

To list all the environment variables of a pod

kubectl exec <pod-name> env

If the pod was created before the service you must delete it and create it again.

Since you named your service api, one of the variables the command above should list is API_SERVICE_HOST.

But you don't really need to lookup the service IP address inside environment variables. You can simply use the service name as the hostname. Any pod can connect to the service api, simply by calling api.default.svc.cluster (assuming your service is in the default namespace).

-- Bruno Calza
Source: StackOverflow