In the previous Chapter, you deployed your Task API to DOKS with a basic configuration. But production services need more than hardcoded values. Your AI agent needs database credentials, API keys for external services, and environment-specific settings that change between staging and production.
Storing these directly in Deployment manifests creates security risks and operational headaches. Every configuration change requires a new container image or manifest edit. Worse, secrets end up in version control where anyone with repository access can read them.
Kubernetes solves this with two primitives: Secrets for sensitive data and ConfigMaps for non-sensitive configuration. This lesson teaches you to use both effectively, including the critical image pull secret that authenticates your cluster to pull images from GitHub Container Registry.
This lesson covers 5 concepts organized into three groups:
Prerequisites:
Time Estimate: 25 minutes
A Kubernetes Secret stores sensitive data like passwords, tokens, and certificates. Unlike ConfigMaps, Secrets are base64-encoded (not encrypted by default, but protected from casual viewing) and can be restricted with RBAC.
Output:
Output:
The values are base64-encoded, not encrypted. Anyone with kubectl get secret access can decode them:
Output:
Security Note: Base64 is encoding, not encryption. For true at-rest encryption, enable Kubernetes secrets encryption or use a secrets manager like HashiCorp Vault or cloud provider secrets (AWS Secrets Manager, GCP Secret Manager).
Your Task API container lives in GitHub Container Registry (GHCR), which requires authentication. Without an image pull secret, Kubernetes cannot pull your private images.
Output:
Where:
Output:
Add imagePullSecrets to your Deployment spec:
Without this reference, pod creation fails with ImagePullBackOff:
Output (without secret):
ConfigMaps store configuration data that isn't sensitive: feature flags, service URLs, logging levels. Unlike Secrets, ConfigMaps appear in plain text and are easier to inspect.
Output:
For complex configuration, use a file:
Output:
Output:
Production applications need layered configuration: defaults that work everywhere, environment overrides for staging vs production, and secrets that are never committed to version control.
Environment variables from higher layers override lower layers.
Output (kubectl describe pod):
If LOG_LEVEL appears in both ConfigMap and as a hardcoded env var, the ConfigMap value wins because envFrom is processed after env. Secrets in envFrom are processed last, so they override everything.
Deploying configuration is only half the battle. You must verify that containers receive the expected values.
Output:
Output:
If expected variables are missing, check:
ConfigMap/Secret exists:
Deployment references are correct:
From ```
Pod events for errors:
Output (missing ConfigMap):
1. Forgetting imagePullSecrets for Private Registries
Fix: Always include imagePullSecrets when using private registries:
2. Putting Secrets in ConfigMaps
Fix: Use Secrets for sensitive data:
3. Using Wrong Secret Type for Docker Registry
Fix: Use docker-registry type:
4. Forgetting to Restart Pods After Secret Update
Updating a Secret doesn't automatically restart pods:
Fix: Restart the deployment:
Create secrets for your Task API with database credentials and an API key.
Instructions:
Create the secret:
Verify creation:
Expected output: Secret listed with Opaque type and 2 data items.
Set up authentication for GitHub Container Registry.
Instructions:
Create a GitHub personal access token with read:packages scope at https://github.com/settings/tokens
Create the secret (replace with your values):
Verify:
Expected output: kubernetes.io/dockerconfigjson
Create a ConfigMap and update your deployment to use the three-layer configuration pattern.
Instructions:
Create ConfigMap:
Apply updated deployment with all references (save as task-api-full.yaml):
Apply and verify:
Expected output: Both ConfigMap and Secret values visible in pod environment.
Part 1: Initial Request
Your Task API needs additional secrets for a new feature: Redis connection string and a webhook signing secret. Ask AI for help:
"I need to add Redis and webhook secrets to my Kubernetes deployment. Create kubectl commands to add REDIS_URL and WEBHOOK_SECRET to my existing task-api-secrets."
What you're learning: How to extend existing secrets without recreating them from scratch.
Part 2: Critical Evaluation
Review AI's response. Ask yourself:
Part 3: Configuration Hierarchy
Ask AI about a more advanced pattern:
"I want to use external-secrets operator to pull secrets from AWS Secrets Manager instead of creating them with kubectl. Is this better than what I'm doing now?"
What you're learning: The difference between simple kubectl-based secrets (good for learning) and enterprise patterns (external-secrets operator).
Part 4: Validation
Verify the secrets work by checking your pod:
If the variable appears with the expected value, your secret management is working.
You built a multi-cloud-deployer skill in an earlier Chapter. Test and improve it based on what you learned.
Ask yourself:
If you found gaps: