K8S之控制器詳解


K8S之控制器詳解

簡介

在kubernetes中,按照Pod的創建方式可以將其分為兩類:

  • 自主式:kubernetes直接創建出來的Pod,這種Pod刪除后就沒有了,也不會重建。
  • 控制器創建pod:通過Pod控制器創建的Pod,這種Pod刪除之后還會自動重建。

Pod控制器是管理Pod的中間層,使用了Pod控制器之后,我們只需要告訴Pod控制器,想要多少個什么樣的Pod就可以了,它就會創建出滿足條件的Pod並確保每一個Pod處於用戶期望的狀態,如果Pod在運行中出現故障,控制器會基於指定的策略重啟或重新創建pod

控制器種類

在kubernetes中,有很多類型的Pod控制器,每種都有自己的適合的場景,常見的有下面這些:

  • ReplicationController:比較原始的Pod控制器,已經被廢棄,由ReplicaSet替代。
  • ReplicaSet:保證指定數量的Pod運行,並支持Pod數量變更,鏡像版本變更。
  • Deployment:通過控制ReplicaSet來控制Pod,並支持滾動升級、版本回退。
  • Horizontal Pod Autoscaler:以根據集群負載自動調整Pod的數量,實現削峰填谷。
  • DaemonSet:在集群中的指定Node上都運行一個副本,一般用於守護進程類的任務。
  • Job:它創建出來的Pod只要完成任務就立即退出,用於執行一次性任務。
  • CronJob:它創建的Pod會周期性的執行,用於執行周期性的任務。
  • StatefulSet:管理有狀態的應用。

ReplicatSet

簡介

ReplicaSet的主要作用是保證一定數量的Pod能夠正常運行,它會持續監聽這些Pod的運行狀態,一旦Pod發生故障,就會重啟或重建。同時它還支持對Pod數量的擴縮容和版本鏡像的升級。

rs

資源清單文件

apiVersion: apps/v1 # 版本號 
kind: ReplicaSet # 類型 
metadata: # 元數據 
  name: # rs名稱
  namespace: # 所屬命名空間 
  labels: #標簽 
    controller: rs 
spec: # 詳情描述 
  replicas: 3 # 副本數量 
  selector: # 選擇器,通過它指定該控制器管理哪些po
    matchLabels: # Labels匹配規則 
      app: nginx-pod 
    matchExpressions: # Expressions匹配規則 
      - {key: app, operator: In, values: [nginx-pod]} 
template: # 模板,當副本數量不足時,會根據下面的模板創建pod副本 
  metadata: 
    labels: 
      app: nginx-pod 
  spec: 
    containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

在這里,需要新了解的配置項就是spec下面幾個選項:

replicas:指定副本數量,其實就是當然rs創建出來的Pod的數量,默認為1.

selector:選擇器,它的作用是建立Pod控制器和Pod之間的關聯關系,采用了Label Selector機制(在Pod模塊上定Label,在控制器上定義選擇器,就可以表明當前控制器能管理哪些Pod了)。

template:模板,就是當前控制器創建Pod所使用的模板,里面其實就是前面學過的Pod的定

創建ReplicaSet

cat > pc-replicaset.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: ReplicaSet # 類型
metadata: # 元數據
  name: pc-replicaset # rs名稱
  namespace: dev # 命名類型
spec: # 詳細描述
  replicas: 3 # 副本數量
  selector: # 選擇器,通過它指定該控制器可以管理哪些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模塊 當副本數據不足的時候,會根據下面的模板創建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名稱
          image: nginx:1.17.1 # 容器需要的鏡像地址
          ports:
            - containerPort: 80 # 容器所監聽的端口
EOF

# 創建rs
[root@master k8s]# kubectl create -f pc-replicaset.yaml 

# 查看rs
[root@master k8s]# kubectl get -n dev rs pc-replicaset -o wide

image-20211024141447471

擴縮容

# 編輯rs的副本數量,修改spec:replicas:6即可。
[root@master k8s]# kubectl edit -n dev rs pc-replicaset 

[root@master k8s]# kubectl get -n dev pod

image-20211024141659976

