Kubernetes 五種資源控制器詳細介紹以及功能演示(轉)

 

 

一、控制器說明

Pod 的分類:

  • 自主式 Pod:該類型的 Pod 無論是異常退出還是正常退出都不會被創建,也就是說沒有對應的管理者。
  • 控制器管理的 Pod:該類型 Pod 在控制器的生命週期裏,控制器始終要維持 Pod 的副本數,日常中基本都是使用該類型 Pod ,因爲自主式 Pod 不能保證穩定性等之類的問題。
 
 
 
 
 
 
五種控制器類型
Deployment
DaemonSet
StatefulSet
Job
CronJob

Deployment 介紹

Deployment 是爲 Pod 和 ReplicaSet 提供了一個 聲明式定義方法,也就是你只要負責描述 Deployment 中的目標狀態,而 Deployment 控制器會去對 ReplicaSet 進行操作使其變成期望的狀態。
Deployment 是用來取代以前的 ReplicationController 達到更方便的管理應用。

典型的應用場景如下:

  • 定義 Deployment 來創建 ReplicaSet 和 Pod

  • 滾動升級和回滾應用

  • 擴容和縮容

  • 暫停和繼續 Deployment

Deployment 創建 RS 流程圖如下:

image-20210607150923413

這裏針對上面第一點強調一下,Deployment 不是直接管理或者創建 Pod,而是通過創建 ReplicaSet 來創建和管理 Pod。

創建 Deployment 時名稱爲 nginx-Deploy,RS 也會被創建出來,名稱爲 nginx-Deploy-xxx,xxx爲隨機碼。

DaemonSet 介紹

DaemonSet 確保全部(或者一些)節點上運行 一個 Pod 的副本。 當有節點加入集羣時, 也會爲他們 新增一個 Pod 。 當有節點從集羣移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的 所有 Pod

上述簡介摘自官方

如果需要多個 Pod 運行在每個 Node 上的話,可以定義多個 DaemonSet 的方案來實現。

DaemonSet 典型應用場景:

  • 運行集羣存儲,例如在每個 Node 上運行 glusterdceph

  • 每個 Node 上運行日誌收集,例如fluentdlogstash

  • 每個 Node 上運行監控程序,例如Prometheus Node Exportercollectd

StatefulSet 介紹

StatefulSet 是用來管理 有狀態服務,爲了解決有狀態服務的問題,而 Deployment 和 ReplicaSet 更適用於無狀態服務的部署。

StatefulSet 爲每個 Pod 維護了一個有粘性的 ID,無論怎麼調度,每個 Pod 都有一個永久不變的 ID。

StatefulSet 應用場景:

  • 穩定的、唯一的網絡標識符。
  • 穩定的、持久的存儲。
  • 有序的、優雅的部署和縮放。
  • 有序的、自動的滾動更新。

Job 介紹

Job 負載批處理任務,僅執行一次的任務,它能夠保證批處理任務的一個或者多個 Pod 成功執行結束。

可以設置 Job 執行成功的數值,Job 跟蹤記錄成功完成的 Pod 個數,當數量達到指定的成功個數閾值時,任務結束。

我們不需要擔心程序是否執行成功,如果 Jod 沒有以0代碼成功退出的話,它會重新執行這個程序。

CronJob 介紹

CronJob 就像 Linux 的 crontab。 它用 Cron 格式進行編寫, 在給定時間點只運行一次、週期性地在給定的調度時間執行 Job。

典型應用場景:

創建週期性運行的 Jod,最常用的是 數據庫備份

二、控制器創建實例測試

RS 與 Deployment 實例測試

在 K8s 新版本中,官方不再使用 ReplicationControler(RC),而是使用 ReplicaSet(RS)代替 RC,其實 RS 和 RC 本質沒什麼不同,只是 RS 多了一個支持集合式的 selector

支持集合式的 selector 作用:

在創建 Pod 的時候會爲它打上標籤(tag),也會爲 Pod 裏面的容器打上標籤,當需要刪除容器或者進行其他操作的時候,可以通過標籤來進行相關操作。

接下來我們演示一下 RS 標籤的作用

rs_frontend.yaml 資源清單如下:

apiVersion: apps/v1
kind: ReplicaSet
metadata:               # RS 元素信息
  name: frontend        # RS 名稱
  labels:               # 自定義標籤
    app: guestbook      # RS 標籤
    tier: frontend      # RS 標籤
spec:
  replicas: 3           # Pod 副本數
  selector:             # 選擇標籤
    matchLabels:        # 匹配標籤
      tier: frontend    # 匹配 frontend 標籤
  template:             # Pod 模板
    metadata:           # Pod 元素信息
      labels:           # 自定義標籤
        tier: frontend  # 標籤 frontend
    spec:
      containers:
      - name: mynginx   # 容器名稱
        image: hub.test.com/library/mynginx:v1  # 鏡像地址

