Kubernetes Environment Variables and Secrets - The Basics Explained
Understand how Kubernetes environment variables and Secrets work together to securely manage configuration and sensitive data in your containers.
In Kubernetes, container environments (or container environment variables) refer to key-value pairs that we define and inject into containers running in Pods. These environment variables:
- Are available inside the container just like any other Linux environment variable.
- Can be used to configure the containerized application (e.g. database URLs, credentials, feature flags).
- Can be hardcoded, passed from ConfigMaps/Secrets, or injected dynamically (e.g. Pod name, namespace).
Hardcoded Environment Variable
In a Pod definition (or Deployment), we can specify environment variables under the container[].env field:
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: env-demo
spec:
containers:
- name: myapp
image: ngnix
env:
- name: MY_ENV_VAR
value: "hello-k8"
Inside the container, the app can read MY_ENV_VAR=hello-k8.
Source From a ConfigMap
1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "production"
LOG_LEVEL: debug
Use it in a Pod:
1
2
3
4
5
6
containers:
- name: app
image: myapp
envFrom:
- configMapRef:
name: app-config
All key-value pairs in the ConfigMap become environment variables in the container.
Source From A Secret
1
2
3
4
5
6
7
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
DB_PASSWORD: c2VJcmv0gOGfzcw= # base64 of 'secretpass'
Inject into container:
1
2
3
4
5
6
7
8
9
containers:
- name: app
image: myapp
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
value: DB_PASSWORD
Secrets are namespace scoped and needs to be created before usage or deployment of resources.
How To Apply Secrets
Kubernetes Secrets must be base64-encoded when written as YAML.
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
DB_USERNAME: YWRTaW4= # 'admin'
DB_PASSWORD: c2VJcmv0gOGfzcw= # 'secretpass'
Apply it:
1
kubectl apply -f my-secret.yaml
We can create secrets from CLI without worrying about encoding:
1
2
3
kubectl create secret generic my-secret \
--from-literal=DB_USERNAME=admin \
--from-literal=DB_PASSWORD=secretpass
User secret values as environment variables in Pod:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod
metadata:
name: app-with-secrets
spec:
containers:
- name: app
image: myapp
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
value: DB_PASSWORD
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: DB_USERNAME
Applying Secrets To Specific Namespace
To apply Kubernetes Secrets to a specific namespace, we must ensure the Secret is created in that namespace because Secrets are namespace-scoped.
1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: my-namespace
type: Opaque
data:
DB_PASSWORD: c2VJcmv0gOGfzcw= # base64 of 'secretpass'
Then apply it with:
1
kubectl apply -f my-secret.yaml
Another way is to create a Secret via kubectl in a specific namespace:
1
2
3
kubectl create secret generic my-secret \
--from-literal=DB_PASSWORD=secretpass \
--namespace=my-namespace
To verify if it’s in the right namespace:
1
kubectl get secret -n my-namespace
Applying Secrets To Specific Namespace In The Azure Portal
- Connect kubectl to the AKS cluster (Azure Cloud Shell)
1
az aks get-credentials --resource-group myresgroup --name myaksclustername
Make sure your YAML file includes the correct namespace:
1
2
3
metadata:
name: my-secret
namespace: default # or your target namespace
If secrets.yaml file is on your local machine, but we are working inside Azure Cloud Shell, we must first upload it.
- Open Azure Cloud Shell in the Portal
- Click the Upload/Download button
- Click Upload and select the secrets file
- Then run kubctl apply -f secrets.yaml