# --replicas=3指定pod數量
[root@master k8s]# kubectl scale -n dev rs pc-replicaset --replicas=3

[root@master k8s]# kubectl get -n dev pod

image-20211024141818034

鏡像升級

# 編輯rs的容器鏡像,修改spec:containers:image為nginx:1.17.2即可
[root@master k8s]# kubectl edit -n dev rs pc-replicaset 

[root@master k8s]# kubectl get -n dev rs -o wide	

image-20211024142108338

# kubectl set image rs rs名稱 容器名稱=鏡像版本 -n 命名空間
[root@master k8s]# kubectl set image -n dev rs pc-replicaset nginx=nginx:1.17.1

[root@master k8s]# kubectl get -n dev rs -o wide	

image-20211024142247620

刪除ReplicaSet

# 在kubernetes刪除ReplicaSet前,會將ReplicaSet的replicas調整為0,等到所有的Pod被刪除后,再執行ReplicaSet對象的刪除
[root@master k8s]# kubectl delete rs pc-replicaset -n dev

[root@master k8s]# kubectl get rs,pod -n dev

image-20211024142450077

# 如果希望僅僅刪除ReplicaSet對象(保留Pod),只需要在使用kubectl delete rs命令的時候添加--cascade=false選項(不推薦)
kubectl delete rs pc-replicaset -n dev --cascade=false

Deployment

簡介

為了更好的解決服務編排的問題,kubernetes在v1.2版本開始,引入了Deployment控制器。值得一提的是,Deployment控制器並不直接管理Pod,而是通過管理ReplicaSet來間接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment的功能比ReplicaSet強大。

dp

Deployment的主要功能如下:

  • 支持ReplicaSet的所有功能。

  • 支持發布的停止、繼續。

  • 支持版本滾動更新和版本回退。

Deployment資源清單

apiVersion: apps/v1 # 版本號 
kind: Deployment # 類型 
metadata: # 元數據 
  name: # rs名稱 
  namespace: # 所屬命名空間 
  labels: #標簽 
    controller: deploy 
spec: # 詳情描述 
  replicas: 3 # 副本數量 
  revisionHistoryLimit: 3 # 保留歷史版本,默認為10 
  paused: false # 暫停部署,默認是false 
  progressDeadlineSeconds: 600 # 部署超時時間(s),默認是600 
  strategy: # 策略 
    type: RollingUpdate # 滾動更新策略 
    rollingUpdate: # 滾動更新 
      maxSurge: 30% # 最大額外可以存在的副本數,可以為百分比,也可以為整數 maxUnavailable: 30% # 最大不可用狀態的    Pod 的最大值,可以為百分比,也可以為整數 
  selector: # 選擇器,通過它指定該控制器管理哪些pod 
    matchLabels: # Labels匹配規則 
      app: nginx-pod 
    matchExpressions: # Expressions匹配規則 
      - {key: app, operator: In, values: [nginx-pod]} 
  template: # 模板,當副本數量不足時,會根據下面的模板創建pod副本 
    metadata: 
      labels: 
        app: nginx-pod 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

創建Deployment

cat > pc-deployment.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: Deployment # 類型
metadata: # 元數據
  name: pc-deployment # deployment的名稱
  namespace: dev # 命名類型
spec: # 詳細描述
  replicas: 3 # 副本數量
  selector: # 選擇器,通過它指定該控制器可以管理哪些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模塊 當副本數據不足的時候,會根據下面的模板創建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名稱
          image: nginx:1.17.1 # 容器需要的鏡像地址
          ports:
            - containerPort: 80 # 容器所監聽的端口
EOF
# 創建Deploy
[root@master k8s]# kubectl create -f pc-deployment.yaml

# 查看
[root@master k8s]# kubectl get -n dev deployments pc-deployment -o wide

image-20211024143748978

擴縮容

# 編輯Deployment的副本數量,修改spec:replicas:6即可
[root@master k8s]# kubectl edit -n dev deployments pc-deployment 

[root@master k8s]# kubectl get pod -n dev

image-20211024143942826

# 使用命令進行修改
[root@master k8s]# kubectl scale -n dev deployment pc-deployment --replicas=3

