Environment variables
Environment variables, such as the locally used .env file can be passed to Kubernetes pods in three ways in OpenShift. As direct references to Secrets or ConfigMaps, by making a volume mount of the contents of a Secret or ConfigMap and as direct environment variables. By using a volume mount, the Secret or ConfigMap is transformed into a configuration file instead of an environment variable. Environment variables can’t be changed during runtime.
Even though all of them are possible, it is recommended to pass all confidential information in Kubernetes Secret-objects* and other possible configurations in ConfigMaps. The current trend, as of 2024, is to make your application check if the configuration file(s) have changed periodically during run-time. This means that changes to the configuration files don’t require a restart of the pods. Currently only volume mounted Secrets and ConfigMaps have their values refreshed during run-time.
*More info can be found on the separate Secrets page.
The basic idea of passing your environment variables outside your code is to make code easily portable.
ConfigMaps vs Secrets
According to Kubernetes docs, ConfigMaps are objects that can be used to store non-confidential data in key-value pairs. You can see an example in the link. As for Secrets, the Kubernetes docs describe Secrets as objects that contain small amounts of confidential data, such as tokens, keys and passwords.
Below you can find a table with some differences listed in an easier to understand format:
| ConfigMap | Secret | |
|---|---|---|
| Intended Usage | most non-condidential configurations | passwords, keys, tokens |
| Exists on Worker Nodes | x | only when a pod on the node requests the Secret |
| Is Written to Node Persistent Storage | x | never |
| Is Visible to All Containers in a Pod | x | needs explicit permission |
| Intended Size | max 1 MiB | small |
| Can Be Made Immutable | x | x |
Giving Pods Access to Environment Variables
Let’s start by the easiest way of adding applications to OpenShift. If you import your project from Git using the web-UI (Developer -> +Add -> Import from git), you can find the options for environment variables under Advanced Build options and Advanced Deployment options. The UI lets you add the variables either as text, or by referencing existing Secret or ConfigMap files.

Make sure that you only add the necessary Secrets to the build phase, as this means that container image that OpenShift builds will contain all the Secrets given here. The given environment variables can be checked from the Environment tab of either the Deployment or BuildConfig. Also, the environment values defined in the BuildConfig are not visible in the Environment tab of the Deployment.
The environment variables defined in the UI are visible in yaml, in the BuildConfig the path is spec.strategy.dockerStrategy.env, like this:
spec:
strategy:
dockerStrategy:
env:
- name: PG_USERNAME
value: placeholder
- name: PG_EMAIL
valueFrom:
secretKeyRef:
name: pgadmin
key: email
and in the Deployment in spec.template.spec.containers.x either under env or envFrom.
template:
spec:
containers:
- name: my-container-1
env:
- name: PG_PASSWORD
value: placeholder
- name: PG_EMAIL
valueFrom:
secretKeyRef:
name: my-secret
key: email
As you may have noticed, the Deployment is given an additional envFrom attribute, which lets you import the entire contents of a Secret or ConfigMap instead of having to explicitly name each field. Below are examples for both a Secret and a ConfigMap.
template:
spec:
containers:
- name: my-container-1
envFrom:
- secretRef:
name: my-secret
- configMapRef:
name: my-configmap
Using Volume Mounts
Using volume mounts for Secrets and ConfigMaps is slightly harder, but has clear advantages. As mentioned above, the Kubernetes API will notice changes in Secret or ConfigMap objects, and eventually updates the volume mount containing the object. Do note that the object needs to exist for the pods to start, and that the mountPath overwrites anything the container image may have placed in the same location. Also, when mounting a ConfigMap or Secret to multiple containers in a single pod, you need to define the volumeMounts for each container, but the spec.volumes is part of the Pod that houses all containers. This means you need to define volumes just once.
Also, all of the examples below are for Pod resources. When using Deployments, the values for containers and volumes should fall under spec.template. Below you will find a table clarifying this.
| Pod | Deployment |
|---|---|
spec: | spec: |
The example in the Kubernetes docs shows that the following yaml can be used to add the contents of the ConfigMap my-configmap to the container in path /etc/config.
containers:
- name: my-container-1
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-configmap
If your configmap has multiple keys, it is also possible to mount a specific key to a specific path. You can do this by adding items to the definition of your volumes, in this case mapping VALUE_1 to /etc/config/values in the container my-container-1.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
VALUE_1: config
VALUE_2: map
---
# Pod
...
spec:
containers:
- name: my-container-1
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-configmap
items:
- key: VALUE_1
path: values
volumemount for Secrets
Everything else stays the same, but field names change a little inside the volumes definition.
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
The kubernetes docs has an example of creating files starting with dots, such as .secrets. In another part of the documentation it is mentioned that if users have access to a service that needs to do something with secrets, it would be smart to use localhost forwarding and two containers. One for customers to connect to, and another that has access to Secrets.
There are also alternatives to Secrets, and operators like Reloader that can trigger updates of pods when updates happen.
For more information about storage, check out volumes and storage.