讓節點進入維護模式

需要維修或維護節點時,請先將節點設為維護模式。這會正常排空現有 Pod 和工作負載,但不包括 API 伺服器等重要系統 Pod。維護模式也會禁止節點接收新的 Pod 指派作業。在維護模式下,您可以處理節點,而且不會有 Pod 流量中斷的風險。

運作方式

Google Distributed Cloud 提供將節點設為維護模式的方法。這種做法可讓其他叢集元件正確得知節點處於維護模式。將節點設為維護模式後,系統就無法在該節點上排定其他 Pod,現有 Pod 也會停止運作。

您可以在特定節點上使用 kubectl cordonkubectl drain 等 Kubernetes 指令,而不必使用維護模式。

使用維護模式程序時,Google Distributed Cloud 會執行下列操作:

1.29

  • Google Distributed Cloud 會在指定節點中新增baremetal.cluster.gke.io/maintenance:NoSchedule 污點,防止在節點上排程新的 Pod。

  • Google Distributed Cloud 會使用驅逐 API 驅逐每個 Pod。這種排空節點的方法會遵守 Pod 中斷預算 (PDB)。您可以設定 PDB,方法是使用 minAvailablemaxUnavailable 欄位,為一組 Pod 指定可容許的干擾程度,藉此保護工作負載。以這種方式排空節點,可更有效地防範工作負載中斷。以節點排空為基礎的節點排空功能已在 1.29 版正式推出。

  • 系統會強制執行 20 分鐘的逾時設定,確保節點不會因等待 Pod 停止而停滯。如果 Pod 設定為容許所有汙點,或具有終止程式,可能就不會停止。Google Distributed Cloud 會嘗試停止所有 Pod,但如果超過逾時時間,節點就會進入維護模式。這個逾時時間可避免執行中的 Pod 阻礙升級。

1.28 以下版本

  • Google Distributed Cloud 會在指定節點中新增baremetal.cluster.gke.io/maintenance:NoSchedule 污點,防止在節點上排程新的 Pod。

  • Google Distributed Cloud 會新增 baremetal.cluster.gke.io/maintenance:NoExecute 汙點。Google Distributed Cloud kube-scheduler 會根據NoExecute污點停止 Pod,並排空節點。這種排空節點的方法不會遵守 PDB。

  • 系統會強制執行 20 分鐘的逾時設定,確保節點不會因等待 Pod 停止而停滯。如果 Pod 設定為容許所有汙點,或有終止程式,可能就不會停止。Google Distributed Cloud 會嘗試停止所有 Pod,但如果超過逾時時間,節點就會進入維護模式。這個逾時時間可避免執行中的 Pod 阻礙升級。

以驅逐為基礎的排空

從以汙點為基礎的節點排空切換為以驅逐為基礎的節點排空時,程序不會有任何異動。這項切換只會影響對帳邏輯。

這項功能在所有支援版本中的推出階段不盡相同:

  • 1.29:正式版
  • 1.28:不適用
  • 1.16:不適用

排除順序

在 1.29 版之前,Google Distributed Cloud kube-scheduler 執行的節點排空作業 (以汙點為依據) 並未採用特定演算法,從節點排空 Pod。如果節點排空作業是根據 Pod 逐出機制進行,系統會依據優先順序,以特定順序逐出 Pod。如以下表格所示,驅逐優先順序與特定 Pod 條件相關聯:

排除順序 Pod 條件 (必須符合所有條件) 和
1

系統會逐出符合下列條件的 Pod:

  • 沒有 spec.prorityClassName 的 Pod
  • 不符合任何已知容器儲存介面 (CSI) 名稱的 Pod
  • 不屬於 DaemonSet 的 Pod
2

系統會逐出符合下列條件的 Pod:

  • 屬於 DaemonSet 的 Pod
  • Pod 不含 PriorityClass
  • 不符合任何已知容器儲存介面 (CSI) 名稱的 Pod