[root@master k8s]# kubectl get pod -n dev

image-20211024144056402

鏡像更新

Deployment支持兩種鏡像更新的策略:重建更新滾動更新(默認),可以通過strategy選項進行配置。

strategy: 指定新的Pod替代舊的Pod的策略,支持兩個屬性
  type: 指定策略類型,支持兩種策略
    Recreate:在創建出新的Pod之前會先殺掉所有已經存在的Pod
    RollingUpdate:滾動更新,就是殺死一部分,就啟動一部分,在更新過程中,存在兩個版本的Pod
  rollingUpdate:當type為RollingUpdate的時候生效,用於為rollingUpdate設置參數,支持兩個屬性:
    maxUnavailable:用來指定在升級過程中不可用的Pod的最大數量,默認為25%。
    maxSurge: 用來指定在升級過程中可以超過期望的Pod的最大數量,默認為25%。
重建更新
cat > pc-deployment.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: Deployment # 類型
metadata: # 元數據
  name: pc-deployment # deployment的名稱
  namespace: dev # 命名類型
spec: # 詳細描述
  replicas: 3 # 副本數量
  strategy: # 鏡像更新策略
    type: Recreate # Recreate:在創建出新的Pod之前會先殺掉所有已經存在的Pod
  selector: # 選擇器,通過它指定該控制器可以管理哪些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模塊 當副本數據不足的時候,會根據下面的模板創建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名稱
          image: nginx:1.17.1 # 容器需要的鏡像地址
          ports:
            - containerPort: 80 # 容器所監聽的端口
EOF

# 加載yaml配文件
[root@master k8s]# kubectl apply -f pc-deployment.yaml

# 版本更換
[root@master k8s]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev

# 另起終端查看pod
[root@master k8s]# kubectl get pod -n dev -w

image-20211024144733984

滾動更新
cat > pc-deployment.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: Deployment # 類型
metadata: # 元數據
  name: pc-deployment # deployment的名稱
  namespace: dev # 命名類型
spec: # 詳細描述
  replicas: 3 # 副本數量
  strategy: # 鏡像更新策略
    type: RollingUpdate # RollingUpdate:滾動更新,就是殺死一部分,就啟動一部分,在更新過程中,存在兩個版本的Pod
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  selector: # 選擇器,通過它指定該控制器可以管理哪些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模塊 當副本數據不足的時候,會根據下面的模板創建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名稱
          image: nginx:1.17.1 # 容器需要的鏡像地址
          ports:
            - containerPort: 80 # 容器所監聽的端口
EOF

# 重新加載
[root@master k8s]# kubectl apply -f pc-deployment.yaml

# 鏡像升級
[root@master k8s]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev

# 另起終端查看pod
[root@master k8s]# kubectl get pod -n dev -w

image-20211024152422377

# 查看rs,發現原來的rs依舊存在,只是Pod的數量變為0,而后又產生了一個rs,Pod的數量變為3
# 其實這就是deployment能夠進行版本回退的奧妙所在
[root@master k8s]# kubectl get rs -n dev

image-20211024152520106

版本回退

Deployment支持版本升級過程中的暫停、繼續功能以及版本回退等諸多功能,下面具體來看:

# 查看升級狀態
[root@master k8s]# kubectl rollout status deployment pc-deployment -n dev

image-20211024152643320

# 查看升級歷史記錄
[root@master k8s]# kubectl rollout history deployment pc-deployment -n dev

image-20211024152759187

# 可以使用-to-revision=1回退到1版本,如果省略這個選項,就是回退到上個版本,即3版本
[root@master k8s]# kubectl rollout undo deployment pc-deployment --to-revision=3 -n dev

image-20211024153216607

deployment之所以能夠實現版本的回退,就是通過記錄下歷史的ReplicaSet來實現的,一旦想回滾到那個版本,只需要將當前版本的Pod數量降為0,然后將回退版本的Pod提升為目標數量即可。

金絲雀發布

Deployment支持更新過程中的控制,如暫停更新操作(pause)或繼續更新操作(resume)。

