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:

  1. Two containers, both using busybox image with restartPolicy: Never
  2. Container frontend:
    • Runs: sh -c "echo frontend: ROLE=$ROLE PORT=$PORT && sleep 3600"
    • Has env vars: ROLE=frontend, PORT=8080
  3. 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

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

  1. Use fieldRef for operational metadata — Pod name and IP are useful for logging and debugging without hardcoding values.
  2. Keep env vars per container — Remember that env vars are scoped to individual containers, not the Pod.
  3. Avoid secrets in plain env vars — Use Secrets (Exercise 08) or Key Vault (Exercise 09) for sensitive values.
  4. Use ConfigMaps for shared configuration — When multiple Pods need the same env vars, use ConfigMaps (Exercise 07) instead of duplicating values.
  5. Name env vars consistently — Follow a convention like APP_NAME, DB_HOST, LOG_LEVEL across all your workloads.

Summary

In this exercise you learned how to:

  • Define static environment variables in a Pod spec
  • Use fieldRef to 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.

results matching ""

    No results matching ""