Kubernetes:Pod總結(二)

不羈的羅恩發表於2022-02-10

Blog:部落格園 個人

承接上文

在實際的生產使用場景中,直接用 Pod 是不合適的,因為必然會產生單點故障。因此,我們需要有一種方法來方便地建立、管理同一個服務的多個例項 Pod。Kubernetes 中引入了 Workload(工作負載) 的概念,它可以理解為 Pod 的父資源,主要的作用就是來管理多個 Pod 的生命週期。

Workload資源主要分為以下幾類:

  • Deployment 和 ReplicaSet :最常見的型別,用來管理叢集上的無狀態應用。
  • DaemonSet:在叢集的每個節點上部署一個 Pod,適用於各種 agent 業務的場景。 such as a networking helper tool, or be part of an add-on.
  • StatefulSet:適用於各種有狀態服務的場景。 例如,如果負載會將資料作持久儲存,可以執行一個 StatefulSet,將每個 Pod 與某個 PersistentVolume 對應起來。
  • Job 和 CronJob: 用於一些自動化任務。Job 用來表達的是一次性的任務,而 CronJob 會根據其時間規劃反覆執行。

接下來將詳細介紹幾種Workload資源的使用方法。

Deployment 和 ReplicaSet

通常,我們不直接建立Pod,而是通過Deployment來建立Pod,由 Deployment 來負責建立、更新、維護其所管理的所有 Pods。而ReplicaSet則負責控制replicas(副本)的數量。

接下來,使用以下deployment作為例子來剖析兩者的關係:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:latest
          name: nginx
      topologySpreadConstraints:
        - topologyKey: address
          maxSkew: 1
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: nginx

建立這個deployment:

[root@master-1 test]# kubectl create -f nginx.yml 
deployment.apps/nginx created
[root@master-1 test]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-58c948c775-5hbhf   1/1     Running   0          20s   10.16.84.138   node-1   <none>           <none>
nginx-58c948c775-vfdp8   1/1     Running   0          20s   10.16.247.19   node-2   <none>           <none>

通過kubectl describe deploy nginx可知,有ScalingReplicaSet資訊:

Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  79s   deployment-controller  Scaled up replica set nginx-58c948c775 to 2

可以清晰的看到2個pod例項是通過replicaset生成的:

[root@master-1 test]# kubectl get rs nginx-58c948c775
NAME               DESIRED   CURRENT   READY   AGE
nginx-58c948c775   2         2         2       4m22s
[root@master-1 test]# kubectl describe rs nginx-58c948c775
Name:           nginx-58c948c775
Namespace:      default
Selector:       app=nginx,pod-template-hash=58c948c775
Labels:         app=nginx
                pod-template-hash=58c948c775
Annotations:    deployment.kubernetes.io/desired-replicas: 2
                deployment.kubernetes.io/max-replicas: 3
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/nginx
Replicas:       2 current / 2 desired
Pods Status:    2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx
           pod-template-hash=58c948c775
  Containers:
   nginx:
    Image:        nginx:latest
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  4m31s  replicaset-controller  Created pod: nginx-58c948c775-5hbhf
  Normal  SuccessfulCreate  4m31s  replicaset-controller  Created pod: nginx-58c948c775-vfdp8

說明:

  • NAME:列出名字空間中 ReplicaSet 的名稱;
  • DESIRED:顯示應用的期望副本個數,即在建立 Deployment 時所定義的值。 此為期望狀態;
  • CURRENT:顯示當前執行狀態中的副本個數;
  • READY:顯示應用中有多少副本可以為使用者提供服務;
  • AGE:顯示應用已經執行的時間長度。

總結

  • 通過kubectl create建立一個deployment,那麼此時就會呼叫deployment-controller建立一個replicaset;
  • replicaset則會呼叫replicaset-controller建立相應的pod;
  • 最後由default-scheduler將pod分配到對應的node節點。

?注意:儘管 ReplicaSet 可以獨立使用,目前它們的主要用途是提供給 Deployment 作為 編排 Pod 建立、刪除和更新的一種機制。

DaemonSet

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

DaemonSet 的一些典型用法:

  • 在每個節點上執行叢集守護程式,例如ceph。
  • 在每個節點上執行日誌收集守護程式,例如filebeat、logstash。
  • 在每個節點上執行監控守護程式,例如Promethues Node Exporter。

例如:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ds
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx-ds
      release: stable
  template:
    metadata:
      labels:
        app: nginx-ds
        release: stable
    spec:
      containers:
      - name: nginx-ds
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

建立DaemonSet:

[root@master-1 test]# kubectl create -f nginx-ds.yml 
daemonset.apps/nginx-ds created
[root@master-1 test]# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-ds-fhz7n   1/1     Running   0          97s   10.16.84.139   node-1   <none>           <none>
nginx-ds-jvc9p   1/1     Running   0          97s   10.16.247.20   node-2   <none>           <none>

?注意: apiVersionkindmetadata 也是DaemonSet必需欄位。

排程指定節點:

  • nodeSelector:只排程到匹配指定 label 的 Node 上

  • nodeAffinity:功能更豐富的 Node 選擇器,比如支援集合操作

  • podAffinity:排程到滿足條件的 Pod 所在的 Node 上

StatefulSet

StatefulSet是Kubernetes中有狀態應用管理的標準實現,本質上是Deployment的一種變體。

在日常開發的應用中,通常可以分為兩類:有狀態無狀態,比如web服務通常都是無狀態的,web應用資料主要來自後端儲存、快取等中介軟體,而本身並不儲存資料;而MySQL、Redis等中介軟體是有狀態的,其資料也是應用自身的一部分,由此可以看出有狀態應用本身會包含兩部分:應用與資料。

Jobs

Job 會建立一個或者多個 Pods,並將繼續重試 Pods 的執行,直到指定數量的 Pods 成功終止。 隨著 Pods 成功結束,Job 跟蹤記錄成功完成的 Pods 個數。 當數量達到指定的成功個數閾值時,任務(即 Job)結束。 刪除 Job 的操作會清除所建立的全部 Pods。 掛起 Job 的操作會刪除 Job 的所有活躍 Pod,直到 Job 被再次恢復執行。

示例:

kubectl apply -f https://kubernetes.io/examples/controllers/job.yaml

檢視Pods:

[root@master-1 test]# kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
pi-bkpn8   1/1     Running   0          36s

檢視輸出:

[root@master-1 test]# kubectl logs pi-bkpn8
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901

?Tips:Job 完成時不會再建立新的 Pod,不過已有的 Pod 通常也不會被刪除。 保留這些 Pod 使得你可以檢視已完成的 Pod 的日誌輸出,以便檢查錯誤、警告 或者其它診斷性輸出。 Job 完成時 Job 物件也一樣被保留下來,這樣你就可以檢視它的狀態。 在檢視了 Job 狀態之後刪除老的 Job 的操作留給了使用者自己。

刪除Job:

[root@master-1 test]# kubectl delete jobs/pi
job.batch "pi" deleted

也可通過CronJob來清理。

CronJob

FEATURE STATE: Kubernetes v1.21 [stable]

CronJob 建立基於時隔重複排程的 Jobs。它用 Cron 格式進行編寫, 並週期性地在給定的排程時間執行 Job。

示例:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

相關文章