CKAD — ConfigMaps & Secrets Lab

2 minute read

Lab 1: ConfigMap as Environment Variables and Volume

# Create a ConfigMap
kubectl create configmap web-config \
  --from-literal=APP_COLOR=blue \
  --from-literal=APP_MODE=production

# Create a Pod that uses it
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - name: web
    image: busybox:1.36
    command: ["/bin/sh", "-c", "echo Color=\$APP_COLOR Mode=\$APP_MODE && cat /config/APP_COLOR && sleep 3600"]
    envFrom:
    - configMapRef:
        name: web-config
    volumeMounts:
    - name: config-vol
      mountPath: /config
  volumes:
  - name: config-vol
    configMap:
      name: web-config
EOF

# Check env vars
kubectl logs web
# Expected: Color=blue Mode=production

# Check mounted files
kubectl exec web -- ls /config
# APP_COLOR  APP_MODE

kubectl exec web -- cat /config/APP_COLOR
# blue

Lab 2: Secrets for Database Credentials

# Create a Secret
kubectl create secret generic db-creds \
  --from-literal=username=app_user \
  --from-literal=password=MyS3cret!

# Create a Pod using the Secret
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: db-client
spec:
  containers:
  - name: client
    image: busybox:1.36
    command: ["/bin/sh", "-c", "echo Connecting as \$DB_USER && sleep 3600"]
    env:
    - name: DB_USER
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: username
    - name: DB_PASS
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: password
    volumeMounts:
    - name: creds
      mountPath: /etc/db
      readOnly: true
  volumes:
  - name: creds
    secret:
      secretName: db-creds
EOF

# Verify
kubectl logs db-client
kubectl exec db-client -- cat /etc/db/password

Practice Questions

Q1: Create a ConfigMap named ui-config with keys THEME=dark and LANG=en. Then create a Pod that uses all keys as environment variables.

Show Answer ```bash kubectl create configmap ui-config --from-literal=THEME=dark --from-literal=LANG=en ``` ```yaml apiVersion: v1 kind: Pod metadata: name: ui spec: containers: - name: ui image: busybox:1.36 command: ["/bin/sh", "-c", "env | grep -E 'THEME|LANG' && sleep 3600"] envFrom: - configMapRef: name: ui-config ```

Q2: Create a Secret named api-key with key TOKEN=abc123xyz. Then decode the value from the command line.

Show Answer ```bash kubectl create secret generic api-key --from-literal=TOKEN=abc123xyz # View encoded value kubectl get secret api-key -o jsonpath='{.data.TOKEN}' # YWJjMTIzeHl6 # Decode it kubectl get secret api-key -o jsonpath='{.data.TOKEN}' | base64 -d # abc123xyz ```

Q3: What happens when you update a ConfigMap that is mounted as a volume vs used as an env var?

Show Answer - **Volume mount:** The files are automatically updated (within approximately 1 minute via kubelet sync). No Pod restart needed. - **Environment variables:** NOT updated. The env vars are set when the container starts and do not change. You must restart the Pod (e.g., `kubectl rollout restart deployment/web`) to pick up changes.

Q4: Mount only the password key from Secret db-creds as a file at /etc/secrets/db-password.

Show Answer ```yaml apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: nginx:1.27 volumeMounts: - name: secret-vol mountPath: /etc/secrets readOnly: true volumes: - name: secret-vol secret: secretName: db-creds items: - key: password path: db-password ``` The file `/etc/secrets/db-password` will contain the decoded password value.

Q5: What is the difference between data and stringData in a Secret YAML?

Show Answer - **`data`** — Values must be **base64 encoded**. This is what Kubernetes stores internally. - **`stringData`** — Values are in **plain text**. Kubernetes automatically base64-encodes them when creating the Secret. `stringData` is a convenience for writing YAML by hand. Both produce the same result. You cannot use both for the same key. ```yaml # Using data (base64 encoded) data: password: czNjdXJlUEBzcyE= # Using stringData (plain text) stringData: password: "s3cureP@ss!" ```

← Previous: ConfigMap vs Secret Next: Resource Management →

Updated: