Kubernetes - Deployment 學習紀錄

Posted by Kubeguts on 2021-05-22

Deployment核心概念

Deployment主要管理Pod的生命週期,
根據ReplicaSet來確認Pod數量要如何管理

先了解ReplicaSet是什麼

ReplicaSet的特色

  • 為Self-Healing的機制
  • 確保指定數量的Pod在運作
  • 提供Fault-Tolerance
  • 可用來擴展Pods

ReplicaSet結果

若事先在ReplicaSet內定義DESIRED=2,Deployment會根據該數值,產生2個pod

pic02

ReplicaSet使用注意事項

在Deployment中設置.selector.matchLabels,建立後不要去改動之,不然會導致Deployment找不到原本指定的ReplicaSet

反而是直接建立新的ReplicaSet,導致舊的ReplicaSet還在運作

pic09

Deployement主要負責管理Pods

  • 根據ReplicaSets來管理Pods
  • 擴展ReplicaSets
  • 支援Zero-Downtime的更新、創建、以及刪除ReplicaSets
  • 提供Rollback的功能
  • 可建立出獨特的label,並分配給ReplicaSet,和生成Pods

定義Deployment

以一組定義nginx的deployment範例做說明

nginx-deployment.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: apps/v1
kind: Deployment # 類型為Deployment
# 說明這個deployment的資訊
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
replicas: 2 # 要複製Pod的數量
# selector 選擇指定的template來創建pod,以label做篩選
selector:
# 符合label的pod template會被用來deploy
matchLabels:
# 若pod template的label符合app: my-nginx
# 就以此做deployment
app: my-nginx
# pod的template,提供給deployment預備部署用
template:
# 以下就跟pod的yaml格式類似
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:alpine
ports:
- containerPort: 80
resources:
limits:
memory: "128Mi" #128 MB
cpu: "200m" #200 millicpu (.2 cpu or 20% of the cpu)

在template中,有定義spec內的container資訊,其中最重要的resources關鍵字是用來限制一組pod所能夠用的最高資源為多少,避免同一個Node的其他Pods的資源被吃光光

1
2
3
4
resources:
limits:
memory: "128Mi" #128 MB
cpu: "200m" #200 millicpu (.2 cpu or 20% of the cpu)

使用kubectl創建Deloyment

kubectl create -f [yaml file]

以yaml檔案為基底,創建deployment

  • --save-config:之後若要更新deployment

範例 nginx-deployment.yml
pic04

以及可用kubectl describe deployment檢查目前建制的資訊,紅色匡起來區域為該Pod的資源限制
pic05

kubectl apply -f [yaml file]

套用yaml檔案,並做更新

kubectl get deployment

取得deployment資訊

  • --show-labels,列出所有deployemnt內所定義的labels

  • -l 取得所有用-l指定labels的deployments

    • ex: kubectl get deployment -l app=nginx

pic06

kubectl delete

刪除deployment

1
k delete deployment.apps/my-nginx

kubectl scale deployment [deployment-name] --replicas=[n]

將deployment內的pod擴展至n個

1
2
3
4
spec:
replicas: n
selector:
tier: frontend

也可以用kubectl scale -f [yaml-file] --replicas=n來更新relicas數量

pic07

升級策略

若要透過Deployment來升級Pod的版本,可以透過strategy類型來達成

先看yaml檔案結構,spec.stratey.type可以定義升級策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-io
labels:
app: k8s-io
version: v1
spec:
replicas: 2
selector:
matchLabels:
app: k8s-io
version: v1
strategy:
type: RollingUpdate # 這邊可以定義Rollout策略
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 5

spec.stratey.type可以定義兩種策略

  1. RollingUpdate: 滾動升級,先創建新的,再把舊的砍掉
  2. Recreate: 終止全部舊的Pod,再創建新的Pod

接著再說明細部設定

  • spec.minReadySeconds: 容器啟動時間,預設0秒
  • spec.strategy.maxSurge: 舊與新的Pod同時存在的最大數目為 replicaSet設置的數目 + maxSurge
  • spec.stretegy.maxUnavailable: 最多幾個舊的Pod處在終止狀態

了解設定後,就可以使用kubectl apply ...來更新Deployment的Rolling策略,會紀錄revision

以下範例添加 --record,可以將這次更動的指令紀錄起來,可透過rollout historyCHANGE-CAUSE查看操作指令的歷史紀錄

1
$ kubectl apply -f nginx.yaml --record
1
2
3
4
5
$ kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment

REVISION CHANGE-CAUSE
1 kubectl apply --filename=nginx.yaml --record=true

以下可以針對各種revision的所有操作說明

列出所有 revision

1
kubectl rollout history deployment [deployment name]

查看特定 revision 詳細資訊

1
kubectl rollout history deployment [deployment name] --revision=<revision>

回退上個 revision

1
kubectl rollout undo deployment [deployment name]

回退特定 revision

1
kubectl rollout undo deployment [deployment name] --to-revision=<revision>

暫停 rollout 更新

1
kubectl rollout pause deployment [deployment name]

繼續 rollout 更新

1
kubectl rollout resume deployment [deployment name]

查看rollout 狀況

1
kubectl rollout status deployment [deployment name]

Case Study: 使用Deployment的優點: Zero Downtime Depoloyment

如果要更新一個正在運行的pod,我們是希望在更新過程中,不要有停機(Downtime)的時候,這時候Deployment可以讓我們有零停機的效用,對把更新後版本部署到Production環境是挺有幫助的。

詳情可看 使用K8S實現Zero-downtime服務更新/移轉的策略一節

參考