在 DaemonSet 上執行滾動式更新

本頁說明如何在 DaemonSet 上執行滾動式更新。

準備開始

您需要有一個 Kubernetes 叢集,並且必須將 kubectl 命令列工具配置為與您的叢集通訊。 建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。 如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用以下 Kubernetes 實驗環境

DaemonSet 更新策略

DaemonSet 有兩種更新策略類型

  • OnDelete:使用 OnDelete 更新策略,在您更新 DaemonSet 範本後,只有在您手動刪除舊的 DaemonSet Pod 時,才會建立新的 DaemonSet Pod。 這與 Kubernetes 1.5 或更早版本中 DaemonSet 的行為相同。
  • RollingUpdate:這是預設的更新策略。
    使用 RollingUpdate 更新策略,在您更新 DaemonSet 範本後,舊的 DaemonSet Pod 將被終止,而新的 DaemonSet Pod 將以受控制的方式自動建立。 在整個更新過程中,每個節點上最多只會有一個 DaemonSet 的 Pod 正在執行。

執行滾動式更新

若要啟用 DaemonSet 的滾動式更新功能,您必須將其 .spec.updateStrategy.type 設定為 RollingUpdate

您可能需要設定 .spec.updateStrategy.rollingUpdate.maxUnavailable (預設值為 1)、.spec.minReadySeconds (預設值為 0) 和 .spec.updateStrategy.rollingUpdate.maxSurge (預設值為 0)。

建立使用 RollingUpdate 更新策略的 DaemonSet

這個 YAML 檔案指定一個更新策略為 'RollingUpdate' 的 DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

在驗證 DaemonSet 資訊清單的更新策略後,建立 DaemonSet

kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

或者,如果您計劃使用 kubectl apply 更新 DaemonSet,請使用 kubectl apply 建立相同的 DaemonSet。

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

檢查 DaemonSet 的 RollingUpdate 更新策略

檢查您的 DaemonSet 的更新策略,並確保它設定為 RollingUpdate

kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system

如果您尚未在系統中建立 DaemonSet,請改用以下命令檢查您的 DaemonSet 資訊清單

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

兩個命令的輸出都應該是

RollingUpdate

如果輸出不是 RollingUpdate,請返回並相應地修改 DaemonSet 物件或資訊清單。

更新 DaemonSet 範本

對於 RollingUpdate DaemonSet 的 .spec.template 進行任何更新都將觸發滾動更新。讓我們透過套用新的 YAML 檔案來更新 DaemonSet。這可以使用幾個不同的 kubectl 命令來完成。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

宣告式命令

如果您使用組態檔更新 DaemonSet,請使用 kubectl apply

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml

命令式命令

如果您使用命令式命令更新 DaemonSet,請使用 kubectl edit

kubectl edit ds/fluentd-elasticsearch -n kube-system
僅更新容器映像

如果您只需要更新 DaemonSet 範本中的容器映像,即 .spec.template.spec.containers[*].image,請使用 kubectl set image

kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system

監看滾動更新狀態

最後,監看最新 DaemonSet 滾動更新的推出狀態

kubectl rollout status ds/fluentd-elasticsearch -n kube-system

當推出完成時,輸出會類似於這樣

daemonset "fluentd-elasticsearch" successfully rolled out

疑難排解

DaemonSet 滾動更新卡住

有時,DaemonSet 滾動更新可能會卡住。以下是一些可能的原因

某些節點資源耗盡

推出卡住的原因是新的 DaemonSet Pod 無法排程到至少一個節點上。當節點資源耗盡時,可能會發生這種情況。

當這種情況發生時,透過比較 kubectl get nodes 的輸出和以下命令的輸出,找出沒有排程 DaemonSet Pod 的節點

kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system

找到這些節點後,從節點刪除一些非 DaemonSet Pod,以便為新的 DaemonSet Pod 騰出空間。

損壞的推出

如果最近的 DaemonSet 範本更新已損壞,例如,容器崩潰迴圈,或容器映像不存在(通常是由於筆誤),則 DaemonSet 推出將不會進行。

若要修正此問題,請再次更新 DaemonSet 範本。新的推出將不會被先前不健康的推出所阻擋。

時鐘偏移

如果在 DaemonSet 中指定了 .spec.minReadySeconds,則 master 和節點之間的時鐘偏移會使 DaemonSet 無法偵測到正確的推出進度。

清理

從命名空間刪除 DaemonSet

kubectl delete ds fluentd-elasticsearch -n kube-system

接下來是什麼

上次修改時間:2023 年 8 月 24 日下午 6:38 PST:Use code_sample shortcode instead of code shortcode (e8b136c3b3)