RS 創建

[root@k8s-master01 ~]# kubectl create -f rs_frontend.yaml 
replicaset.apps/frontend created

查看 Pod 和 RS 狀態

image-20210608101308744

查看 Pod 選擇標籤,這三個 Pod 的標籤都是frontend

image-20210608101435448

接下來修改其中一個 Pod 標籤測試

[root@k8s-master01 ~]# kubectl label pod frontend-8wsl2 tier=frontend1 --overwrite
pod/frontend-8wsl2 labeled

再次查看 Pod 狀態及標籤

image-20210608103242914

此時已經變成四個 Pod ,因爲 RS 是通過frontend標籤進行 Pod 匹配,RS 檢測到 frontend標籤的 Pod 此時少了一個,所以會新創建一個屬於自己的標籤 Pod 出來,從而滿足期望值。

而此時frontend-8wsl2這個 Pod 已經不屬於 RS 的控制範圍之內了,因爲它的標籤是frontend1

把 RS 給刪除後可以更直觀的看出標籤的作用

[root@k8s-master01 ~]# kubectl delete rs frontend
replicaset.apps "frontend" deleted
[root@k8s-master01 ~]# kubectl get pod --show-labels

image-20210608104637077

其他的三個 Pod 都被刪除了,只有標籤爲frontend1 Pod 沒有被刪除,因爲該 Pod 標籤不匹配 RS ,所以 RS 就不會對該 Pod 進行任何操作。

Deployment 實例測試

下面是 Deployment 示例。實際是創建了一個 ReplicaSet,負責啓動三個 Nginx Pod。

nginx-deployment.yaml資源清單如下

apiVersion: apps/v1
kind: Deployment
metadata:                 # Deployment 元素信息
  name: nginx-deployment  # Deployment 名稱
  labels:                 # 自定義標籤
    app: nginx            # Deployment 標籤
spec:
  replicas: 3             # Pod 副本數
  selector:
    matchLabels:
      app: nginx          # 匹配 frontend 標籤
  template:
    metadata:
      labels:
        app: nginx        # Pod 標籤 frontend
    spec:
      containers:
      - name: mynginx
        image: hub.test.com/library/mynginx:v1  # 鏡像地址
        ports:
        - containerPort: 80

創建 Deployment

[root@k8s-master01 ~]# kubectl apply -f nginx-deployment.yaml  --record
deployment.apps/nginx-deployment created

--record 記錄命令,方便回滾的時候方便查看每次 revision 變化。

查看 Deployment、RS、Pod 狀態,全部都已經Running

image-20210608150810501

查看 Pod 詳細信息,訪問測試

