You know the Kubernetes primitives. Now let's deploy a production-quality application end to end, incorporating the patterns that make Kubernetes deployments reliable.
A Production-Ready Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: production
labels:
app: api-server
version: v2.1.0
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # allow 1 extra Pod during update
maxUnavailable: 0 # keep all replicas available (zero-downtime)
template:
metadata:
labels:
app: api-server
version: v2.1.0
spec:
serviceAccountName: api-server-sa
containers:
- name: api
image: my-registry/api:v2.1.0 # never use :latest in production
imagePullPolicy: Always
ports:
- containerPort: 3000
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-secrets
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
Health Probes Explained
Liveness Probe
Determines if a container is running correctly. If it fails, Kubernetes restarts the container. Use it to detect deadlocks and stuck processes.
Readiness Probe
Determines if a container is ready to serve traffic. If it fails, Kubernetes removes the Pod from Service endpoints — traffic stops being sent until it recovers. Use it to prevent traffic hitting containers that are still starting up or temporarily overloaded.
Startup Probe
Used for slow-starting containers. Disables liveness and readiness probes until startup completes. Prevents premature restarts.
Resource Requests and Limits
| Requests | Limits | |
|---|---|---|
| Purpose | Minimum guaranteed for scheduling | Maximum allowed |
| Scheduler uses | Yes — to find a node with enough capacity | No |
| Exceeding | N/A | CPU: throttled; Memory: OOMKilled |
Always set requests. Set limits on memory to prevent OOM cascades, but be careful with CPU limits — they can cause unnecessary throttling.
Rolling Updates and Rollbacks
# Update the image version
kubectl set image deployment/api-server api=my-registry/api:v2.2.0
# Watch the rollout progress
kubectl rollout status deployment/api-server
# View rollout history
kubectl rollout history deployment/api-server
# Rollback to previous version
kubectl rollout undo deployment/api-server
# Rollback to a specific revision
kubectl rollout undo deployment/api-server --to-revision=2
Service and Ingress for the Deployment
apiVersion: v1
kind: Service
metadata:
name: api-server
namespace: production
spec:
selector:
app: api-server
ports:
- port: 80
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-server
port:
number: 80
tls:
- hosts: [api.example.com]
secretName: api-tls
Debugging Deployments
# Pod stuck in Pending
kubectl describe pod <pod-name> # check Events section
# Pod in CrashLoopBackOff
kubectl logs <pod-name> --previous # logs from previous crashed container
# Pod in ImagePullBackOff
kubectl describe pod <pod-name> # check image name and registry credentials
# View resource usage
kubectl top pods
kubectl top nodes
Common Deployment Patterns
- Blue/Green: Two identical environments; switch traffic instantly. Zero risk, high cost.
- Canary: Route a small percentage of traffic to the new version first. Catch issues early.
- Rolling (default): Gradually replace old Pods with new. Best balance of safety and resource use.
You've now covered the Kubernetes fundamentals — containers, architecture, workloads, networking, storage, configuration, access control, Helm, and deployments. The next step is hands-on practice with the CKA or CKS certification, or putting these skills to work in AWS with EKS.