Kubernetes equivalent of env-file in Docker
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: v1kind: Podmetadata: labels: context: docker-k8s-lab name: mysql-pod name: mysql-podspec: 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: v1kind: Secretmetadata: name: mysql-secrettype: Opaquedata: MYSQL_USER: bXlzcWwK MYSQL_PASSWORD: bXlzcWwK MYSQL_DATABASE: c2FtcGxlCg== MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK
prod-secret.yaml:
apiVersion: v1kind: Secretmetadata: name: mysql-secrettype: Opaquedata: 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 devkubectl create -f dev-secret.yamlkubectl config use-context prodkubectl create -f prod-secret.yaml
Now whenever a Pod starts it will populate its environment variables from the values specified in the Secret.
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_hereDB_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.
When defining a pod for Kubernetes using a YAML file, there's no direct way to specify a different file containing environment variables for a container. The Kubernetes project says they will improve this area in the future (see Kubernetes docs).
In the meantime, I suggest using a provisioning tool and making the pod YAML a template. For example, using Ansible your pod YAML file would look like:
file my-pod.yaml.template
:
apiVersion: v1kind: Pod...spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ...
Then your Ansible playbook can specify the variable mysql_root_password
somewhere convenient, and substitute it when creating the resource, for example:
file my-playbook.yaml
:
- hosts: my_hosts vars_files: - my-env-vars-{{ deploy_to }}.yaml tasks: - name: create pod YAML from template template: src=my-pod.yaml.template dst=my-pod.yaml - name: create pod in Kubernetes command: kubectl create -f my-pod.yaml
file my-env-vars-prod.yaml
:
mysql_root_password: supersecret
file my-env-vars-test.yaml
:
mysql_root_password: notsosecret
Now you create the pod resource by running, for example:
ansible-playbook -e deploy=test my-playbook.yaml