[root@k8s-master01 ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
nginx-deployment-644f95f9bc-fb6wv   1/1     Running   0          7m2s   10.244.1.63   k8s-node01   <none>           <none>
nginx-deployment-644f95f9bc-hbhj7   1/1     Running   0          7m2s   10.244.2.46   k8s-node02   <none>           <none>
nginx-deployment-644f95f9bc-j8q2k   1/1     Running   0          7m2s   10.244.1.64   k8s-node01   <none>           <none>

image-20210608155109300

Deployment 擴容功能

[root@k8s-master01 ~]# kubectl scale deployment nginx-deployment --replicas=10

image-20210608155522676

可以看到此時已經擴容到 10 個 Pod ,Deployment 擴容非常簡單,一個命令就可以水平擴容,從而緩解應用對外提供的壓力。

上面是手動擴容的,哪能不能根據 Pod 的負載情況來進行自動擴容縮呢?

是可以的,K8s 提供了 HPA 功能,詳細可以看 我這篇筆記

Deployment 更新鏡像操作

[root@k8s-master01 ~]# kubectl set image deployment/nginx-deployment nginx=hub.test.com/library/mynginx:v2

nginx 爲容器名稱

查看 RS 狀態,此時已經創建新的 RS,但是舊的 RS 還保留着,後續可以進行回滾操作

image-20210608161554356

訪問其中一個 Pod 測試

image-20210608161623909

Deployment 回滾操作

[root@k8s-master01 ~]# kubectl rollout undo deployment/nginx-deployment 
deployment.apps/nginx-deployment rolled back

已經回滾到之前的 RS 的版本

[root@k8s-master01 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5cf56df4d6   0         0         0       8m2s
nginx-deployment-644f95f9bc   10        10        10      37m

默認是回滾到上一個版本,訪問測試

image-20210608161949271

還可以滾動或者回滾到指定版本

查看版本信息

[root@k8s-master01 ~]# kubectl rollout history deployment/nginx-deployment

image-20210608164400532

回滾到指定版本命令如下,這裏就不做測試

[root@k8s-master01 ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=3

版本清理策略

可以在 Deployment 中設置 .spec.revisionHistoryLimit 字段以指定保留此 Deployment 的多少箇舊有 ReplicaSet。其餘的 ReplicaSet 將在後臺被垃圾回收。 默認情況下,此值爲 10 。

DaemonSet 實例測試

daemonset.yaml資源清單如下

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    app: daemonset
spec:
  selector:
    matchLabels:
      name: daemonset-example
  template:
    metadata:
      labels:
        name: daemonset-example
    spec:
      containers:
      - name: mynginx
        image: hub.test.com/library/mynginx:v1

創建 DaemonSet

[root@k8s-master01 ~]# kubectl create -f daemonset.yaml 
daemonset.apps/daemonset-example created

查看 DaemonSet Pod 狀態

image-20210608170237252

分別在兩個 Node 上一個 Pod ,因爲 K8s 裏面有個 污點的概念 ,所以 Master 上不會被創建,可以自行去了解一下,後續的文章中也會講到。

把其中一個 Node 上的 Pod 刪除,它會自動創建一個新的 Pod 來滿足 DaemonSet 的期望值,每個 Node 上一個副本,如圖所示。

image-20210608170950499

Job 實例測試

job.yaml資源清單,它負責計算 π 到小數點後 2000 位,並將結果打印出來。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi  # Job 名稱
spec:
  template:
    spec:
      containers:
      - name: pi      # Pod 名稱
        image: perl   # 鏡像名稱
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        # 計算圓周率,計算小數點後 2000 位
      restartPolicy: Never  # 重啓策略,永不重啓
  backoffLimit: 4     # 設置重試次數,達到後將 Job 標記爲失敗

創建 Job 並查看狀態

[root@k8s-master01 ~]# kubectl create -f job.yaml 
job.batch/pi created
[root@k8s-master01 ~]# kubectl get pod -w

image-20210609103920620

可以看到 Job 從 Running 到 Completed 的一個過程,該 Job 已經完成了計算。

查看具體結果

image-20210609104305730

其他參數配置

.spec.completions 標誌 Job 需要成功完成 Pod 個數,才視爲整個 Job 完成。(默認1)

.spec.parallelism標誌 Pod 並行運行個數。(默認1)

.spec.activeDeadlineSeconds標誌 Job 的整個生命期,一旦 Job 運行時間達到設定值,則所有運行中的 Pod 都會被終止。(秒數值)

CronJob 實例測試

cronjob.yaml資源清單示例如下

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"   # 每分鐘執行一次
  jobTemplate:				# 指定需要運行的任務
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: hub.test.com/library/busybox:latest
            imagePullPolicy: IfNotPresent   # 默認值,本地有則使用本地鏡像就不拉取
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure    # 重啓策略,不失敗則不重啓

大家如果設置定時計劃任務不確定時間的時候,可以通過這個小工具網站進行驗證。

crontab 執行時間計算:https://tool.lu/crontab/

image-20210609152005169

創建 CronJob

[root@k8s-master01 ~]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

查看 CronJob 狀態

[root@k8s-master01 ~]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        21s             21m

查看 Job 運行狀態,默認是保存三個成功的 Pod 記錄

image-20210609164508052

查看其中一個 Pod 日誌,可以看到每分鐘執行一個,符合我們預期設置要求。

[root@k8s-master01 ~]# kubectl logs hello-27053804-jc6jd
Wed Jun  9 08:44:00 UTC 2021
Hello from the Kubernetes cluster
[root@k8s-master01 ~]# kubectl logs hello-27053805-hfr5l
Wed Jun  9 08:45:00 UTC 2021
Hello from the Kubernetes cluster

其他參數配置

.spec.successfulJobsHistoryLimit設置保存執行成功的 Job 數量(默認3)

.spec.failedJobsHistoryLimit設置保存失敗的 Job 數量(默認1)

.spec.concurrencyPolicy併發策略(默認Allow)

當讀到這裏的時候,你會發現 StatefulSet 還有進行實例測試,原因是 StatefulSet 需要跟 K8s 存儲配合使用,所以後續講到存儲部署的時候再進行演示。


作者:神奇二進制
文章出處:https://www.cnblogs.com/l-hh/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利。
文章如有敘述不當的地方,歡迎指正。如果覺得文章對你有幫助,可以精神上的支持 [推薦] 或者 [關注我] ,一起交流,共同進步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章