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:
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
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.
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.
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.
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.
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.
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:
--from-file
- shows that this option is available.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With