Deployment 簡介
deployment 是用來管理無狀態應用的,面向的集群的管理,而不是面向的是一個不可變的個體,舉例:有一群鴨子,要吃掉一個,只需要再放一個新的鴨仔就好了,不會影響什么,而有狀態的應用,就同時養三條狗一樣,而每個狗都是無法代替用新的事物代替的,因為有“感情”這個狀態在里面。
Deployment 為Pod 和 ReplicaSet 之上,提供了一個聲明式定義(declarative)方法,用來替代以前的ReplicationController 來方便的管理應用。
你只需要在 Deployment 中描述您想要的目標狀態是什么,Deployment controller 就會幫您將 Pod 和ReplicaSet 的實際狀態改變到您的目標狀態。您可以定義一個全新的 Deployment 來
創建 ReplicaSet 或者刪除已有的 Deployment 並創建一個新的來替換。也就是說Deployment是可以管理多個ReplicaSet的,如下圖:
典型的應用場景包括:
- 定義Deployment來創建Pod和ReplicaSet,使用Deployment來創建ReplicaSet。ReplicaSet在后台創建pod。檢查啟動狀態,看它是成功還是失敗。
- 然后,通過更新Deployment的PodTemplateSpec字段來聲明Pod的新狀態。這會創建一個新的ReplicaSet,Deployment會按照控制的速率將pod從舊的ReplicaSet移動到新d的ReplicaSet中。
- 如果當前狀態不穩定,回滾到之前的Deployment revision。每次回滾都會更新Deployment的revision。
- 擴容Deployment以滿足更高的負載。
- 暫停Deployment來應用PodTemplateSpec的多個修復,然后恢復上線。
- 根據Deployment 的狀態判斷上線是否hang住了。
- 清除舊的不必要的 ReplicaSet。
Deployment 升級
kubectl explain deploy.spec.strategy 策略訂是配置怎么滾動升級的,支持兩種策略:
- Recreate 重建式更新,就是刪一個建一個。
- rollingUpdate 滾動更新,簡單定義 更新期間pod最多有幾個等
rollingUpdate 有兩種策略
- maxSurge 指定超出副本數有幾個,兩種方式:1、指定數量 2、百分比
- maxUnavailable 最多有幾個不可用
Deployment 歷史版本
kubectl explain deploy.spec.revisionHistoryLimit
最多保存多少個歷史版本,默認是10個
Deployment 模板
kubectl explain deploy.spec.template
通過template 創建我們的目標狀態
類似pod的定義(包含 spec 、 metadata)
spec <Object> Specification of the desired behavior of the pod. More info: https:// git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status/ metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
案例:
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: dev template: metadata: labels: app: myapp release: dev spec: containers: - name: myapp-containers image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80
結果
看一下deploy 是否成功 $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE myapp-deploy 2 2 2 2 2m 因為deploy 是三層架構 現在會自動啟動一個replicasets 我們看一下是否啟動 $ kubectl get rs NAME DESIRED CURRENT READY AGE myapp-deploy-f4bcc4799 2 2 2 5m 我們看自動創建一個rs.名稱后面的字符串是 模板的哈希值。是不會發生變化的,最后pod的是隨機值 我們再看一下最后一層,最后一層為pod $ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-f4bcc4799-cs5xc 1/1 Running 0 7m myapp-deploy-f4bcc4799-k4tq5 1/1 Running 0 7m
滾動升級案例:
我們通過修改yaml的方式升級
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 5 selector: matchLabels: app: myapp release: dev template: metadata: labels: app: myapp release: dev spec: containers: - name: myapp-containers image: ikubernetes/myapp:v2 ports: - name: http containerPort: 80
升級過程(我們看到,是停止一台,升級一台的這種循環。)
kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-f4bcc4799-cs5xc 1/1 Running 0 23m myapp-deploy-f4bcc4799-cwzd9 1/1 Running 0 14m myapp-deploy-f4bcc4799-k4tq5 1/1 Running 0 23m myapp-deploy-f4bcc4799-shbmb 1/1 Running 0 14m myapp-deploy-f4bcc4799-vtk6m 1/1 Running 0 14m myapp-deploy-f4bcc4799-shbmb 1/1 Terminating 0 16m myapp-deploy-869b888f66-mv5c6 0/1 Pending 0 0s myapp-deploy-869b888f66-mv5c6 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 Pending 0 0s myapp-deploy-869b888f66-mv5c6 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-r57t5 0/1 Pending 0 0s myapp-deploy-869b888f66-r57t5 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-r57t5 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-r57t5 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-mv5c6 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vk9j6 0/1 ContainerCreating 0 2s myapp-deploy-f4bcc4799-shbmb 0/1 Terminating 0 16m myapp-deploy-f4bcc4799-shbmb 0/1 Terminating 0 16m myapp-deploy-869b888f66-r57t5 1/1 Running 0 4s myapp-deploy-f4bcc4799-vtk6m 1/1 Terminating 0 16m myapp-deploy-869b888f66-rxzbb 0/1 Pending 0 1s myapp-deploy-869b888f66-rxzbb 0/1 Pending 0 1s myapp-deploy-869b888f66-rxzbb 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vk9j6 1/1 Running 0 5s myapp-deploy-f4bcc4799-cwzd9 1/1 Terminating 0 16m myapp-deploy-869b888f66-vvwwv 0/1 Pending 0 0s myapp-deploy-869b888f66-vvwwv 0/1 Pending 0 0s .....
我們查看一下 rs的情況 以下可以看到原的rs作為備份,而現在是啟動新的rs
$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINER(S) IMAGE(S) SELECTOR myapp-deploy-869b888f66 5 5 5 3m myapp-containers ikubernetes/myapp:v2 app=myapp,pod-template-hash=4256444922,release=dev myapp-deploy-f4bcc4799 0 0 0 29m myapp-containers ikubernetes/myapp:v1 app=myapp,pod-template-hash=906770355,release=dev
修改滾動升級策略
$ kubectl patch deplop myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
$ kubectl describe deploy myapp-deploy
Name: myapp-deploy
Namespace: default
CreationTimestamp: Tue, 28 Aug 2018 09:52:03 -0400
Labels: app=myapp
release=dev
Annotations: deployment.kubernetes.io/revision=4
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"myapp-deploy","namespace":"default"},"spec":{"replicas":3,"selector":{...
Selector: app=myapp,release=dev
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 0 max unavailable, 1 max surge
Pod Template:
....
金絲雀發布
##通過 set image 發布新的鏡像 也可以通過yaml文件發布 myapp-containers 是containers 的名稱 $ kubectl set image deploy myapp-deploy myapp-containers=ikubernetes/myapp:v3 && kubectl rollout pause deploy myapp-deploy deployment "myapp-deploy" image updated deployment "myapp-deploy" paused #查看更新情況(新增加一個資源,但是沒執行。是因為pause暫停命令,所以發布一個,這樣形成了金絲雀發布,這個金絲雀就是讓真實用戶驗證的) $ kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-869b888f66-dpwvk 1/1 Running 0 24m myapp-deploy-869b888f66-frspv 1/1 Running 0 24m myapp-deploy-869b888f66-sgsll 1/1 Running 0 24m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 2s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 19s #那個金絲雀沒問題,可以發布后續的更新了 kubectl rollout resume deploy myapp-deploy #查看更新情況 kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-869b888f66-dpwvk 1/1 Running 0 24m myapp-deploy-869b888f66-frspv 1/1 Running 0 24m myapp-deploy-869b888f66-sgsll 1/1 Running 0 24m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 2s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 19s myapp-deploy-869b888f66-dpwvk 1/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Pending 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 Pending 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 ContainerCreating 0 2s myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-p6kzm 1/1 Running 0 18s myapp-deploy-869b888f66-frspv 1/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-q8mvs 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 ContainerCreating 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m
回滾
查看現在有幾個版本
kubectl rollout history deploy myapp-deploy deployments "myapp-deploy" REVISION CHANGE-CAUSE 0 <none> 3 <none> 4 <none> 5 <none>
回滾到第0版(默認回滾上一版,可以通過 --to-revision指定版本)
$ kubectl rollout undo deploy myapp-deploy --to-revision=0 deployment "myapp-deploy" rolled back #查看回滾情況 $ kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 6m myapp-deploy-7cbd5b69b9-p6kzm 1/1 Running 0 1m myapp-deploy-7cbd5b69b9-q8mvs 1/1 Running 0 54s ^[[Amyapp-deploy-869b888f66-7shh9 0/1 Pending 0 0s myapp-deploy-869b888f66-7shh9 0/1 Pending 0 0s myapp-deploy-869b888f66-7shh9 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-7shh9 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-7shh9 1/1 Running 0 3s myapp-deploy-7cbd5b69b9-q8mvs 1/1 Terminating 0 5m myapp-deploy-869b888f66-4l4cv 0/1 Pending 0 0s myapp-deploy-869b888f66-4l4cv 0/1 Pending 0 0s myapp-deploy-869b888f66-4l4cv 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-4l4cv 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-869b888f66-4l4cv 1/1 Running 0 2s myapp-deploy-7cbd5b69b9-p6kzm 1/1 Terminating 0 6m myapp-deploy-869b888f66-vwgj2 0/1 Pending 0 0s myapp-deploy-869b888f66-vwgj2 0/1 Pending 0 0s myapp-deploy-869b888f66-vwgj2 0/1 ContainerCreating 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-869b888f66-vwgj2 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vwgj2 1/1 Running 0 3s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m $ kubectl get rs -l app=myapp -o wide NAME DESIRED CURRENT READY AGE CONTAINER(S) IMAGE(S) SELECTOR myapp-deploy-7cbd5b69b9 0 0 0 14m myapp-containers ikubernetes/myapp:v3 app=myapp,pod-template-hash=3768162565,release=dev myapp-deploy-869b888f66 3 3 3 1h myapp-containers ikubernetes/myapp:v2 app=myapp,pod-template-hash=4256444922,release=dev myapp-deploy-f4bcc4799 0 0 0 1h myapp-containers ikubernetes/myapp:v1 app=myapp,pod-template-hash=906770355,release=dev
kubectl patch 打補丁的方式更新
格式案例(通過json格式)
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
更新一個images
kubectl patch deploy myapp-deploy -p '{"spec":{"template":{"spec":{"containers":[{"name":"myapp-containers","image":"ikubernetes/myapp:v1"}]}}}}'