3

系統會逐出符合下列條件的 Pod:

  • Pod,搭配 Spec.ProrityClassName
  • 不符合任何已知容器儲存介面 (CSI) 名稱的 Pod

系統會根據相符 Pod 的優先順序 (由低至高) 逐一驅逐。PriorityClass.value

4

等待 CSI 在所有 Pod 遭逐出後,清除 PV/PVC 掛接點。使用 Node.Status.VolumesInUse 表示所有磁碟區都已清除。

5

系統會逐出符合下列條件的 Pod:

  • 符合已知 Container Storage 介面 (CSI) 名稱的 Pod

這些 Pod 仍需排空,因為 kubelet 不提供就地升級相容性。

由於以驅逐為基礎的節點排空作業會遵守 PDB,因此在某些情況下,PDB 設定可能會封鎖節點排空作業。如需節點集區排空的疑難排解資訊,請參閱「檢查節點長時間處於排空狀態的原因」。

停用以驅逐為依據的節點排除功能

對於子版本為 1.29 以上的叢集,或升級至子版本 1.29 以上的叢集,系統預設會啟用以排空為基礎的節點排空功能。如果叢集升級或維護作業因節點排空 (以節點排空為準) 而發生問題,您可以將 baremetal.cluster.gke.io/maintenance-mode-ignore-pdb: "" 註解新增至叢集資源,改用以汙染為準的節點排空作業。

如要還原預設的節點排空行為 (以節點排空為準),請徹底移除註解。將註解設為 false 不會重新啟用預設行為。

讓節點進入維護模式

在叢集設定檔的 maintenanceBlocks 下方,為所選節點指定 IP 範圍,選擇要進入維護模式的節點。所選節點必須處於就緒狀態,且在叢集中運作。

如要讓節點進入維護模式,請按照下列步驟操作:

  1. 編輯叢集設定檔,選取要進入維護模式的節點。

    您可以使用所選的編輯器編輯設定檔,也可以執行下列指令,直接編輯叢集自訂資源:

    kubectl -n CLUSTER_NAMESPACE edit cluster CLUSTER_NAME

    更改下列內容:

    • CLUSTER_NAMESPACE:叢集的命名空間。
    • CLUSTER_NAME:叢集名稱。
  2. maintenanceBlocks 區段新增至叢集設定檔,為要進入維護模式的節點指定單一 IP 位址或位址範圍。

    下列範例說明如何指定 IP 位址範圍,選取多個節點:

    metadata:
      name: my-cluster
      namespace: cluster-my-cluster
    spec:
      maintenanceBlocks:
        cidrBlocks:
        - 172.16.128.1-172.16.128.64
    
  3. 儲存並套用更新後的叢集設定。

    Google Distributed Cloud 開始讓節點進入維護模式。

  4. 執行下列指令,取得叢集中節點的狀態:

    kubectl get nodes --kubeconfig=KUBECONFIG

    輸出結果會與下列內容相似:

    NAME                STATUS   ROLES           AGE     VERSION
    user-baremetal-01   Ready    control-plane   2d22h   v1.27.4-gke.1600
    user-baremetal-04   Ready    worker          2d22h   v1.27.4-gke.1600
    user-baremetal-05   Ready    worker          2d22h   v1.27.4-gke.1600
    user-baremetal-06   Ready    worker          2d22h   v1.27.4-gke.1600
    

    請注意,節點仍可排程,但 taint 會防止任何 Pod (沒有適當的容許條件) 排程到節點上。

  5. 執行下列指令,取得處於維護模式的節點數量:

    kubectl get nodepools --kubeconfig ADMIN_KUBECONFIG 
    

    回應內容應如下列範例所示:

    NAME   READY   RECONCILING   STALLED   UNDERMAINTENANCE   UNKNOWN
    np1    3       0             0         1                  0
    

    這個範例中的 UNDERMAINTENANCE 欄顯示一個節點處於維護模式。

    節點進入維護模式時,Google Distributed Cloud 也會在節點中新增下列汙點:

    • baremetal.cluster.gke.io/maintenance:NoExecute
    • baremetal.cluster.gke.io/maintenance:NoSchedule