例如有一批新的Pod資源創建完成后立即暫停更新過程,此時,僅存在一部分新版本的應用,主體部分還是舊的版本。然后,再篩選一小部分的用戶請求到新版本的Pod應用,繼續觀察能夠穩定的按照期望的方式運行,如果沒有問題之后再繼續完成余下的Pod資源的滾動更新,否則立即回滾操作。

[root@master k8s]# kubectl set image deployment pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev

image-20211024153705355

# 另起終端查看狀態
[root@master k8s]# kubectl rollout status deployment pc-deployment -n dev

image-20211024153745196

# 查看rs
# 監控更新的過程,可以看到已經新增了一個資源,但是並沒有按照預期的狀態去刪除一個舊的資源,因為使用了pause暫停命令
[root@master k8s]# kubectl get -n dev rs

image-20211024153823686

# 查看pod
[root@master k8s]# kubectl get -n dev pod

image-20211024153933659

# 繼續更新
[root@master k8s]# kubectl rollout resume deployment pc-deployment -n dev

# 查看
[root@master k8s]# kubectl get -n dev rs,pod -o wide

image-20211024154136351### Horizontal Pod Autoscaler

簡介

我們已經可以通過手動執行kubectl scale命令實現Pod的擴縮容,但是這顯然不符合kubernetes的定位目標–自動化和智能化。kubernetes期望可以通過監測Pod的使用情況,實現Pod數量的自動調整,於是就產生了HPA這種控制器。

HPA可以獲取每個Pod的利用率,然后和HPA中定義的指標進行對比,同時計算出需要伸縮的具體值,最后實現Pod的數量的調整。其實HPA和之前的Deployment一樣,也屬於一種kubernetes資源對象,它通過追蹤分析目標Pod的負載變化情況,來確定是否需要針對性的調整目標Pod的副本數。

安裝metrics-server

# 下載
wget https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz

# 解壓
tar -zxvf v0.3.6.tar.gz

# 切換目錄
cd metrics-server-0.3.6/deploy/1.8+/

# 備份配置文件
cp metrics-server-deployment.yaml metrics-server-deployment.bak.yaml

# 修改配置文件
vim metrics-server-deployment.yaml
# 按圖中添加下面選項
hostNetwork: true
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6 
args:
  - --kubelet-insecure-tls 
  - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP

image-20211024172809405

# 安裝metrics-server
kubectl apply -f ./

# 查看metrics-server生成的Pod
[root@master 1.8+]# kubectl get pod -n kube-system

image-20211024172940989

# 查看資源使用情況
[root@master 1.8+]# kubectl top node

image-20211024173034056

[root@master 1.8+]# kubectl top pod -n kube-system

image-20211024173110494

配置Deployment控制器

cat > nginx.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: Deployment # 類型
metadata: # 元數據
  name: nginx # deployment的名稱
  namespace: dev # 命名類型
spec: # 詳細描述
  selector: # 選擇器,通過它指定該控制器可以管理哪些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模塊 當副本數據不足的時候,會根據下面的模板創建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名稱
          image: nginx:1.17.1 # 容器需要的鏡像地址
          ports:
            - containerPort: 80 # 容器所監聽的端口
          resources: # 資源限制
            requests:
              cpu: "100m" # 100m表示100millicpu,即0.1個CPU
EOF

# 創建控制器
[root@master k8s]# kubectl create -f nginx.yaml

# 查看
[root@master k8s]# kubectl get pods,deploy -o wide -n dev  

image-20211024173839260

創建service

# 創建service
[root@master k8s]# kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80 -n dev

[root@master k8s]# kubectl get svc -n dev -o wide

image-20211024174008274

部署HPA

cat > pc-hpa.yaml << EOF
apiVersion: autoscaling/v1 # 版本號
kind: HorizontalPodAutoscaler # 類型
metadata: # 元數據
  name: pc-hpa # deployment的名稱
  namespace: dev # 命名類型
spec:
  minReplicas: 1 # 最小Pod數量
  maxReplicas: 10 # 最大Pod數量
  targetCPUUtilizationPercentage: 3 # CPU使用率指標
  scaleTargetRef:  # 指定要控制的Nginx的信息
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
EOF

