Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes equivalent of env-file in Docker

Background:

Currently we're using Docker and Docker Compose for our services. We have externalized the configuration for different environments into files that define environment variables read by the application. For example a prod.env file:

ENV_VAR_ONE=Something Prod ENV_VAR_TWO=Something else Prod 

and a test.env file:

ENV_VAR_ONE=Something Test ENV_VAR_TWO=Something else Test 

Thus we can simply use the prod.env or test.env file when starting the container:

docker run --env-file prod.env <image> 

Our application then picks up its configuration based on the environment variables defined in prod.env.

Questions:

  1. Is there a way to provide environment variables from a file in Kubernetes (for example when defining a pod) instead of hardcoding them like this:
 apiVersion: v1 kind: Pod metadata:    labels:      context: docker-k8s-lab     name: mysql-pod   name: mysql-pod spec:    containers:      -        env:          -            name: MYSQL_USER           value: mysql         -            name: MYSQL_PASSWORD           value: mysql         -            name: MYSQL_DATABASE           value: sample         -            name: MYSQL_ROOT_PASSWORD           value: supersecret       image: "mysql:latest"       name: mysql       ports:          -            containerPort: 3306 
  1. If this is not possible, what is the suggested approach?
like image 236
Johan Avatar asked Nov 02 '15 13:11

Johan


People also ask

What are .env files in Docker?

The . env file, is only used during a pre-processing step when working with docker-compose. yml files. Dollar-notation variables like $HI are substituted for values contained in an “. env” named file in the same directory.

Does Docker build .env files?

If you are using docker-compose (which now comes bundled with Docker), . env is the default filename for the file that contains variables that are made available to the parser for the docker-compose. yml file ONLY, and not to the build process or container environment variables.

How do I pass an env file in Kubernetes?

There are two ways to define environment variables with Kubernetes: by setting them directly in a configuration file, from an external configuration file, using variables, or a secrets file. This tutorial shows both options, and uses the Humanitec getting started application used in previous tutorials.

What is env in Kubernetes?

Kubernetes environment variables are nothing but the variables that we can define in a Pod's configuration and it can be used elsewhere in the configuration.


2 Answers

You can populate a container's environment variables through the use of Secrets or ConfigMaps. Use Secrets when the data you are working with is sensitive (e.g. passwords), and ConfigMaps when it is not.

In your Pod definition specify that the container should pull values from a Secret:

apiVersion: v1 kind: Pod metadata:    labels:      context: docker-k8s-lab     name: mysql-pod   name: mysql-pod spec:    containers:   - image: "mysql:latest"     name: mysql     ports:      - containerPort: 3306     envFrom:       - secretRef:          name: mysql-secret 

Note that this syntax is only available in Kubernetes 1.6 or later. On an earlier version of Kubernetes you will have to specify each value manually, e.g.:

env:  - name: MYSQL_USER   valueFrom:     secretKeyRef:       name: mysql-secret       key: MYSQL_USER 

(Note that env take an array as value)

And repeating for every value.

Whichever approach you use, you can now define two different Secrets, one for production and one for dev.

dev-secret.yaml:

apiVersion: v1 kind: Secret metadata:   name: mysql-secret type: Opaque data:   MYSQL_USER: bXlzcWwK   MYSQL_PASSWORD: bXlzcWwK   MYSQL_DATABASE: c2FtcGxlCg==   MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK 

prod-secret.yaml:

apiVersion: v1 kind: Secret metadata:   name: mysql-secret type: Opaque data:   MYSQL_USER: am9obgo=   MYSQL_PASSWORD: c2VjdXJlCg==   MYSQL_DATABASE: cHJvZC1kYgo=   MYSQL_ROOT_PASSWORD: cm9vdHkK 

And deploy the correct secret to the correct Kubernetes cluster:

kubectl config use-context dev kubectl create -f dev-secret.yaml  kubectl config use-context prod kubectl create -f prod-secret.yaml 

Now whenever a Pod starts it will populate its environment variables from the values specified in the Secret.

like image 112
Pixel Elephant Avatar answered Oct 09 '22 22:10

Pixel Elephant


A new update for Kubernetes(v1.6) allows what you asked for(years ago).

You can now use the envFrom like this in your yaml file:

  containers:   - name: django     image: image/name     envFrom:       - secretRef:          name: prod-secrets 

Where development-secrets is your secret, you can create it by:

kubectl create secret generic prod-secrets --from-env-file=prod/env.txt` 

Where the txt file content is a key-value:

DB_USER=username_here DB_PASSWORD=password_here 

The docs are still lakes of examples, I had to search really hard on those places:

  • Secrets docs, search for --from-file - shows that this option is available.
  • The equivalent ConfigMap docs shows an example on how to use it.

Note: there's a difference between --from-file and --from-env-file when creating secret as described in the comments below.

like image 22
Or Duan Avatar answered Oct 09 '22 23:10

Or Duan