Cloud & DevOps6 min read

Kubernetes Workload Management

Run production workloads on Kubernetes: Deployments, Services, Ingress, HPA autoscaling, resource limits, and health probes.

kubernetesk8scontainersdevops

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

  1. Write a production-grade DeploymentA Deployment manages ReplicaSets and provides rolling updates with zero downtime.
  2. Configure health probesProbes prevent traffic from reaching unhealthy pods and restart crashed containers.
  3. Expose with Service and IngressService provides stable DNS and load balancing; Ingress routes external HTTP/HTTPS to Services.
  4. Configure HPA for autoscalingHPA scales pod count based on CPU/memory usage - handles traffic spikes automatically.
  5. 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 upgrades

Edge 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/

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.