kubernetes之Deployment

2022-07-26 21:00:21

1.什麼是Deployment?

Deployment(簡寫為deploy)是kubernetes控制器的又一種實現,構建於ReplicasSet控制器之上,可以為Pod和ReplicaSet提供宣告式更新。相比較而言,Pod和ReplicaSet很少用來直接使用,而是藉助於控制器來使用。Deployment Controller核心功能也是保證Pod資源的正常使用,大部分功能呼叫ReplicaSet來實現。

1.2我們只需要描述Deployment中目標Pod期望狀態,而Deployment控制器以控制更改為實際狀態,使其變成期望狀態。我們不需要直接使用Pod和ReplicaSet來實現,Deployment控制器在ReplicaSet的基礎上增加了部分特性:

1.事件和狀態檢視: 可以通過特定的命令檢視Deployment物件的更新進度和狀態;
2.版本記錄: 將Deployment物件的歷史更新操作都進行儲存,以便於後續執行回滾操作使用;
3.多種更新方案: Recreate重建,可以實現單批次更新所有的Pod。RollingUpdate可以實現多批次替換Pod至新版本。

2.Deployment的構成部分

Deployment是標準的k8s資源,Deployment構建於ReplicaSet之上,spec欄位巢狀了包含了replicaset控制器支援的selector、replicas、template、minReadySeconds
2.1Selector: 標籤選擇器,匹配並關聯Pod,並對其受控制的Pod進行管理;
2.2Replicas: 期望的Pod的副本數,期望在叢集所執行的Pod物件的數量;
2.3template: Pod的模板;實際上定義了Pod的內容,相當於把一個Pod的描述資訊以模板的方式巢狀在ReplicaSet;

3.Deployment的資源規範

apiVersion: apps/v1   # API群組及版本;
kind: Deployment      # 資源型別;
metadata:             # Pod後設資料;
   name:              # 資源名稱,在作用域中要唯一;
   namespace: <string>         # 名稱空間,Deployment隸屬名稱空間級別;
spec:             
  minReadySeconds: <integer>   # Pod就緒後多少秒內任一容器無Crash方可為就緒;
  replicas: <integer>          # 期望的Pod副本數,預設為1;
  selector: <Object>           # 標籤選擇器,必須匹配template欄位中Pod模板中的標籤;
  template: <Object>           # Pod模板物件;
  
  revisionHistoryLimit: <integer>  # 捲動更新歷史記錄數量,預設為10;
  strategy: <Object>               # 捲動更新策略;
    type: <string>                 # 捲動更新型別,可用值有Recreate和Rollingupdate;
    rollingUpdaate: <Object>       # 捲動更新引數,專用於RollingUpdate型別;
      maxSurge: <string>           # 更新起見可比期望的Pod數量多出的數量和比例;
      maxUnavailable: <string>     # 更新期間可比期望的Pod數量缺少的數量或比例;
   progressDeadlineSeconds: <integer>  # 捲動更新故障超時時長,預設為600;
   paused: <boolean>                   # 是否暫停部署過程;

4.Deployment的設定範例:

# 以Nginx應用為範例設定
root@kubernetes-master01:~# cat nginx-deployment-test.yaml 
apiVersion: apps/v1     # 資源群組
kind: Deployment        # 資源型別
metadata:               # 後設資料
  name: deployment-nginx-test  # Pod名稱
  namespace: default           # Pod所在的名稱空間
spec:
  replicas: 2                  # Pod的副本數
  selector:                    # 標籤選擇器
    matchLabels:
      app: nginx-deployment     # Pod的標籤

  template:                      # 定義Pod的模板
    metadata:                    # 
      labels:                    # 標籤同上要一致
        app: nginx-deployment
    spec:                         # 定義容器的
      containers:                 
      - name: nginx                # 容器名稱
        image: nginx               # 容器映象
        imagePullPolicy: IfNotPresent # 容器拉取策略
        ports:                     # 定義容器的埠
        - name: http         
          containerPort: 80          # 容器埠為80

# 
root@kubernetes-master01:~# kubectl apply -f nginx-deployment-test.yaml
deployment.apps/deployment-nginx-test created

