project: deployment strategy types in k8s

Source: Dev.to | Jan 05, 2026 (UTC)

Common commands (use for every strategy)

kubectl get deploy,pods,rs,svc kubectl rollout status deploy/<name> kubectl rollout history deploy/<name> kubectl describe pod <pod> kubectl logs <pod> kubectl get events --sort-by=.lastTimestamp | tail -30

Enter fullscreen mode

Exit fullscreen mode

If you need a quick request loop to see behavior:

URL="<your service url>" while true; do curl -s --max-time 1 "$URL" || echo "DOWN"; echo; sleep 0.3; done

Enter fullscreen mode

Exit fullscreen mode

1) RollingUpdate (most used)

Why it’s used most

Behavior

(Deployment + Service)

rolling.yaml

apiVersion: apps/v1 kind: Deployment metadata: {name: rolling} spec: replicas: 3 selector: {matchLabels: {app: rolling}} strategy: type: RollingUpdate rollingUpdate: {maxSurge: 1, maxUnavailable: 1} template: metadata: {labels: {app: rolling}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=ROLLING v1"] ports: [{containerPort: 5678}] --- apiVersion: v1 kind: Service metadata: {name: rolling-svc} spec: selector: {app: rolling} ports: [{port: 80, targetPort: 5678}] type: NodePort

Enter fullscreen mode

Exit fullscreen mode

How to use (demo flow)

kubectl apply -f rolling.yaml kubectl get pods -w kubectl rollout status deploy/rolling

Enter fullscreen mode

Exit fullscreen mode

Get URL:

minikube service rolling-svc --url

Enter fullscreen mode

Exit fullscreen mode

Update “version” (triggers rollout):

kubectl patch deploy rolling --type='json' -p='[ {"op":"replace","path":"/spec/template/spec/containers/0/args/1","value":"-text=ROLLING v2"} ]' kubectl rollout status deploy/rolling

Enter fullscreen mode

Exit fullscreen mode

Troubleshooting (production style)

Symptom: rollout stuck / never completes

  1. Check rollout:

kubectl rollout status deploy/rolling kubectl get rs kubectl get pods

Enter fullscreen mode

Exit fullscreen mode

  1. Find failing Pod and inspect:

kubectl describe pod <new-pod> kubectl logs <new-pod> kubectl get events --sort-by=.lastTimestamp | tail -30

Enter fullscreen mode

Exit fullscreen mode

Common causes:

Fast rollback

kubectl rollout undo deploy/rolling kubectl rollout status deploy/rolling

Enter fullscreen mode

Exit fullscreen mode

Operational note
In production you nearly always add readiness checks, but they are omitted here to keep YAML minimal.

2) Recreate (rarely used)

Why it’s rarely used

When it’s used

Behavior

recreate.yaml

apiVersion: apps/v1 kind: Deployment metadata: {name: recreate} spec: replicas: 3 strategy: {type: Recreate} selector: {matchLabels: {app: recreate}} template: metadata: {labels: {app: recreate}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=RECREATE v1"] ports: [{containerPort: 5678}] --- apiVersion: v1 kind: Service metadata: {name: recreate-svc} spec: selector: {app: recreate} ports: [{port: 80, targetPort: 5678}] type: NodePort

Enter fullscreen mode

Exit fullscreen mode

How to use

kubectl apply -f recreate.yaml URL=$(minikube service recreate-svc --url)

Enter fullscreen mode

Exit fullscreen mode

Trigger change:

kubectl patch deploy recreate --type='json' -p='[ {"op":"replace","path":"/spec/template/spec/containers/0/args/1","value":"-text=RECREATE v2"} ]'

Enter fullscreen mode

Exit fullscreen mode

Troubleshooting

Symptom: brief outage during deploy

Symptom: service never returns

kubectl get pods kubectl describe pod <pod> kubectl logs <pod> kubectl get events --sort-by=.lastTimestamp | tail -30

Enter fullscreen mode

Exit fullscreen mode

3) Blue–Green (common for critical releases)

Why it’s used

Tradeoffs

Behavior

Smallest YAML (blue+green+svc)

blue-green.yaml