# 創建
[root@master k8s]# kubectl create -f pc-hpa.yaml

[root@master k8s]# kubectl get hpa -n dev

image-20211024174217699

壓力測試

# 另起終端動態查詢deploy
[root@master k8s]# kubectl get deployment -n dev -w

image-20211024175221924

# 另起終端查詢pod
[root@master k8s]# kubectl get pod -n dev -w

image-20211024175334374

# 另起終端查詢hpa
[root@master k8s]# kubectl get -n dev hpa -w

image-20211024175259719

# ab進行壓力測試
ab -n 1000 -c 1000 http://10.1.1.2:31742/index.html

image-20211024174850252

  • 正常流量的hpa

image-20211024180407681

  • 正常流量pod

image-20211024180456197

  • 正常流量deployment

image-20211024180551178### DaemonSet

簡介

DaemonSet類型的控制器可以保證集群中的每一台(或指定)節點上都運行一個副本,一般適用於日志收集、節點監控等場景。也就是說,如果一個Pod提供的功能是節點級別的(每個節點都需要且只需要一個),那么這類Pod就適合使用DaemonSet類型的控制器創建

ds

DaemonSet控制器的特點:

  • 每向集群中添加一個節點的時候,指定的Pod副本也將添加到該節點上。
  • 當節點從集群中移除的時候,Pod也會被垃圾回收。

資源清單

apiVersion: apps/v1 # 版本號
kind: DaemonSet # 類型
metadata: # 元數據
  name: # 名稱
  namespace: #命名空間
  labels: #標簽
    controller: daemonset
spec: # 詳情描述
  revisionHistoryLimit: 3 # 保留歷史版本
  updateStrategy: # 更新策略
    type: RollingUpdate # 滾動更新策略
    rollingUpdate: # 滾動更新
      maxUnavailable: 1 # 最大不可用狀態的Pod的最大值,可用為百分比,也可以為整數
  selector: # 選擇器,通過它指定該控制器管理那些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
    matchExpressions: # Expressions匹配規則
      - key: app
        operator: In
        values:
          - nginx-pod
  template: # 模板,當副本數量不足時,會根據下面的模板創建Pod模板
     metadata:
       labels:
         app: nginx-pod
     spec:
       containers:
         - name: nginx
           image: nginx:1.17.1
           ports:
             - containerPort: 80

創建DaemonSet

cat > pc-daemonset.yaml << EOF
apiVersion: apps/v1 # 版本號
kind: DaemonSet # 類型
metadata: # 元數據
  name: pc-damonset # 名稱
  namespace: dev #命名空間
spec: # 詳情描述
  selector: # 選擇器,通過它指定該控制器管理那些Pod
    matchLabels: # Labels匹配規則
      app: nginx-pod
  template: # 模板,當副本數量不足時,會根據下面的模板創建Pod模板
     metadata:
       labels:
         app: nginx-pod
     spec:
       containers:
         - name: nginx
           image: nginx:1.17.1
           ports:
             - containerPort: 80
EOF

# 創建DS
[root@master k8s]# kubectl create -f pc-daemonset.yaml 

[root@master k8s]# kubectl get -n dev ds -o wide

image-20211024212752023

在筆者心里安裝DaemonSet如果沒有配置Node-Selector應該會在所有的節點都會生成DaemonSet控制器,但是在此處我只有node2節點生成控制器,而node1節點沒有生成,但是筆者所有node節點都是處於正常狀態,至於為什么產生這樣的原因沒有排查成功,如果有大佬看到該文章麻煩告知一下排查思路,另外筆者只是一個本科生如果有錯誤的地方也請大家不要噴。

Job

概述

Job可以保證指定數量的pod批量完成一次性的任務

  • job創建的Pod成功結束的時候,job會記錄pod的數量
  • 當記錄的pod達到一定數量的時候,job執行完成

資源清單

apiVersion: batch/v1 # 版本號
kind: Job # 類型
metadata: # 元數據
  name:  # 名稱
  namespace:  #命名空間
  labels: # 標簽
    controller: job
