Kubernetes Workload Management
Run production workloads on Kubernetes: Deployments, Services, Ingress, HPA autoscaling, resource limits, and health probes.
Kubernetes (K8s) orchestrates containerized workloads at scale. Production K8s requires understanding core objects (Deployment, Service, Ingress), resource management (requests/limits), autoscaling (HPA), health checks (probes), and configuration management (ConfigMap, Secret).
Set resource requests and limits on every container - resource starvation is the #1 production issue on K8s. Configure both liveness and readiness probes. Use HPA for autoscaling. Store secrets in a secret manager (Vault, AWS Secrets Manager) not K8s Secrets (they're base64 encoded, not encrypted).
Workflow
- Write a production-grade DeploymentA Deployment manages ReplicaSets and provides rolling updates with zero downtime.
- Configure health probesProbes prevent traffic from reaching unhealthy pods and restart crashed containers.
- Expose with Service and IngressService provides stable DNS and load balancing; Ingress routes external HTTP/HTTPS to Services.
- Configure HPA for autoscalingHPA scales pod count based on CPU/memory usage - handles traffic spikes automatically.
- Manage configuration and secretsExternalizing config enables environment promotion without rebuilding images.
Output Format
Deployment with `maxUnavailable: 0`, resource requests/limits, liveness (process health) and readiness (traffic ready) probes, HPA with CPU target, ExternalSecret for credentials.
Examples
Complete pod spec: `containers: - name: api image: myapp:v1.2.3 resources: requests: { memory: "256Mi", cpu: "100m" } limits: { memory: "512Mi", cpu: "500m" } livenessProbe: { httpGet: { path: /health, port: 3000 }, initialDelaySeconds: 30, failureThreshold: 3 } readinessProbe: { httpGet: { path: /ready, port: 3000 }, initialDelaySeconds: 5 } envFrom: [{ configMapRef: { name: api-config } }] env: [{ name: DATABASE_URL, valueFrom: { secretKeyRef: { name: api-secrets, key: database-url } } }]`KEDA: `kind: ScaledObject spec: scaleTargetRef: { name: worker } minReplicaCount: 0 maxReplicaCount: 50 triggers: [{ type: aws-sqs-queue, metadata: { queueURL: https://sqs.../my-queue, queueLength: "5", awsRegion: us-east-1 } }]`PodDisruptionBudget: `kind: PodDisruptionBudget spec: minAvailable: 2 selector: matchLabels: app: api` - prevents k8s drain from taking too many pods offline during cluster upgradesEdge Cases & Gotchas
- OOMKilled: container exits with OOMKilled when it exceeds memory limit. Monitor with `kubectl top pods`. Increase `limits.memory` or fix memory leaks. Set limit ~2x the typical usage to allow for spikes without runaway memory
- Image pull policy: use `Always` only in development; in production use `IfNotPresent` with specific image tags (never `latest`) for reproducibility and speed
- Namespace-level resource quotas: `ResourceQuota` limits total CPU/memory per namespace - prevents one team from consuming all cluster resources
When to Break These Rules
- For small teams (<5 engineers) running <10 services, Kubernetes operational overhead (cluster management, RBAC, networking) outweighs benefits. Use managed platforms (Railway, Render, Fly.io) instead.
Reference Files
Kubernetes docs: https://kubernetes.io/docs/cert-manager: https://cert-manager.io/KEDA: https://keda.sh/External Secrets: https://external-secrets.io/