apiVersion: apps/v1 kind: Deployment metadata: {name: blue} spec: replicas: 2 selector: {matchLabels: {app: bg, color: blue}} template: metadata: {labels: {app: bg, color: blue}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=BLUE v1"] ports: [{containerPort: 5678}] --- apiVersion: apps/v1 kind: Deployment metadata: {name: green} spec: replicas: 2 selector: {matchLabels: {app: bg, color: green}} template: metadata: {labels: {app: bg, color: green}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=GREEN v2"] ports: [{containerPort: 5678}] --- apiVersion: v1 kind: Service metadata: {name: bg-svc} spec: selector: {app: bg, color: blue} ports: [{port: 80, targetPort: 5678}] type: NodePort

Enter fullscreen mode

Exit fullscreen mode

How to use

kubectl apply -f blue-green.yaml URL=$(minikube service bg-svc --url) curl -s $URL && echo

Enter fullscreen mode

Exit fullscreen mode

Switch to green:

kubectl patch svc bg-svc -p '{"spec":{"selector":{"app":"bg","color":"green"}}}' curl -s $URL && echo

Enter fullscreen mode

Exit fullscreen mode

Rollback to blue:

kubectl patch svc bg-svc -p '{"spec":{"selector":{"app":"bg","color":"blue"}}}'

Enter fullscreen mode

Exit fullscreen mode

Troubleshooting

Symptom: after switch you still hit old version

  1. Check Service selector and endpoints:

kubectl get svc bg-svc -o yaml | sed -n '1,80p' kubectl get endpoints bg-svc -o wide

Enter fullscreen mode

Exit fullscreen mode

  1. Verify labels match:

kubectl get pods --show-labels | grep bg

Enter fullscreen mode

Exit fullscreen mode

Most common root cause:

Symptom: green is unhealthy

kubectl rollout status deploy/green kubectl logs deploy/green

Enter fullscreen mode

Exit fullscreen mode

Operational best practice:

4) Canary (highly used in mature production setups)

Why it’s used

Tradeoffs

Behavior

canary.yaml

apiVersion: apps/v1 kind: Deployment metadata: {name: stable} spec: replicas: 3 selector: {matchLabels: {app: canary, track: stable}} template: metadata: {labels: {app: canary, track: stable}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=STABLE v1"] ports: [{containerPort: 5678}] --- apiVersion: apps/v1 kind: Deployment metadata: {name: canary} spec: replicas: 1 selector: {matchLabels: {app: canary, track: canary}} template: metadata: {labels: {app: canary, track: canary}} spec: containers: - name: app image: hashicorp/http-echo:0.2.3 args: ["-listen=:5678","-text=CANARY v2"] ports: [{containerPort: 5678}] --- apiVersion: v1 kind: Service metadata: {name: canary-svc} spec: selector: {app: canary} ports: [{port: 80, targetPort: 5678}] type: NodePort

Enter fullscreen mode

Exit fullscreen mode

How to use

kubectl apply -f canary.yaml URL=$(minikube service canary-svc --url) for i in {1..25}; do curl -s $URL; echo; done

Enter fullscreen mode

Exit fullscreen mode

Promote (increase canary):

kubectl scale deploy/canary --replicas=2

Enter fullscreen mode

Exit fullscreen mode

Abort (remove canary immediately):

kubectl scale deploy/canary --replicas=0

Enter fullscreen mode

Exit fullscreen mode

Troubleshooting

Symptom: canary never receives traffic

kubectl get svc canary-svc -o yaml | grep -A3 selector kubectl get pods --show-labels | grep canary

Enter fullscreen mode

Exit fullscreen mode

Symptom: canary causing errors

kubectl scale deploy/canary --replicas=0 kubectl logs deploy/canary kubectl describe pod <canary-pod>

Enter fullscreen mode

Exit fullscreen mode

Operational best practice:

5) A/B (specialized; product-driven)

Why it’s not “default”

Behavior

Minimal A/B in pure Kubernetes (no ingress) isn’t truly possible

Without ingress/mesh you can’t route by headers; you can only do replica-based canary. In production, A/B is usually NGINX Ingress / Istio / Linkerd.

If you want the smallest A/B that is real, it needs ingress + annotations. I can give that minimal manifest as a separate block (it will still be longer than others because routing rules require extra objects).

Summary: what is used more vs rarely (and why)

For further actions, you may consider blocking this person and/or reporting abuse

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Читайте також