spec: # 詳情描述
  completions: 1 # 指定Job需要成功運行Pod的總數量,默認為1 
  parallelism: 1 # 指定Job在任一時刻應該並發運行Pod的數量,默認為1
  activeDeadlineSeconds: 30 # 指定Job可以運行的時間期限,超過時間還沒結束,系統將會嘗試進行終止
  backoffLimit: 6 # 指定Job失敗后進行重試的次數,默認為6
  manualSelector: true # 是否可以使用selector選擇器選擇Pod,默認為false
  selector: # 選擇器,通過它指定該控制器管理那些Pod
    matchLabels: # Labels匹配規則
      app: counter-pod
    matchExpressions: # Expressions匹配規則
      - key: app
        operator: In
        values:
          - counter-pod
  template: # 模板,當副本數量不足時,會根據下面的模板創建Pod模板
     metadata:
       labels:
         app: counter-pod
     spec:
       restartPolicy: Never # 重啟策略只能設置為Never或OnFailure
       containers:
         - name: counter
           image: busybox:1.30
           command: ["/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done"]

創建job

cat > pc-job.yaml << EOF
apiVersion: batch/v1
kind: Job
metadata:
  name:  name
  namespace: dev
spec:
  # 是否使用標簽選擇器
  manualSelector: true
  selector:
    matchLabels:
      app: counter-pod
  # pod模板
  template:
    metadata:
      labels:
        app:  counter-pod
    spec:
      # 配置容器
      containers:
        - name: counter
          image:  busybox:1.30
          command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 3;done" ]
      # 由於是一次性任務因此不需要重啟
      restartPolicy: Never

EOF

# 創建
[root@master k8s]# kubectl create -f pc-job.yaml 

# 查看
[root@master k8s]# kubectl get pod -n dev -w

image-20211025100015283

# 查看job
[root@master k8s]# kubectl get job -n dev -w

image-20211025100056745### Cronjob

概述

CronJob控制器以Job控制器為其管控對象,並借助它管理Pod資源對象,Job控制器定義的作業任務在其控制器資源創建之后便會立即執行,但CronJob可以以類似Linux操作系統的周期性任務作業計划的方式控制器運行時間點及重復運行的方式,換言之,CronJob可以在特定的時間點反復去執行Job任務。

cj

資源清單

apiVersion: batch/v1beta1 # 版本號
kind: CronJob # 類型
metadata: # 元數據
  name:  # 名稱
  namespace:  #命名空間
  labels:
    controller: cronjob
spec: # 詳情描述
  schedule: # cron格式的作業調度運行時間點,用於控制任務任務時間執行
  concurrencyPolicy: # 並發執行策略
  failedJobsHistoryLimit: # 為失敗的任務執行保留的歷史記錄數,默認為1
  successfulJobsHistoryLimit: # 為成功的任務執行保留的歷史記錄數,默認為3
  jobTemplate: # job控制器模板,用於為cronjob控制器生成job對象,下面其實就是job的定義
    metadata: {}
    spec:
      completions: 1 # 指定Job需要成功運行Pod的總次數,默認為1
      parallelism: 1 # 指定Job在任一時刻應該並發運行Pod的數量,默認為1
      activeDeadlineSeconds: 30 # 指定Job可以運行的時間期限,超過時間還沒結束,系統將會嘗試進行終止
      backoffLimit: 6 # 指定Job失敗后進行重試的次數,默認為6
      template: # 模板,當副本數量不足時,會根據下面的模板創建Pod模板
        spec:
          restartPolicy: Never # 重啟策略只能設置為Never或OnFailure
          containers:
            - name: counter
              image: busybox:1.30
              command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done" ]

concurrencyPolicy:並發執行策略

  • Allow:運行job並發執行(默認)
  • Forbid:禁止並發執行,如果上次任務沒有執行完畢會跳過下一次任務
  • Replace:新的任務代替舊的任務

創建Cronjob

# 創建cronjob
cat > pc-cronjob.yaml << EOF
apiVersion: batch/v1beta1 # 版本號
kind: CronJob # 類型
metadata:         # 元數據
  name: pc-cronjob # 名稱
  namespace: dev  #命名空間