將節點從維護模式中移除

如要移除維護模式的節點,請按照下列步驟操作:

  1. 編輯叢集設定檔,清除要從維護模式移除的節點。

    您可以使用所選的編輯器編輯設定檔,也可以執行下列指令,直接編輯叢集自訂資源:

    kubectl -n CLUSTER_NAMESPACE edit cluster CLUSTER_NAME

    更改下列內容:

    • CLUSTER_NAMESPACE:叢集的命名空間。
    • CLUSTER_NAME:叢集名稱。
  2. 您可以編輯 IP 位址,從維護模式中移除特定節點,也可以移除 maintenanceBlocks 區段,從維護模式中移除所有節點。

  3. 儲存並套用更新後的叢集設定。

  4. 使用 kubectl 指令檢查節點狀態。

關閉並重新啟動叢集

如有必要關閉整個叢集,請按照下列章節的操作說明,安全地關閉及重新啟動叢集。

關閉叢集

如果要關閉管理使用者叢集的叢集,請務必先關閉所有受管理的使用者叢集。下列操作說明適用於所有 Google Distributed Cloud 叢集類型。

  1. 檢查所有叢集節點的狀態:

    kubectl get nodes --kubeconfig CLUSTER_KUBECONFIG
    

    CLUSTER_KUBECONFIG 替換為叢集的 kubeconfig 檔案路徑。

    輸出結果會與下列內容相似:

    NAME        STATUS   ROLES           AGE    VERSION
    control-0   Ready    control-plane   202d   v1.27.4-gke.1600
    control-1   Ready    control-plane   202d   v1.27.4-gke.1600
    control-2   Ready    control-plane   202d   v1.27.4-gke.1600
    worker-0    Ready    worker          202d   v1.27.4-gke.1600
    worker-1    Ready    worker          202d   v1.27.4-gke.1600
    worker-2    Ready    worker          202d   v1.27.4-gke.1600
    worker-3    Ready    worker          202d   v1.27.4-gke.1600
    worker-4    Ready    worker          154d   v1.27.4-gke.1600
    worker-5    Ready    worker          154d   v1.27.4-gke.1600
    worker-6    Ready    worker          154d   v1.27.4-gke.1600
    worker-7    Ready    worker          154d   v1.27.4-gke.1600
    worker-8    Ready    worker          154d   v1.27.4-gke.1600
    worker-9    Ready    worker          154d   v1.27.4-gke.1600
    

    如果節點的 STATUS 不是 Ready,強烈建議您排解節點問題,並在所有節點都為 Ready 時再繼續操作。

  2. 如果要關閉使用者叢集,請檢查管理員叢集節點的狀態:

    kubectl get nodes --kubeconfig ADMIN_KUBECONFIG
    

    ADMIN_KUBECONFIG 替換為管理叢集的 kubeconfig 檔案路徑。

    後續步驟會依附於管理員叢集。如果節點的 STATUS 不是 Ready,強烈建議您排解節點問題,並在所有節點都為 Ready 時再繼續操作。

  3. 檢查要關閉的叢集健康狀態:

    bmctl check cluster -c CLUSTER_NAME --kubeconfig ADMIN_KUBECONFIG
    

    更改下列內容:

    • CLUSTER_NAME:要檢查的叢集名稱。

    • ADMIN_KUBECONFIG:管理叢集的 kubeconfig 檔案路徑。

    請先修正所有回報的問題,再繼續操作。

  4. 確認要關閉的叢集已執行所有 etcd Pod:

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG -A \
        -l component=etcd
    

    CLUSTER_KUBECONFIG 替換為叢集的 kubeconfig 檔案路徑。

    輸出結果會與下列內容相似:

    NAMESPACE     NAME                   READY   STATUS    RESTARTS   AGE
    kube-system   etcd-control-0-admin   1/1     Running   0          2d22h
    kube-system   etcd-control-1-admin   1/1     Running   0          2d22h
    kube-system   etcd-control-2-admin   1/1     Running   0          2d22h
    

    如果 Pod 的 STATUS 不是 Running,強烈建議您排解 Pod 的問題,並在所有 Pod 都是 Running 時再繼續。

  5. 按照「備份叢集」一文的說明執行備份。

    關閉叢集前,請務必先備份 etcd,這樣在重新啟動叢集時遇到任何問題,都能還原叢集。Etcd 損毀、節點硬體故障、網路連線問題,以及其他可能狀況,都可能導致叢集無法正常重新啟動。

  6. 如果要關閉含有工作站節點的叢集,請將工作站節點設為維護模式

    這個步驟可盡量減少寫入 etcd 的資料量,降低叢集重新啟動時需要大量協調 etcd 寫入作業的可能性。

  7. 將控制層節點設為維護模式

    這個步驟可避免節點關機期間,有狀態工作負載的寫入作業損毀。

  8. 依下列順序關閉叢集節點電源:

    1. 工作站節點
    2. 控制層負載平衡器節點
    3. 控制層節點,從 etcd follower 開始,到 etcd leader 結束

      如果您有高可用性 (HA) 叢集,可以透過 SSH 連線至每個控制平面節點,並執行下列 etcdctl 指令,找出 etcd 領導者:

      ETCDCTL_API=3 etcdctl \
          --cacert /etc/kubernetes/pki/etcd/ca.crt \
          --cert /etc/kubernetes/pki/etcd/server.crt \
          --key /etc/kubernetes/pki/etcd/server.key \
          --write-out=table endpoint status
      

      回應會包含 IS LEADER 欄,如果節點是 etcd 領導者,則會傳回 true

