How to Set Replicas, MaxSurge and MaxUnavailable values for Rolling Updates

# How to Set Replicas, MaxSurge, and MaxUnavailable Values for Rolling Updates

Rolling updates are a common strategy for deploying changes to a Kubernetes cluster without downtime. In this article, we’ll explore the key configuration values—**Replicas**, **MaxSurge**, and **MaxUnavailable**—that control the behavior of rolling updates. We’ll also discuss how these values affect deployment time and provide a code example to tie it all together.

---

## What Are Replicas, MaxSurge, and MaxUnavailable?

### Replicas
The **replicas** value specifies the desired number of pod instances for a deployment. These pods run simultaneously and ensure high availability and scalability.  
For example, in the following code:  
```yaml
spec:
  replicas: 20
```
The deployment ensures 20 pods are running. During a rolling update, Kubernetes will work to maintain the specified number of pods, adjusting how many are added or removed based on the other values.

### MaxSurge
The maxSurge value defines how many additional pods can be temporarily created during a rolling update. These extra pods allow the system to handle requests while new pods are being initialized.
For example, in the following code:  
```yaml
rollingUpdate:
  maxSurge: 1
```
This configuration allows 1 additional pod to be created above the specified replicas during an update.

### MaxUnavailable
The maxUnavailable value controls how many pods can be unavailable (e.g., terminated or not ready) at a time during a rolling update.
For example, in the following code:  
```yaml
rollingUpdate:
  maxUnavailable: 1
```
This configuration ensures that no more than 1 pod is unavailable at any time during the update process.

---

## What is a rolling update?
A rolling update is a Kubernetes deployment strategy that replaces pods incrementally to avoid downtime. Instead of shutting down all pods and starting new ones, rolling updates replace pods one by one (or based on configured limits). This ensures continuous availability of the application while updates are being applied.

---

## How Do Replicas, MaxSurge, and MaxUnavailable Affect Rolling Updates?
1. **Replicas**: Dictates the baseline number of pods. For example, with replicas: 20, Kubernetes tries to maintain 20 functional pods throughout the update.
2. **MaxSurge**: Controls how many extra pods can be created during the update. Higher values allow for faster updates but may temporarily increase resource usage.
3. **MaxUnavailable**: Sets a limit on how many pods can be unavailable. Lower values ensure better availability but may slow down the update process.

--- 
## Example Scenario
Given the configuration below:

We will be using a yaml wordpress deployment file. below is the full file source code.
```yaml
apiVersion: v1
kind: Service
metadata:
  name: roll
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 6
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - name: wordpress
        image: wordpress:6.2.1-apache
        imagePullPolicy: Always
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        - name: WORDPRESS_DB_USER
          value: wordpress
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim
```
To apply this file, use the following command:
```
kubectl apply -f wordpress-deployment.yaml 
```
Below is the part where the replicas, maxsurge and maxunavailable values are changed.
```yaml
spec:
  replicas: 6
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
```
- Replicas: 20 ensures 20 pods are running.
- MaxSurge: 1 allows Kubernetes to temporarily run 21 pods (20 + 1 extra).
- MaxUnavailable: 1 ensures no more than 1 pod is unavailable during the update.

In this setup, Kubernetes updates 1 pod at a time:

1. Creates a new pod (total: 21).
2. Waits for the new pod to be ready.
3. Terminates 1 old pod (total: 20). This process repeats until all pods are updated.

---
## Output Example
For the example, i will be using the above YAML file. the values for replicas, maxSurge and maxUnavailable will be as of below:
replicas : 3
maxSurge : 1
maxUnavailable : 1

I will apply the deployment using the following command:
```terminal
kubectl apply -f wordpress-deployment.yaml 
```
To monitor the progress of the pod, I will be using the following command to monitor the deployment progress in real time:
```terminal
kubectl get pod -w -n roll
```

The output at the terminal will be like this:
```terminal
roll1-c0a22173@roll1:~/roll1$ kubectl get pod -w
NAME                         READY   STATUS              RESTARTS   AGE
hello-dep-7db6667867-ncnkx   1/1     Running             0          20s
hello-dep-7db6667867-vjn5c   1/1     Running             0          20s
hello-dep-858675448b-qgdn8   0/1     ContainerCreating   0          1s
hello-dep-858675448b-qgdn8   1/1     Running             0          5s
hello-dep-7db6667867-vjn5c   1/1     Terminating         0          24s
hello-dep-858675448b-jfjrz   0/1     Pending             0          0s
hello-dep-858675448b-jfjrz   0/1     Pending             0          0s
hello-dep-858675448b-jfjrz   0/1     ContainerCreating   0          0s
hello-dep-7db6667867-vjn5c   0/1     Terminating         0          24s
hello-dep-7db6667867-vjn5c   0/1     Terminating         0          25s
hello-dep-7db6667867-vjn5c   0/1     Terminating         0          25s
hello-dep-858675448b-jfjrz   1/1     Running             0          1s
hello-dep-7db6667867-ncnkx   1/1     Terminating         0          25s
hello-dep-7db6667867-ncnkx   0/1     Terminating         0          26s
hello-dep-7db6667867-ncnkx   0/1     Terminating         0          27s
hello-dep-7db6667867-ncnkx   0/1     Terminating         0          27s
```

The output shows that the deployed containers which were initially in the Running status have changed to the Terminating status. This is because the old pods have been replaced with new ones, causing the old pods to be terminated. 

```terminal
hello-dep-7db6667867-ncnkx   1/1     Running             0          20s
hello-dep-7db6667867-vjn5c   1/1     Running             0          20s
hello-dep-858675448b-qgdn8   0/1     ContainerCreating   0          1s
```
From the part above, which is a cutout of the output, we can see that when maxSurge and maxUnavailable is set to 1, the number of pods that can be updated is only one at a time.

---

## Conclusion
By understanding and configuring replicas, maxSurge, and maxUnavailable, you can control the balance between availability, resource usage, and deployment speed during rolling updates. Tuning these values to match your application's needs ensures a smooth deployment process without compromising user experience.

---