spec: # 詳情描述
  schedule: "*/1 * * * * " # cron格式的作業調度運行時間點,用於控制任務任務時間執行
  jobTemplate: # job控制器模板,用於為cronjob控制器生成job對象,下面其實就是job的定義
    metadata: {}
    spec:
      template: # 模板,當副本數量不足時,會根據下面的模板創建Pod模板
        spec:
          restartPolicy: Never # 重啟策略只能設置為Never或OnFailure
          containers:
            - name: counter
              image: busybox:1.30
              command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 2;done" ]
EOF
[root@master k8s]# kubectl create -f pc-cronjob.yaml 

[root@master k8s]# kubectl get -n dev cj -o wide

image-20211026162918777

# 另起終端查看cronjob
[root@master k8s]# kubectl get cronjob -n dev -w

image-20211026163135679

# 另起終端查看job
[root@master k8s]# kubectl get job -n dev -w

image-20211026163026436

# 另起終端查看pod
[root@master k8s]# kubectl get pod -n dev -w

image-20211026163105420### StatefulSet

概述

  • 無狀態應用

    • 認為pod都是一樣的
    • 隨意進行伸縮擴展
    • 不用考慮在那個node運行
    • 沒有順序要求
  • 有狀態應用

    • 有順序要求
    • pod是獨立不一樣的,保證pod啟動順序和唯一性
    • 需要考慮在哪個pod進行運行
    • 需要安裝順序進行伸縮和擴展
  • StatefulSet是Kubernetes提供的管理有狀態應用的負載管理控制器。

  • StatefulSet部署需要HeadLinessService(無頭服務)

使用HeadLinessService(無頭服務)

  • 在使用Deployment的時候,每一個Pod名稱是沒有順序的,是通過隨機字符串拼湊而成的,因此此時的pod是無順序的,但是在StatefulSet中要求pod是有序的每一個pod不能被隨意取代,pod重建后pod名稱保持不變
  • Pod的P是變化的,所以是以pod名稱來識別,pod名稱是pod唯一識別碼,無頭服務可以給每一個pod一個唯一的名稱

創建StatefulSet

cat > pc-stateful.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # 將clusterIP設置為None,即可創建headliness Service
  type: ClusterIP
  ports:
    - port: 80 # Service的端口
      targetPort: 80 # Pod的端口
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pc-statefulset
  namespace: dev
spec:
  replicas: 3
  serviceName: service-headliness
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80
EOF

[root@master k8s]# kubectl create -f pc-stateful.yaml 

[root@master k8s]# kubectl get statefulset pc-statefulset -n dev -o wide

image-20211027104849016

# 查看pod
[root@master k8s]# kubectl get pod -n dev -o wide

image-20211027105426768

Deployment和StatefulSet的區別

  • Deployment和StatefulSet的區別:Deployment沒有唯一標識而StatefulSet有唯一標識。

  • StatefulSet的唯一標識是根據主機名+一定規則生成的。

  • StatefulSet的唯一標識是主機名.無頭Service名稱.命名空間.svc.cluster.local

StatefulSet的金絲雀發布

updateStrategy:
  rollingUpdate: # 如果更新的策略是OnDelete,那么rollingUpdate就失效
    partition: 2 # 表示從第2個分區開始更新,默認是0
  type: RollingUpdate /OnDelete # 滾動更新

StatefulSet支持兩種更新策略:OnDelete和RollingUpdate(默認),其中OnDelete表示刪除之后才更新,RollingUpdate表示滾動更新

cat > pc-statefulset.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # 將clusterIP設置為None,即可創建headliness Service
  type: ClusterIP
  ports:
    - port: 80 # Service的端口
      targetPort: 80 # Pod的端口
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pc-statefulset
  namespace: dev
spec:
  replicas: 3
  serviceName: service-headliness
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80
			
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate  
EOF

[root@master k8s]# kubectl apply -f pc-stateful.yaml 

# 修改鏡像
[root@master k8s]# kubectl set image -n dev statefulset pc-statefulset nginx=nginx:1.17.2

image-20211027111401761


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM