06: Environment Variables
06: Environment Variables
Objective
- Understand how to pass configuration to containers using environment variables
- Learn the difference between static env vars and dynamic values from the Kubernetes API (fieldRef)
- Practice defining env vars at the container level in multi-container Pods
Theory
Environment Variables in Kubernetes
Environment variables are the simplest way to pass configuration to containers. In a Pod spec, you define them under spec.containers[].env as a list of name-value pairs.
There are two main approaches:
| Approach | Description | Example Use Case |
|---|---|---|
| Static value | Hardcoded string in the Pod manifest | Application name, environment label, team ownership |
| fieldRef | Dynamically populated from Pod metadata at runtime | Pod name, Pod IP, node name, namespace |
Static Values
env:
- name: ENVIRONMENT
value: "production"
The value is set at Pod creation time and does not change.
fieldRef — Pod Metadata as Environment Variables
Kubernetes can inject information about the running Pod into environment variables using the Downward API via fieldRef:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
Commonly Used fieldRef Fields
| fieldPath | Value |
|---|---|
metadata.name |
Name of the Pod |
metadata.namespace |
Namespace where the Pod runs |
status.podIP |
IP address assigned to the Pod |
spec.nodeName |
Name of the node where the Pod is scheduled |
metadata.labels['<KEY>'] |
Value of a specific label |
metadata.annotations['<KEY>'] |
Value of a specific annotation |
Key Points
- Environment variables are defined per container, not per Pod.
- In a multi-container Pod, each container has its own independent set of env vars.
- Env vars are set once at container startup and do not update if the source changes.
Practical Tasks
Task 1: Pod with Simple Environment Variables
Create a Pod that sets static environment variables and prints them.
Create the file env-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: env-pod
namespace: student-XX
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo ENVIRONMENT=$ENVIRONMENT APP_NAME=$APP_NAME TEAM=$TEAM && sleep 3600"]
env:
- name: ENVIRONMENT
value: "staging"
- name: APP_NAME
value: "my-app"
- name: TEAM
value: "platform"
restartPolicy: Never
Apply and verify:
kubectl apply -f env-pod.yaml
# Check the env vars in the container logs
kubectl logs env-pod -n student-XX
# Alternatively, exec into the container
kubectl exec env-pod -n student-XX -- env | grep -E "ENVIRONMENT|APP_NAME|TEAM"
Expected output:
ENVIRONMENT=staging
APP_NAME=my-app
TEAM=platform
Clean up:
kubectl delete pod env-pod -n student-XX
Task 2: Pod with System Environment Variables (fieldRef)
Create a Pod that exposes Kubernetes metadata as environment variables using the Downward API.
Create the file env-fieldref.yaml:
apiVersion: v1
kind: Pod
metadata:
name: env-fieldref
namespace: student-XX
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c"]
args:
- |
echo "POD_NAME=$POD_NAME"
echo "POD_IP=$POD_IP"
echo "NODE_NAME=$NODE_NAME"
echo "POD_NAMESPACE=$POD_NAMESPACE"
sleep 3600
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: Never
Apply and verify:
kubectl apply -f env-fieldref.yaml
# Check the logs
kubectl logs env-fieldref -n student-XX
Expected output (values will vary):
POD_NAME=env-fieldref
POD_IP=10.244.1.15
NODE_NAME=aks-nodepool1-12345678-vmss000000
POD_NAMESPACE=student-XX
Verify with exec:
kubectl exec env-fieldref -n student-XX -- env | grep -E "POD_|NODE_"
Clean up:
kubectl delete pod env-fieldref -n student-XX
Task 3: Challenge — Multi-Container Pod with Separate Env Vars
Challenge: Build the YAML yourself based on the requirements below. Do not look ahead at the verification commands until you have written your manifest.
Create a file env-multi.yaml with a Pod named env-multi in namespace student-XX that meets these requirements:
- Two containers, both using
busyboximage withrestartPolicy: Never - Container
frontend:- Runs:
sh -c "echo frontend: ROLE=$ROLE PORT=$PORT && sleep 3600" - Has env vars:
ROLE=frontend,PORT=8080
- Runs:
- Container
backend:- Runs:
sh -c "echo backend: ROLE=$ROLE PORT=$PORT DB_HOST=$DB_HOST && sleep 3600" - Has env vars:
ROLE=backend,PORT=3000,DB_HOST=db.internal.svc.cluster.local
- Runs:
Goal: Demonstrate that environment variables are scoped per container — each container has its own independent set.
Hint: YAML structure
Use `spec.containers` as an array with two entries. Each entry has its own `env` list. Remember that `restartPolicy` is set at the Pod level, not per container.Apply and verify:
kubectl apply -f env-multi.yaml
# Check logs for each container separately
kubectl logs env-multi -c frontend -n student-XX
kubectl logs env-multi -c backend -n student-XX
# Verify env vars are isolated per container
kubectl exec env-multi -c frontend -n student-XX -- env | grep ROLE
kubectl exec env-multi -c backend -n student-XX -- env | grep ROLE
Expected output for frontend:
frontend: ROLE=frontend PORT=8080
Expected output for backend:
backend: ROLE=backend PORT=3000 DB_HOST=db.internal.svc.cluster.local
Notice that the DB_HOST variable is only available in the backend container and not in frontend.
Clean up:
kubectl delete pod env-multi -n student-XX
Common Problems
| Problem | Cause | Solution |
|---|---|---|
| Env var is empty | Typo in fieldPath or incorrect YAML indentation |
Check kubectl describe pod for warnings |
valueFrom and value both set |
Cannot use both value and valueFrom on the same env entry |
Use only one of them |
| Env var not updating after Pod edit | Env vars are set at container startup | Delete and recreate the Pod |
exec shows extra system env vars |
Kubernetes injects Service-related env vars automatically | Filter with grep for your specific variables |
Best Practices
- Use fieldRef for operational metadata — Pod name and IP are useful for logging and debugging without hardcoding values.
- Keep env vars per container — Remember that env vars are scoped to individual containers, not the Pod.
- Avoid secrets in plain env vars — Use Secrets (Exercise 08) or Key Vault (Exercise 09) for sensitive values.
- Use ConfigMaps for shared configuration — When multiple Pods need the same env vars, use ConfigMaps (Exercise 07) instead of duplicating values.
- Name env vars consistently — Follow a convention like
APP_NAME,DB_HOST,LOG_LEVELacross all your workloads.
Summary
In this exercise you learned how to:
- Define static environment variables in a Pod spec
- Use
fieldRefto inject Pod metadata (name, IP, node, namespace) at runtime - Configure separate environment variables for each container in a multi-container Pod
Proceed to Exercise 07 to learn how to manage configuration with ConfigMaps.