此時,叢集已完全關閉。完成所有必要維護作業後,即可按照下一節的說明重新啟動叢集。

重新啟動叢集

請按照下列步驟重新啟動已完全關閉的叢集。

  1. 關機順序的相反順序開啟節點電腦。

  2. 從維護模式移除控制層節點。

    如需操作說明,請參閱「從維護模式移除節點」。

  3. 從維護模式移除工作站節點。

  4. 執行叢集健康狀態檢查,確保叢集運作正常:

    bmctl check cluster -c CLUSTER_NAME --kubeconfig ADMIN_KUBECONFIG
    
  5. 如果叢集無法正常重新啟動 (例如 etcd 發生當機迴圈),請嘗試從最新的已知良好備份還原叢集。如需操作說明,請參閱「還原叢集」。

帳單與維護模式

Google Distributed Cloud 的計費方式,是根據叢集內可執行工作負載的節點所擁有的 vCPU 數量。將節點設為維護模式時,系統會將 NoExecuteNoSchedule 汙點新增至節點,但不會停用帳單。將節點設為維護模式後,請限制節點 (kubectl cordon NODE_NAME),將其標示為不可排程。節點標示為不可排程後,系統就不會針對該節點和相關聯的 vCPU 收費。

定價頁面所述,您可以使用 kubectl 查看每個使用者叢集的 vCPU 負荷能力 (用於計費)。這項指令不會考量節點是否可排程,只會提供每個節點的 vCPU 數量。

如要判斷使用者叢集每個節點的 vCPU 數量,請按照下列步驟操作:

kubectl get nodes \
    --kubeconfig USER_KUBECONFIG \
    -o=jsonpath="{range .items[*]}{.metadata.name}{\"\t\"} \
    {.status.capacity.cpu}{\"\n\"}{end}"

請將 USER_KUBECONFIG 替換為使用者叢集的 kubeconfig 檔案路徑。