k8s學習 - 概念 - Deployment
有了 ReplicaSet 還需要有 Deployment 的原因是希望有一個控制器能管理部署更新時候的版本控制問題。一個 Deployment 可以管理多個 ReplicaSet, 一個 ReplicaSet 可以管理多個 Pod。最通用的場景是當我們對某個 Pod 裡面的映象進行升級的時候,我們非常迫切需要有一個版本號概念,並且在發現問題的時候可以隨時回滾。那麼這個就是 Deployment 的使命。
使用
官方和很多文章都是使用 nginx 來做示例的。我們也不能免俗。我們來看一下最簡易的配置檔案:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.11.5
ports:
- containerPort: 80
很簡單吧,template 開始以下是 Pod 的內容,裡面有個 name=nginx 的容器,使用映象 nginx:1.11.5。 sepc.replicas 說明了這個 Deployment 管理了多少個 Pod。
如圖,對應的 deployment:replicaset:pod = 1:1:3
下面我們要升級 pod 裡面的 nginx container,使用映象 nginx:1.10.1
kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record
這裡的 record 表示這次升級記錄下命令,否則我們檢視這次升級的版本,就是 NONE
kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
2 kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record=true
如果我們發現1.10.1映象是有問題,我們可以進行回滾
kubectl rollout undo deployment nginx-deployment
kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
2 kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record=true
3 <none>
我們可以看到這裡就有了3個版本,第三個版本就是我們回滾的版本,由於我們沒有增加 --record,在CHANGE-CAUSE 就出現了NONE。
yaml 配置全解析
上述就是 Deployment 的基本用法。慣例,我們還是有必要全部解析一遍 Deployment 的配置。
kubectl get deployment nginx-deployment -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "3"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"replicas":3,"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.11.5","name":"nginx","ports":[{"containerPort":80}]}]}}}}
creationTimestamp: 2019-07-15T00:52:16Z
generation: 4
labels:
app: nginx
name: nginx-deployment
namespace: default
resourceVersion: "1638554"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
uid: cad03233-a69a-11e9-ac73-025000000001
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.11.5
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 3
conditions:
- lastTransitionTime: 2019-07-15T00:52:18Z
lastUpdateTime: 2019-07-15T00:52:18Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: 2019-07-15T00:52:16Z
lastUpdateTime: 2019-07-15T01:01:26Z
message: ReplicaSet "nginx-deployment-dd74f8bcd" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 4
readyReplicas: 3
replicas: 3
updatedReplicas: 3
把 template (Pod 內容),自身介紹性的欄位去掉:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
...
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
...
status:
...
spec.strategy
定義升級策略,Deployment 的升級有兩種策略,一種是 RollingUpdate,滾動升級。顧名思義,就是一個一個 pod 進行升級,而不是同時停止整個服務。這個升級能保證整個升級過程中服務的可用性。另外一種就是 Recreate,先將舊 Pod 下線,再啟動新 Pod。 預設是使用 RollingUpdate。
所以 sepc.strategy.rollingUpdate 就是滾動升級的一些詳細策略:
- maxSurge: 在升級過程中,最多可以建立多少個 Pod。也就是說每次滾動的步長。該值不能為0。
- maxUnavailable: 在升級過程中,最多不可用的 pod 的數量。該值不能為0。
spec.progressDeadlineSeconds
k8s 在升級過程中有可能由於各種原因升級卡住(這個時候還沒有明確的升級失敗),比如在拉取被牆的映象,許可權不夠等錯誤。那麼這個時候就需要有個 deadline ,在 deadline 之內如果還卡著,那麼就上報這個情況,這個時候這個 Deployment 狀態就被標記為 False,並且註明原因。但是它並不會阻止 Deployment 繼續進行卡住後面的操作。完全由使用者進行控制。
這個配置就是設定 deadline 的。單位為秒。
spec.revisionHistoryLimit
我們做的回滾操作並不是沒有代價的,代價就是舊版本的 ReplicaSet 會被保留,但是不會繼續提供服務了。當我們執行回滾操作的時候,就直接使用舊版本的 ReplicaSet。
這個配置就是控制保留多少個版本的 ReplicaSet。
參考
https://tachingchen.com/tw/blog/kubernetes-rolling-update-with-deployment/
https://www.cnblogs.com/breezey/p/8810094.html