4.1檢視Pod,Deployment的名稱-Replicaset的名稱-隨機字串hash值是由Deployment Controller自動生成。Pod對應的名稱遵循ReplicaSet控制器的命名格式,它以Replicaset控制器的名稱為簽註,後跟5位隨機字元。

root@kubernetes-master01:~/cloud-Native/deployment/replicas# kubectl get pods 
NAME                                    READY   STATUS    RESTARTS   AGE
deployment-nginx-test-dd5bdc67f-b5dlz   1/1     Running   0          6m12s
deployment-nginx-test-dd5bdc67f-t94j7   1/1     Running   0          6m12s
# NAME: 列出了叢集中Deployment的名稱。
# READY: 顯示應用程式的可用的"副本數"顯示的模式是"就緒個數/期望個數"
# UP-TO-DATE: 標識已經達到期望狀態的Pod的副本數量。
# AVAILABLE: 表示當前處於可用狀態的Pod的數量。

4.2檢視replicaset,Deployment控制器會自動建立相關的ReplicaSet控制器資源,並以[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]格式為其命名,其中的hash值由Deployment控制器自動生成,由Deployment建立的ReplicaSet物件會自動使用相同的標籤選擇器。

root@kubernetes-master01:~# kubectl get replicaset deployment-nginx-test-dd5bdc67f 
NAME                              DESIRED   CURRENT   READY   AGE
deployment-nginx-test-dd5bdc67f   2         2         2       9m34s

5.為Pod建立Service資源以實現負載均衡。

root@kubernetes-master01:~# cat  nginx-service-test.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-deployment-test
  namespace: default
spec:
  type: ClusterIP  # 型別為ClusterIP
  selector:    # 標籤選擇器跟Pod的標籤相匹配,才能被識別為後端端點。
    app: nginx-deployment
  ports:
  - name: http
    protocol: TCP
    port: 80  
    targetPort: 80
# 
root@kubernetes-master01:~# kubectl apply -f nginx-service-test.yaml 
service/nginx-deployment-test created

6.進行存取測試

6.1我提前修改了Nginx的index檔案。方便效果。

root@kubernetes-master01:~# echo "nginx-1-haitang.net" > /usr/share/nginx/html/index.html 
root@kubernetes-master01:~# echo "nginx2-haitang.com" > /usr/share/nginx/html/index.html 

6.2存取Service的IP,因為是ClusterIP,只能在叢集記憶體取。也是沒有問題的。

root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net
root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net

7.Pod的伸縮

7.1比如現在兩個副本有點無法應對突發的流量,可以通過命令的方式修改replicas也可以通過修改組態檔的方式去修改。

1.1# 命令方式來伸縮
root@kubernetes-master01:~# kubectl scale deployment deployment-nginx-test --replicas=3
deployment.apps/deployment-nginx-test scaled

1.2# 縮容的話就是=多少副本數即可。 例如=2
root@kubernetes-master01:~# kubectl scale deployment deployment-nginx-test --replicas=2

1.3# 修改組態檔vim nginx-deployment-test.yaml 修改spec欄位的replicas即可。

7.2伸縮完成後,Service就會發現帶有同樣標籤的Pod,Pod就緒後加入到後端的可用端點。
再次存取測試。也是沒有問題。

root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net

7.3也可以通過describe命令來檢視Events事件。

root@kubernetes-master01:~# kubectl describe deploy deployment-nginx-test  
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   deployment-nginx-test-dd5bdc67f (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  36s   deployment-controller  Scaled up replica set deployment-nginx-test-dd5bdc67f to 3

8.故障測試。

8.1現在刪除Pod會發生什麼?

root@kubernetes-master01:~# kubectl delete pods deployment-nginx-test-dd5bdc67f-2vggw  
pod "deployment-nginx-test-dd5bdc67f-2vggw" deleted

# 有控制器管理的Pod刪除會自動重建,沒有控制器管理的Pod刪除就是刪除了不可能會自動重建。我們建立的Pod受控於Deployment Controller。所以能重建。
root@kubernetes-master01:~# kubectl get pods
deployment-nginx-test-dd5bdc67f-2vggw   1/1     Running   0          4s
deployment-nginx-test-dd5bdc67f-lc6nm   1/1     Running   0          4s