1.deployment介紹
為了更好地解決服務編排的問題,k8s在V1.2版本開始,引入了deployment控制器,值得一提的是,這種控制器並不直接管理pod,
而是通過管理replicaset來間接管理pod,即:deployment管理replicaset,replicaset管理pod。所以deployment比replicaset的功能更強大。
deployment的主要功能有下面幾個:
- 支持replicaset的所有功能
- 支持版本的滾動更新和版本回退
- 支持發布的停止、繼續
deployment的資源清單文件
apiVersion: apps/v1 #版本號 kind: Deployment #類型 metadata: #元數據 name: #rs名稱 namespace: #所屬命名空間 labels: #標簽 controller: deploy spec: #詳情描述 replicas: #副本數量 revisionHistoryLimit: #保留歷史版本,默認是10 paused: #暫停部署,默認是false progressDeadlineSeconds: #部署超時時間(s),默認是600 strategy: #策略 type: RollingUpdates #滾動更新策略 rollingUpdate: #滾動更新 maxSurge: #最大額外可以存在的副本數,可以為百分比,也可以為整數 maxUnavaliable: #最大不可用狀態的pod的最大值,可以為百分比,也可以為整數 selector: #選擇器,通過它指定該控制器管理哪些pod matchLabels: #Labels匹配規則 app: nginx-pod matchExpressions: #Expression匹配規則 - {key: app, operator: In, values: [nginx-pod]} template: #模板,當副本數量不足時,會根據下面的模板創建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80
2.deployment創建
1)nginx-deployment.yaml,內容如下:
[root@k8s-master yaml]# cat nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: default spec: replicas: 3 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1
2)執行創建
[root@k8s-master yaml]# kubectl apply -f nginx-deployment.yaml [root@k8s-master yaml]# kubectl get deploy,rs,po -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/nginx-deployment 3/3 3 3 41s nginx nginx:1.17.1 app=nginx-pod NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/nginx-deployment-5d9c9b97bb 3 3 3 41s nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d9c9b97bb NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-deployment-5d9c9b97bb-4p2hx 1/1 Running 0 41s 10.244.36.82 k8s-node1 <none> <none> pod/nginx-deployment-5d9c9b97bb-p58lf 1/1 Running 0 41s 10.244.169.133 k8s-node2 <none> <none> pod/nginx-deployment-5d9c9b97bb-sm9zz 1/1 Running 0 41s 10.244.36.83 k8s-node1 <none> <none>
注:查看deployment控制的rs和pod,發現rs是在deployment之后加了一段字符串,而pod是在rs之后加了一段字符串
即:deployment管理replicaset,replicaset管理pod。所以deployment比replicaset的功能更強大
3.deployment擴縮容
Deployment擴容縮容的本質其實就是改變ReplicaSet的數量來控制Pod的數量,增加就是擴容,縮小就是縮容。
- 方式一:kubectl scale deploy deploy名稱 --replicas=pod數量 -n 命名空間
- 方式二:kubectl edit deploy deploy名字 -n 命名空間
注:以上兩種方式均可以實現擴縮容,根據實際情況選擇即可
1)擴容示例:假設我們要將nginx從3個pod擴展到5個pod
[root@k8s-master yaml]# kubectl scale deploy nginx-deployment --replicas=5 -n default deployment.apps/nginx-deployment scaled [root@k8s-master yaml]# kubectl get deploy,rs,po NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 5/5 5 5 19m NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5d9c9b97bb 5 5 5 19m NAME READY STATUS RESTARTS AGE pod/nginx-deployment-5d9c9b97bb-4p2hx 1/1 Running 0 19m pod/nginx-deployment-5d9c9b97bb-bjnbs 1/1 Running 0 29s pod/nginx-deployment-5d9c9b97bb-p58lf 1/1 Running 0 19m pod/nginx-deployment-5d9c9b97bb-sm9zz 1/1 Running 0 19m pod/nginx-deployment-5d9c9b97bb-x92nj 1/1 Running 0 29s
[root@k8s-master yaml]# kubectl edit deploy nginx-deployment -n default deployment.apps/nginx-deployment edited #找到replicas,將其數量改為3 spec: progressDeadlineSeconds: 600 replicas: 3 [root@k8s-master yaml]# kubectl get deploy,rs,po NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 3/3 3 3 29m NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5d9c9b97bb 3 3 3 29m NAME READY STATUS RESTARTS AGE pod/nginx-deployment-5d9c9b97bb-4p2hx 1/1 Running 0 29m pod/nginx-deployment-5d9c9b97bb-bjnbs 1/1 Running 0 9m47s pod/nginx-deployment-5d9c9b97bb-p58lf 1/1 Running 0 29m
4.deployment更新和回滾
deployment支持兩種鏡像更新策略:重建更新和滾動更新(默認),可以通過strategy選項進行配置
strategy:指定新的pod替換舊的pod的策略,支持兩個屬性: type:指定策略類型,支持兩種策略 Recreate:在創建出新的pod之前會先殺掉所有已存在的pod RollingUpdate:滾動更新,就是殺死一部分,就啟動一部分,在更新過程中,存在兩個版本pod rollingUpdate:當type為RollingUpdate時生效,用於為RollingUpdate設置參數,支持兩個屬性 maxUnavailable:用來指定在升級過程中不可用pod的最大數量,默認為25% maxSurge:用來指定在升級過程中可以超過期望的pod的最大數量,默認為25%
1)重建更新
編輯pc-deployment.yaml,在spec節點下添加更新策略
spec:
strategy: #策略
type: Recreate #重建更新策略
創建deploy進行驗證
#首先記錄原本的pod名 [root@k8s-master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-5d9c9b97bb-4p2hx 1/1 Running 0 40m nginx-deployment-5d9c9b97bb-bjnbs 1/1 Running 0 21m nginx-deployment-5d9c9b97bb-p58lf 1/1 Running 0 40m #更改pod鏡像 [root@k8s-master yaml]# kubectl set image deploy nginx-deployment nginx=nginx:1.17.2 deployment.apps/nginx-deployment image updated #再次查看鏡像(先是中斷rs控制器,再是拉取nginx新鏡像,最后根據新鏡像創建pod) [root@k8s-master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-5d9c9b97bb-4p2hx 0/1 Terminating 0 42m [root@k8s-master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-7c7477c7ff-5xmxl 0/1 ContainerCreating 0 0s nginx-deployment-7c7477c7ff-xjdcg 0/1 ContainerCreating 0 0s nginx-deployment-7c7477c7ff-xtxh7 0/1 ContainerCreating 0 0s [root@k8s-master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-7c7477c7ff-5xmxl 1/1 Running 0 63s nginx-deployment-7c7477c7ff-xjdcg 1/1 Running 0 63s nginx-deployment-7c7477c7ff-xtxh7 1/1 Running 0 63s
注:Recreate 的升級策略就是完全刪除再重建,這樣會導致服務一段時間不可用
2)滾動更新
編輯pc-deployment.yaml,在spec節點下添加滾動更新策略(也可以把strategy去掉,因為默認滾動更新策略)
strategy: type: RollingUpdate #滾動更新策略 rollingUpdate: maxUnavailable: 25% #用來指定在升級過程中不可用pod的最大數量,默認為25% maxSurge: 25% #用來指定在升級過程中可以超過期望的pod的最大數量,默認為25%
創建deploy進行驗證
滾動更新前(nginx為1.17.2) [root@k8s-master yaml]# kubectl get deploy,rs,pod -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/nginx-deployment 3/3 3 3 6m4s nginx nginx:1.17.2 app=nginx-pod NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 6m4s nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d9c9b97bb replicaset.apps/nginx-deployment-7c7477c7ff 3 3 3 87s nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=7c7477c7ff NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-deployment-7c7477c7ff-769lc 1/1 Running 0 84s 10.244.36.94 k8s-node1 <none> <none> pod/nginx-deployment-7c7477c7ff-9jvdj 1/1 Running 0 87s 10.244.36.93 k8s-node1 <none> <none> pod/nginx-deployment-7c7477c7ff-m9b2r 1/1 Running 0 85s 10.244.169.139 k8s-node2 <none> <none> 更新鏡像 [root@k8s-master yaml]# kubectl set image deploy nginx-deployment nginx=nginx:1.17.3 deployment.apps/nginx-deployment image updated [root@k8s-master yaml]# kubectl get deploy,rs,pod -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/nginx-deployment 3/3 3 3 8m43s nginx nginx:1.17.3 app=nginx-pod NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 8m43s nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d9c9b97bb replicaset.apps/nginx-deployment-76fd8c7f84 3 3 2 3s nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=76fd8c7f84 replicaset.apps/nginx-deployment-7c7477c7ff 1 1 1 4m6s nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=7c7477c7ff NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-deployment-76fd8c7f84-2ttfm 1/1 Running 0 2s 10.244.169.140 k8s-node2 <none> <none> pod/nginx-deployment-76fd8c7f84-4g5wq 0/1 ContainerCreating 0 1s <none> k8s-node1 <none> <none> pod/nginx-deployment-76fd8c7f84-694sl 1/1 Running 0 3s 10.244.36.95 k8s-node1 <none> <none> pod/nginx-deployment-7c7477c7ff-769lc 0/1 Terminating 0 4m3s 10.244.36.94 k8s-node1 <none> <none> pod/nginx-deployment-7c7477c7ff-9jvdj 1/1 Running 0 4m6s 10.244.36.93 k8s-node1 <none> <none> pod/nginx-deployment-7c7477c7ff-m9b2r 1/1 Terminating 0 4m4s 10.244.169.139 k8s-node2 <none> <none> 查看更新后鏡像版本(nginx為1.17.3) [root@k8s-master yaml]# kubectl get deploy,rs,pod -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/nginx-deployment 3/3 3 3 10m nginx nginx:1.17.3 app=nginx-pod NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 10m nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d9c9b97bb replicaset.apps/nginx-deployment-76fd8c7f84 3 3 3 118s nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=76fd8c7f84 replicaset.apps/nginx-deployment-7c7477c7ff 0 0 0 6m1s nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=7c7477c7ff NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-deployment-76fd8c7f84-2ttfm 1/1 Running 0 117s 10.244.169.140 k8s-node2 <none> <none> pod/nginx-deployment-76fd8c7f84-4g5wq 1/1 Running 0 116s 10.244.36.96 k8s-node1 <none> <none> pod/nginx-deployment-76fd8c7f84-694sl 1/1 Running 0 118s 10.244.36.95 k8s-node1 <none> <none>
3)滾動更新的過程
5.deployment回滾
deployment支持版本升級過程中的暫停,繼續功能以及版本回退等諸多功能,下面具體來看
kubectl rollout:版本升級相關功能,支持下面的選項:
- status:顯示當前升級狀態
- history:顯示升級歷史記錄
- pause:暫停版本升級過程
- resume:繼續已經暫停的版本升級過程
- restart:重啟版本升級過程
- undo:回滾到上一級版本(可以使用--to-revision回滾到指定版本)
#當前nginx版本 [root@k8s-master yaml]# kubectl get deploy -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx-deployment 3/3 3 3 24m nginx nginx:1.17.3 app=nginx-pod #查看升級狀態 [root@k8s-master yaml]# kubectl rollout status deploy nginx-deployment deployment "nginx-deployment" successfully rolled out #查看升級歷史 [root@k8s-master yaml]# kubectl rollout history deploy nginx-deployment deployment.apps/nginx-deployment REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> #查看版本詳情 [root@k8s-master yaml]# kubectl rollout history deployment nginx-deployment --revision=2 deployment.apps/nginx-deployment with revision #2 Pod Template: Labels: app=nginx-pod pod-template-hash=7c7477c7ff Containers: nginx: Image: nginx:1.17.2 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> #版本回滾這里使用--to-revision=2回滾到2版本,如果省略這個選項,則會回退到上個版本 [root@k8s-master yaml]# kubectl rollout undo deployment nginx-deployment --to-revision=2 deployment.apps/nginx-deployment rolled back #查看當前版本(nginx為1.17.2)說明回退成功 [root@k8s-master yaml]# kubectl get deployments -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx-deployment 3/3 3 3 27m nginx nginx:1.17.2 app=nginx-pod
6.金絲雀發布(灰度發布)
deployment支持更新過程中的控制,如"暫停(pause)"或"繼續(resume)"更新操作,觀察新服務實際運行狀況再決定操作
金絲雀發布(可以理解為灰度發布):比如有一批新的pod資源創建完成后立即暫停更新過程,此時,僅存在一部分新版本的應用,主體部分還是舊的版本。然后,再篩選一小部分的用戶請求路由到新的pod應用,繼續觀察能否穩定地按期望的方式運行。確定沒問題之后再繼續完成余下的pod資源滾動更新,否則立即回滾更新操作。這就是所謂的金絲雀發布。
#更新deployment版本,並配置暫停deployment [root@k8s-master yaml]# kubectl set image deploy nginx-deployment nginx=nginx:1.17.3 && kubectl rollout pause deploy nginx-deployment deployment.apps/nginx-deployment image updated deployment.apps/nginx-deployment paused #查看rs,發現老版本rs沒有減少,新版本rs增加一個,狀態為更新中.... [root@k8s-master yaml]# kubectl get rs,deploy NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 39m replicaset.apps/nginx-deployment-76fd8c7f84 1 1 1 30m replicaset.apps/nginx-deployment-7c7477c7ff 3 3 3 34m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 4/3 1 4 39m [root@k8s-master yaml]# kubectl rollout status deployment nginx-deployment Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated... #繼續deploy的更新 [root@k8s-master yaml]# kubectl rollout resume deployment nginx-deployment deployment.apps/nginx-deployment resumed [root@k8s-master yaml]# kubectl rollout status deployment nginx-deployment Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination... deployment "nginx-deployment" successfully rolled out #查看rs更新結果,發現老版本均停止,新版本已經創建好 [root@k8s-master yaml]# kubectl get rs,deploy NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 41m replicaset.apps/nginx-deployment-76fd8c7f84 3 3 3 32m replicaset.apps/nginx-deployment-7c7477c7ff 0 0 0 36m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 3/3 3 3 41m