# Deployment strategy
* Kubernetes 在計算 availableReplicas 數值時不考慮終止過程中的 Pod, availableReplicas 的值一定介於 replicas - maxUnavailable 和 replicas + maxSurge 之間。 因此,你可能在上線期間看到 Pod 個數比預期的多,Deployment 所消耗的總的資源也大於 replicas + maxSurge 個 Pod 所用的資源,直到被終止的 Pod 所設定的 terminationGracePeriodSeconds 到期為止。
```
# maxSurge、maxUnavailable 可以用數字和 % 宣告,如果使用數字宣告,單位就是 pod 的個數
# maxSurge 代表是在 rolling update 過程中可以創建的額外 Pod 的最大數量或百分比
# maxUnavailable 代表是在 rolling update 過程中允許不可用的 Pod 的最大數量或百分比
$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
strategy:
rollingUpdate:
maxSurge: 1 # 可以多出一個 pod
maxUnavailable: 1 # 允許一個不可提供服務的 pod
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- image: quay.io/cloudwalker/nginx
name: nginx
resources: {}
status: {}' | kubectl apply -f -
```
* 使用 rollout 更新 deploy
```
$ kubectl rollout restart deploy test
```
* deployment 會去呼叫新的 replica 多長出一個 pod,之後就再叫舊的 replica 減少一個 pod,以此類推
```
$ kubectl describe deploy test
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 54s deployment-controller Scaled up replica set test-6477f8d8fd to 5
Normal ScalingReplicaSet 33s deployment-controller Scaled up replica set test-6d7487958d to 1
Normal ScalingReplicaSet 33s deployment-controller Scaled down replica set test-6477f8d8fd to 4 from 5
Normal ScalingReplicaSet 32s deployment-controller Scaled up replica set test-6d7487958d to 2 from 1
Normal ScalingReplicaSet 30s deployment-controller Scaled down replica set test-6477f8d8fd to 3 from 4
Normal ScalingReplicaSet 30s deployment-controller Scaled up replica set test-6d7487958d to 3 from 2
Normal ScalingReplicaSet 28s deployment-controller Scaled down replica set test-6477f8d8fd to 2 from 3
Normal ScalingReplicaSet 28s deployment-controller Scaled up replica set test-6d7487958d to 4 from 3
Normal ScalingReplicaSet 26s deployment-controller Scaled down replica set test-6477f8d8fd to 1 from 2
Normal ScalingReplicaSet 22s (x2 over 26s) deployment-controller (combined from similar events): Scaled down replica set test-6477f8d8fd to 0 from 1
```
* 刪除 deployment
```
$ kubectl delete deploy test
```
### 測試 maxSurge 設為 2
```
$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
strategy:
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- image: quay.io/cloudwalker/nginx
name: nginx
resources: {}
status: {}' | kubectl apply -f -
```
* 使用 rollout 更新 deploy
```
$ kubectl rollout restart deploy test
```
* 可以發現 deployment 第一次呼叫新的 replica 會直接多兩個 pod,但是由於刪除舊的 pod 只有一個,因此第二次新的 replica 只有長出一個 pod。
* pod 數量需要符合 replicas - maxUnavailable 和 replicas + maxSurge 之間,以此題為例, pod 數量就是 4~7 之間。
```
$ kubectl describe deploy test
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 46s deployment-controller Scaled up replica set test-6477f8d8fd to 5
Normal ScalingReplicaSet 18s deployment-controller Scaled up replica set test-77b9c86d to 2
Normal ScalingReplicaSet 18s deployment-controller Scaled down replica set test-6477f8d8fd to 4 from 5
Normal ScalingReplicaSet 17s deployment-controller Scaled up replica set test-77b9c86d to 3 from 2
Normal ScalingReplicaSet 15s deployment-controller Scaled down replica set test-6477f8d8fd to 3 from 4
Normal ScalingReplicaSet 15s deployment-controller Scaled up replica set test-77b9c86d to 4 from 3
Normal ScalingReplicaSet 11s deployment-controller Scaled down replica set test-6477f8d8fd to 2 from 3
Normal ScalingReplicaSet 11s deployment-controller Scaled up replica set test-77b9c86d to 5 from 4
Normal ScalingReplicaSet 11s deployment-controller Scaled down replica set test-6477f8d8fd to 1 from 2
Normal ScalingReplicaSet 9s deployment-controller (combined from similar events): Scaled down replica set test-6477f8d8fd to 0 from 1
```
* 刪除 deployment
```
$ kubectl delete deploy test
```
### 測試 maxSurge 設為 1 maxUnavailable 設為 0
```
$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- image: quay.io/cloudwalker/nginx
name: nginx
resources: {}
status: {}' | kubectl apply -f -
```
```
$ kubectl rollout restart deploy test
```
```
$ kubectl describe deploy test
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set test-86f864c84c to 5
Normal ScalingReplicaSet 10s deployment-controller Scaled up replica set test-6c754cf5f6 to 1
Normal ScalingReplicaSet 8s deployment-controller Scaled down replica set test-86f864c84c to 4 from 5
Normal ScalingReplicaSet 8s deployment-controller Scaled up replica set test-6c754cf5f6 to 2 from 1
Normal ScalingReplicaSet 5s deployment-controller Scaled down replica set test-86f864c84c to 3 from 4
Normal ScalingReplicaSet 5s deployment-controller Scaled up replica set test-6c754cf5f6 to 3 from 2
Normal ScalingReplicaSet 3s deployment-controller Scaled down replica set test-86f864c84c to 2 from 3
Normal ScalingReplicaSet 3s deployment-controller Scaled up replica set test-6c754cf5f6 to 4 from 3
Normal ScalingReplicaSet 1s deployment-controller Scaled down replica set test-86f864c84c to 1 from 2
Normal ScalingReplicaSet 1s deployment-controller (combined from similar events): Scaled up replica set test-6c754cf5f6 to 5 from 4
```
* 刪除 deployment
```
$ kubectl delete deploy test
```
### 測試 maxSurge 設為 0 maxUnavailable 設為 1
```
$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- image: quay.io/cloudwalker/nginx
name: nginx
resources: {}
status: {}' | kubectl apply -f -
```
```
$ kubectl rollout restart deploy test
```
* 會先刪除原本的 pod 在建立新的 pod
```
$ kubectl describe deploy test
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 37s deployment-controller Scaled up replica set test-86f864c84c to 5
Normal ScalingReplicaSet 23s deployment-controller Scaled down replica set test-86f864c84c to 4 from 5
Normal ScalingReplicaSet 23s deployment-controller Scaled up replica set test-5b97f75c85 to 1 from 0
Normal ScalingReplicaSet 20s deployment-controller Scaled down replica set test-86f864c84c to 3 from 4
Normal ScalingReplicaSet 20s deployment-controller Scaled up replica set test-5b97f75c85 to 2 from 1
Normal ScalingReplicaSet 18s deployment-controller Scaled down replica set test-86f864c84c to 2 from 3
Normal ScalingReplicaSet 18s deployment-controller Scaled up replica set test-5b97f75c85 to 3 from 2
Normal ScalingReplicaSet 16s deployment-controller Scaled down replica set test-86f864c84c to 1 from 2
Normal ScalingReplicaSet 16s deployment-controller Scaled up replica set test-5b97f75c85 to 4 from 3
Normal ScalingReplicaSet 14s (x2 over 14s) deployment-controller (combined from similar events): Scaled up replica set test-5b97f75c85 to 5 from 4
```
## 參考文件
https://medium.com/@bubu.tripathy/understanding-maxsurge-and-maxunavailable-4966dfafc8ba
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/