In this section, we’ll explore some more advanced techniques and features for managing configuration data in Kubernetes.
Projected volumes are a special volume type that allows you to combine data from multiple sources into a single directory in your container. This is particularly useful when you need to access configuration data from different sources in the same location.
A projected volume can combine data from:
apiVersion: v1
kind: Pod
metadata:
name: projected-volume-demo
spec:
containers:
- name: app
image: nginx:1.19
volumeMounts:
- name: config-volume
mountPath: /etc/config
readOnly: true
volumes:
- name: config-volume
projected:
sources:
- configMap: # Source 1: ConfigMap
name: app-config
items:
- key: app.properties
path: app.properties
- secret: # Source 2: Secret
name: app-secrets
items:
- key: api-key
path: api.key
mode: 0400 # Custom permissions
- downwardAPI: # Source 3: Downward API
items:
- path: "namespace"
fieldRef:
fieldPath: metadata.namespace
- path: "cpu-limit"
resourceFieldRef:
containerName: app
resource: limits.cpu
- serviceAccountToken: # Source 4: ServiceAccount token
path: token
expirationSeconds: 3600
In this example:
/etc/config/app.properties comes from the ConfigMap app-config/etc/config/api.key comes from the Secret app-secrets with 0400 permissions/etc/config/namespace contains the current namespace name/etc/config/cpu-limit contains the CPU limit of the container/etc/config/token contains a short-lived ServiceAccount tokenKubernetes 1.19+ supports making ConfigMaps and Secrets immutable, which offers several benefits:
To make a ConfigMap or Secret immutable, add the immutable: true field:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
environment=production
log.level=info
immutable: true # Makes this ConfigMap immutable
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
username: admin
password: s3cr3t
immutable: true # Makes this Secret immutable
Once a ConfigMap or Secret is marked as immutable:
This requires careful planning for updates:
Example update process:
# Create new ConfigMap with updated data
kubectl create configmap app-config-v2 --from-file=app.properties=path/to/new-app.properties
# Update deployment to use the new ConfigMap
kubectl set volumes deployment/app-deployment \
--add --name=config-volume \
--type=configmap \
--configmap-name=app-config-v2 \
--mount-path=/etc/config
The Downward API allows Pods to access their own metadata and the resources assigned to them, without needing to contact the Kubernetes API directly.
You can access this information through:
apiVersion: v1
kind: Pod
metadata:
name: downward-api-env
labels:
app: web
tier: frontend
spec:
containers:
- name: main
image: busybox
command: ["sleep", "3600"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: main
resource: limits.cpu
apiVersion: v1
kind: Pod
metadata:
name: downward-api-volume
labels:
app: web
tier: frontend
spec:
containers:
- name: main
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
- path: "cpu-request"
resourceFieldRef:
containerName: main
resource: requests.cpu
divisor: 1m
fieldRef (Pod-level information):
metadata.name - Pod namemetadata.namespace - Namespacemetadata.uid - Pod UIDmetadata.labels - All Pod labelsmetadata.annotations - All Pod annotationsspec.nodeName - Node namespec.serviceAccountName - ServiceAccount namestatus.hostIP - Host IPstatus.podIP - Pod IPresourceFieldRef (Container-level information):
requests.cpu - CPU requestslimits.cpu - CPU limitsrequests.memory - Memory requestslimits.memory - Memory limitsrequests.ephemeral-storage - Ephemeral storage requestslimits.ephemeral-storage - Ephemeral storage limitsWhile Kubernetes Secrets are sufficient for many use cases, enterprise environments often require more advanced secrets management solutions.
The External Secrets Operator (ESO) is a Kubernetes operator that integrates with external secret management systems:
Example ExternalSecret resource:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: database/credentials
property: username
- secretKey: password
remoteRef:
key: database/credentials
property: password
Sealed Secrets allows you to encrypt your Secrets so they can be safely stored in version control:
kubeseal command-line toolExample workflow:
# Create a Secret
kubectl create secret generic db-creds \
--from-literal=username=admin \
--from-literal=password=s3cr3t \
--dry-run=client -o yaml > db-creds-secret.yaml
# Encrypt the Secret
kubeseal --format yaml < db-creds-secret.yaml > db-creds-sealed.yaml
# Apply the SealedSecret
kubectl apply -f db-creds-sealed.yaml
HashiCorp’s Vault Agent Injector automatically injects secrets from Vault into Kubernetes Pods using init containers and annotations:
apiVersion: v1
kind: Pod
metadata:
name: vault-demo
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-database-creds: "database/creds/db-app"
vault.hashicorp.com/role: "db-app"
spec:
containers:
- name: app
image: app:1.0
With these annotations, Vault Agent Injector will:
Each major cloud provider offers native solutions for Kubernetes secrets management:
These solutions typically mount secrets as files in Pods using the Secrets Store CSI Driver.
Example using Azure Key Vault:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kv-provider
spec:
provider: azure
parameters:
usePodIdentity: "true"
keyvaultName: "my-keyvault"
objects: |
array:
- |
objectName: db-password
objectType: secret
---
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: app:1.0
volumeMounts:
- name: secrets-store
mountPath: "/mnt/secrets"
readOnly: true
volumes:
- name: secrets-store
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "azure-kv-provider"
Use Projected Volumes when you need to combine multiple configuration sources
Make Critical Configuration Immutable to prevent accidental changes
Leverage Downward API for Pod-aware configuration
app-config-v1, app-config-v2For the CKAD exam, focus on:
While enterprise solutions like External Secrets Operator are not typically covered in the CKAD exam, understanding the basics of Kubernetes’ native configuration mechanisms is essential.
In the next section, we’ll put everything together with practical exercises to help you prepare for the CKAD exam.