# 7: Kubernetes Deployment Strategies and Rollouts: A Comprehensive Guide with Examples

When working with Kubernetes, managing application updates and deployments is crucial for ensuring stability and availability. Kubernetes provides several deployment strategies to suit different use cases, environments, and requirements. This blog will cover these strategies in detail, including examples, commands, and common troubleshooting steps.

---

## Deployment Strategies in Kubernetes

Kubernetes offers multiple deployment strategies to manage application updates. Each has unique advantages and trade-offs:

### 1\. **Recreate Strategy**

* **Concept**: The existing application pods (e.g., version 1) are terminated before starting the new application pods (e.g., version 2).
    
* **Usage**: Best suited for **development environments** where downtime is acceptable.
    
* **Trade-offs**: Causes downtime since the old version stops before the new version starts.
    

```plaintext
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  strategy:
    type: Recreate
  template:
    spec:
      containers:
        - name: app-container
          image: my-app:v2
```

> This approach leads to downtime while switching versions.

---

### 2\. **Rolling Update (Ramped Deployment)**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732535001356/a25ea412-e8b3-4e04-ba87-048dbda18d9b.png align="center")

* **Concept**: Gradually replaces old pods with new pods while maintaining service availability.
    
* **Usage**: The default strategy in Kubernetes, suitable for **production environments**.
    
* **Trade-offs**: Avoids downtime but might cause version conflicts during the transition phase.
    
* **Command**:
    
    ```plaintext
    kubectl apply -f deployment.yaml
    ```
    

**Example:**

```plaintext
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    spec:
      containers:
        - name: app-container
          image: my-app:v2
```

* **Details**:
    
    * `maxUnavailable`: The number of pods that can be unavailable during the update.
        
    * `maxSurge`: The number of additional pods created during the update.
        

---

### 3\. **Blue/Green Deployment**

* **Concept**: Maintains two environments, "blue" (current version) and "green" (new version). Once the new version is verified, traffic is switched to it.
    
* **Usage**: Ideal for scenarios needing **rapid rollback**.
    
* **Trade-offs**: Requires **double compute resources**, increasing costs.
    

**Example:**

```plaintext
# Update service to point to the green deployment
kubectl set selector service/my-app version=green
```

**Details**:

* The current version (blue) continues to serve traffic.
    
* The new version (green) is deployed alongside, and labels are used to switch traffic.
    

---

### 4\. **Canary Deployment**

* **Concept**: Deploys the new version to a subset of users for testing, gradually increasing traffic.
    
* **Usage**: Effective for **feature validation** or **incremental testing**.
    
* **Trade-offs**: Requires traffic management tools (e.g., **HAProxy**, **Istio**, or **Linkerd**).
    

**Example Using Service Mesh**:

```plaintext
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
spec:
  hosts:
    - my-app.example.com
  http:
    - route:
        - destination:
            host: my-app
            subset: v1
          weight: 90
        - destination:
            host: my-app
            subset: v2
          weight: 10
```

---

### 5\. **A/B Testing**

* **Concept**: Similar to canary, but users are split into groups based on specific characteristics (e.g., location, device type) for feature testing.
    
* **Usage**: Useful for testing user experiences or feedback.
    
* **Example**:
    
    * Use tools like **NGINX ingress** or **Istio** to route traffic conditionally.
        

**Example**:

```plaintext
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app-ab
spec:
  hosts:
    - my-app.example.com
  http:
    - match:
        - headers:
            user-group:
              exact: test-group
      route:
        - destination:
            host: my-app
            subset: v2
    - route:
        - destination:
            host: my-app
            subset: v1
```

---

## Managing Deployment Rollouts in Kubernetes

### Checking Rollout History

Kubernetes maintains a history of deployments. You can view the rollout history and annotate changes for better tracking.

#### Common Commands:

* View history:
    
    ```plaintext
    kubectl rollout history deployment/my-app
    ```
    
* Add change-cause annotation:
    
    ```plaintext
    kubectl annotate deployment.apps my-app kubernetes.io/change-cause="Updated to v2"
    ```
    
* Record changes automatically:
    
    ```plaintext
    kubectl apply -f deployment.yaml --record=true
    ```
    

### Rollbacks

Rollback to a previous version if needed:

* Rollback to the last version:
    
    ```plaintext
    kubectl rollout undo deployment/my-app
    ```
    
* Rollback to a specific revision:
    
    ```plaintext
    kubectl rollout undo deployment/my-app --to-revision=2
    ```
    

### Setting Revision History Limit

To avoid managing excessive replicasets:

* Add the `revisionHistoryLimit` field in your deployment:
    
    ```plaintext
    spec:
      revisionHistoryLimit: 5
    ```
    

---

## Key Insights and Best Practices

1. **Imperative vs. Declarative Updates**:  
    Use declarative YAML configurations over imperative commands for better traceability.
    

```plaintext
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deploy
  annotations:
    kubernetes.io/change-cause: "version 1"
spec:
  replicas: 10
  selector:
     matchLabels:
        app: hello-world
  minReadySeconds: 10
  strategy:
     type: RollingUpdate
     rollingUpdate:
        maxUnavailable: 1
        maxSurge: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-pod
        image: lovelearnlinux/webserver:v1
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 100m
            memory: 128Mi
          requests:
            cpu: 50m
            memory: 100Mi
```

```plaintext
  annotations:
    kubernetes.io/change-cause: "version 1"
```

1. **ReplicaSet Metadata**:  
    In rolling updates, while pods are deleted, the old replicaset's metadata persists unless manually cleaned.
    
2. **Zero Downtime Deployment**:  
    To achieve true ZDD, combine rolling updates with health checks and liveness probes.
    

---
