Kubernetes env variable to containers

8/5/2018

I want to pass some values from Kubernetes yaml file to the containers. These values will be read in my Java app using System.getenv("x_slave_host"). I have this dockerfile:

FROM jetty:9.4
...
ARG slave_host
ENV x_slave_host $slave_host
...
$JETTY_HOME/start.jar -Djetty.port=9090

The kubernetes yaml file contains this part where I added env section:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: master
spec:
  template:
    metadata:
      labels:
        app: master
    spec:
      volumes:
      - name: shared-data
        emptyDir: {}
      containers:
      - name: master
        image: xregistry.azurecr.io/Y:latest
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: shared-data
          mountPath: ~/.X/experiment
      - env:
        - name: slave_host
          value: slavevalue
      - name: jupyter
        image: xregistry.azurecr.io/X:latest
        ports:
        - containerPort: 8000
        - containerPort: 8888
        volumeMounts:
        - name: shared-data
          mountPath: /var/folder/experiment
      imagePullSecrets:
      - name: acr-auth

Locally when I did the same thing using docker compose, it worked using args. This is a snippet:

  master:
    image: master
    build:
      context: ./master
      args:
        - slave_host=slavevalue
    ports:
      - "9090:9090"

So now I am trying to do the same thing but in Kubernetes. However, I am getting the following error (deploying it on Azure):

    error: error validating "D:\\a\\r1\\a\\_X\\deployment\\kub-deploy.yaml": error validating data: field spec.template.spec.containers[1].name for v1.Container is required; if you choose to ignore these errors, turn validation off with --validate=false

In other words, how to rewrite my docker compose file to kubernetes and passing this argument.

Thanks!

-- Ziad Halabi
containers
docker
kubernetes

2 Answers

8/6/2018

env section should be added under containers, like this:

  containers:
  - name: master
    env:
    - name: slave_host
      value: slavevalue
-- Kun Li
Source: StackOverflow

8/6/2018

To elaborate a on @Kun Li's answer, besides adding environment variables e.g. in the Deployment manifest directly you can create a ConfigMap (or Secret depending on the data being stored) and reference these in your manifests. This is a good way of sharing the same environment variables across applications, compared to manually adding environment variables to several different applications.

Note that a ConfigMap can consist of one or more key: value pairs and it's not limited to storing environment variables, it's just one of the use cases. And as i mentioned before, consider using a Secret if the data is classified as sensitive.

Example of a ConfigMap manifest, in this case used for storing an environment variable:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-env-var
data:
  slave_host: slavevalue

To create a ConfigMap holding one key=value pair using kubectl create:

kubectl create configmap my-env --from-literal=slave_host=slavevalue

To get hold of all environment variables configured in a ConfigMap use the following in your manifest:

  containers:
    envFrom:
      - configMapRef:
          name: my-env-var

Or if you want to pick one specific environment variable from your ConfigMap containing several variables:

  containers:
    env:
      - name: slave_host
        valueFrom:
          configMapKeyRef:
            name: my-env-var
            key: slave_host

See this page for more examples of using ConfigMap's in different situations.

-- mikejoh
Source: StackOverflow