Deployment為Pod和Replica Set提供聲明式更新。
創建Deployment
nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
創建nginx pod:
$ kubectl create -f nginx-deployment.yaml --record
將kubectl的 --record 的 flag 設置為 true可以在 annotation 中記錄當前命令創建或者升級了該資源。
查看狀態:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 18s
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-2035384211 3 3 0 18s
$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
Deployment已經創建了3個 replica,ReplicaSet 的名字總是
Pod-template-hash label
當 Deployment 創建或者接管 ReplicaSet 時,Deployment controller 會自動為 Pod 添加 pod-template-hash label。這樣做的目的是防止 Deployment 的子ReplicaSet 的 pod 名字重復。通過將 ReplicaSet 的 PodTemplate 進行哈希散列,使用生成的哈希值作為 label 的值,並添加到 ReplicaSet selector 里、 pod template label 和 ReplicaSet 管理中的 Pod 上。
更新Deployment
Deployment 的 rollout 當且僅當 Deployment 的 pod template(例如.spec.template)中的label更新或者鏡像更改時被觸發。
nginx pod 使用nginx:1.9.1的鏡像來代替原來的nginx:1.7.9的鏡像:
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated
使用edit命令來編輯 Deployment,修改 .spec.template.spec.containers[0].image ,將nginx:1.7.9 改寫成 nginx:1.9.1:
$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment" edited
查看狀態:
$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 36s
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 3 3 0 6s
nginx-deployment-2035384211 0 0 0 36s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1564180365-khku8 1/1 Running 0 14s
nginx-deployment-1564180365-nacti 1/1 Running 0 14s
nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
Deployment 可以保證在升級時只有一定數量的 Pod 是 down 的。默認的,它會確保至少有比期望的Pod數量少一個是up狀態(最多一個不可用)。
Deployment 同時也可以確保只創建出超過期望數量的一定數量的 Pod。默認的,它會確保最多比期望的Pod數量多一個的 Pod 是 up 的(最多1個 surge )。
開始創建一個新的 Pod,然后刪除一些舊的 Pod 再創建一個新的。當新的Pod創建出來之前不會殺掉舊的Pod。
回退Deployment
若更新 Deployment 的時候出現拼寫錯誤,Rollout 將會卡住。查看pod會看到新的 ReplicaSet 創建的 Pod 處於 ImagePullBackOff 狀態,循環拉取鏡像。
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated
$ kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 2 2 0 25s
nginx-deployment-2035384211 0 0 0 36s
nginx-deployment-3066724191 2 2 2 6s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1564180365-70iae 1/1 Running 0 25s
nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s
nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s
為了修復這個問題,我們需要回退到穩定的 Deployment revision。
檢查 Deployment 升級的歷史記錄
檢查下 Deployment 的 revision:
$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment":
REVISION CHANGE-CAUSE
1 kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml--record
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91
創建 Deployment 的時候使用了--recored參數可以記錄命令,我們可以很方便的查看每次 revision 的變化。
查看單個revision 的詳細信息:
$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" revision 2
Labels: app=nginx
pod-template-hash=1159050644
Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
QoS Tier:
cpu: BestEffort
memory: BestEffort
Environment Variables: <none>
No volumes.
回退到歷史版本
回退當前的 rollout 到之前的版本:
$ kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
(指定版本回滾)
deployment "nginx-deployment" rolled back
再次查看正常:
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 30m
$ kubectl describe deployment
可以通過設置.spec.revisonHistoryLimit項來指定 deployment 最多保留多少 revision 歷史記錄。默認的會保留所有的 revision;如果將該項設置為0,Deployment就不允許回退了。
Deployment 擴容
擴容為10個:
$ kubectl scale deployment nginx-deployment --replicas 10
deployment "nginx-deployment" scaled
編寫 Deployment Spec
在所有的 Kubernetes 配置中,Deployment 也需要apiVersion,kind和metadata這些配置項。
Pod Template
.spec.template 是 .spec中唯一要求的字段。
另外為了划分Pod的范圍,Deployment中的pod template必須指定適當的label和適當的重啟策略。
Replicas
.spec.replicas 是可以選字段,指定期望的pod數量,默認是1。
Selector
.spec.selector是可選字段,用來指定 label selector ,圈定Deployment管理的pod范圍。
如果被指定, .spec.selector 必須匹配 .spec.template.metadata.labels,否則它將被API拒絕。如果 .spec.selector 沒有被指定, .spec.selector.matchLabels 默認是 .spec.template.metadata.labels。
策略
.spec.strategy 指定新的Pod替換舊的Pod的策略。 .spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是默認值。
Recreate Deployment
.spec.strategy.type==Recreate時,在創建出新的Pod之前會先殺掉所有已存在的Pod。
Rolling Update Deployment
.spec.strategy.type==RollingUpdate時,Deployment使用rolling update 的方式更新Pod 。您可以指定maxUnavailable 和 maxSurge 來控制 rolling update 進程。
MAX UNAVAILABLE
.spec.strategy.rollingUpdate.maxSurge 是可選配置項,用來指定可以超過期望的Pod數量的最大個數。該值可以是一個絕對值(例如5)或者是期望的Pod數量的百分比(例如10%)。當MaxUnavailable為0時該值不可以為0。通過百分比計算的絕對值向上取整。默認值是1。
Progress Deadline Seconds
.spec.progressDeadlineSeconds 是可選配置項,用來指定在系統報告Deployment的failed progressing——表現為resource的狀態中type=Progressing、Status=False、 Reason=ProgressDeadlineExceeded前可以等待的Deployment進行的秒數。
如果設置該參數,該值必須大於 .spec.minReadySeconds。
Min Ready Seconds
.spec.minReadySeconds是一個可選配置項,用來指定沒有任何容器crash的Pod並被認為是可用狀態的最小秒數。默認是0(Pod在ready后就會被認為是可用狀態)。
Rollback To
.spec.rollbackTo 是一個可以選配置項,用來配置Deployment回退的配置。設置該參數將觸發回退操作,每次回退完成后,該值就會被清除。
Revision
.spec.rollbackTo.revision是一個可選配置項,用來指定回退到的revision。默認是0,意味着回退到歷史中最老的revision。
Revision History Limit
Deployment revision history存儲在它控制的ReplicaSets中。
.spec.revisionHistoryLimit 是一個可選配置項,用來指定可以保留的舊的ReplicaSet數量。該理想值取決於心Deployment的頻率和穩定性。如果該值沒有設置的話,默認所有舊的Replicaset或會被保留,將資源存儲在etcd中,是用kubectl get rs查看輸出。
Paused
.spec.paused是可以可選配置項,boolean值。用來指定暫停和恢復Deployment。Paused和沒有paused的Deployment之間的唯一區別就是,所有對paused deployment中的PodTemplateSpec的修改都不會觸發新的rollout。Deployment被創建之后默認是非paused。