How to Inject Environment Variables into Kubernetes Pods Before Deployment

7/6/2019

I need to inject container port from an environment variable inside my pod. How to do that?

Have been through the documentation, Links:- 1. https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ 2. https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
        - containerPort: $(MY_CONTAINER_PORT)
      env:
        - name: MY_CONTAINER_PORT
          value: 80
error: error validating "nginx-pod-exposed-through-env.yaml": error validating data: ValidationError(Pod.spec.containers[0].ports[0].containerPort): invalid type for io.k8s.api.core.v1.ContainerPort.containerPort: got "string", expected "integer"; if you choose to ignore these errors, turn validation off with --validate=false
-- Kunal Malhotra
kubernetes
kubernetes-pod

3 Answers

7/8/2019

Below example has an environment variable "PASSWORD"

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
    command: [ "/bin/bash", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]
    env:
    - name: PASSWORD
      value: "password"
-- Ravishankar S R
Source: StackOverflow

7/7/2019

You can't use environment variables defined for the pod to be used to expose the port. Kubernetes expects the value of container port to be integer, but since you gave $(MY_CONTAINER_PORT), it says string values are not allowed.

The right configuration would be,

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
        - containerPort: 80

However, if you still need environment variables to be specified as containerPort, its better to use kubernetes package manager like helm, or run a shell script to your yaml before deploying to kubernetes, preferrably with envsubstr that will resolve the environment variable and regenerate the yaml file with the env variable substituted for containerPort. Perhaps this github link might help you why kubectl will never support variable substitution.

-- Malathi
Source: StackOverflow

7/8/2019

A way to accomplish this would be to use a templating tool such as ytt. With ytt you would turn your manifest into a template like:

#@ load("@ytt:data", "data")
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
        - containerPort: #@ data.values.port

And then supply a values.yml like:

#@data/values
---
port: 8080

Assuming the original template is named test.yml we could run ytt like so to generate the output:

$ ytt -f test.yml -f values.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 8080

The ytt utility then lets us override the data values one the command line with --data-value (or -v for short). An example changing to port 80:

$ ytt -v port=80 -f test.yml -f values.yml            
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80

Your original question sounded like you wanted to use environment variables. This is supported with --data-values-env. An example using prefix MYVAL:

$ export MYVAL_port=9000
$ ytt --data-values-env MYVAL -f test.yml -f values.yml   
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 9000

You can then combine ytt and kubectl to create and apply resources:

ytt --data-values-env MYVAL -f test.yml -f values.yml | kubectl apply -f-

Additional information on injecting data into ytt templates is at https://github.com/k14s/ytt/blob/master/docs/ytt-data-values.md.

-- Andy Shinn
Source: StackOverflow