Azure Kubernetes Service (AKS)中的節點強化(預覽)

節點強化是 Linux 節點池的一項自願加入功能,當工作負載使節點承受 CPU、記憶體或磁碟壓力時,保護節點穩定性。 當你在叢集啟用節點強化時,AKS 會改變每個節點如何保留並對 Kubernetes 元件和主機服務的資源使用加以管控,以及當資源不足時 kubelet 如何驅逐 pod。

本文說明節點加固會帶來哪些改變,比較加固預設與標準 AKS 預設,並示範如何啟用、驗證、自訂及停用此功能。

Important

AKS 預覽功能以自助方式提供,並採選擇加入制。 預覽版本係依「現狀」及「可用情況」提供,且不適用於服務等級協定與有限保固。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:

節點硬化的好處

在忙碌或負載突增的節點上,工作負載可能會消耗 kubelet、容器執行時和主機服務所需的資源。 當這種情況發生時,節點可能會失去回應、回報 NotReady 狀態,或突然終止 pod。 節點硬化透過以下方式降低這些風險:

  • 強制保留: 預設情況下,AKS 僅使用 kube 保留值來計算排程器可分配給 pod 的容量。 透過使用 Node Hardening,kubelet 也透過 Linux 控制群組(cgroups)強制執行 kube 保留與系統保留容量。 kubelet 和 containerd 在專用的 kubereserved.slice cgroup 中運行,因此即使 pod 使節點資源飽和,它們仍保有其保留的 CPU 份額和記憶體。
  • 主機服務專用容量: 節點強化為主機作業系統服務新增系統保留分配,這些服務會在 system.slice 中執行。
  • 更多記憶體餘裕: 可用記憶體的硬性驅逐門檻會隨節點記憶體增加而調整,因此 kubelet 會在節點記憶體嚴重不足前先驅逐 pod。
  • 優雅驅逐: 軟性驅逐門檻讓 kubelet 能在記憶體或磁碟空間不足時,以終止寬限期優雅地驅逐 Pod。 硬性驅逐會立即終止 Pod,因此作為最後手段。
  • 隨 Pod 密度調整的保留: Kube 保留記憶體的計算會隨著每個節點最大 pod 數量增加而增加,這也考慮到了運行更多 pod 所帶來的 kubelet 和 containerd 開銷。

啟用節點硬化後會有什麼變化

以下表格比較了運行 Kubernetes 1.29 或更新版本的 Linux 節點標準預設值,與啟用節點強化時 AKS 所適用的預設值。

資源保留

Setting 沒有 Node Hardening 使用節點強化
Kube 保留 CPU 根據 CPU 核心數量來決定。 欲了解更多資訊,請參閱 CPU 保留量。 未變更
Kube 保留記憶體 min(20 × maxPods + 50, 25% of node memory) MiB min(35 × maxPods + max(250, 2% of node memory), 25% of node memory) MiB
Kube 保留程序識別碼(PIDs) 1000 非保留
系統保留 CPU None 100m
系統保留記憶體 None 200 MiB,加上每滿 32 GiB 的節點記憶體,再加上 100 MiB;使用 Azure CNI 的叢集,再加上 100 MiB
系統保留的臨時儲存 None 1Gi

淘汰門檻

Setting 未使用 Node Hardening 使用節點強化
強制驅逐: memory.available 100Mi 250Mi 記憶體為 8 GiB 或以下的節點,375Mi 對超過 8 GiB 且少於 32 GiB 的節點,以及 512Mi 對於 32 GiB 或以上的節點
強行驅逐: nodefs.available 以及 nodefs.inodesFree 10% 與 5% 未變更
強制清除: pid.available 2000 未設定
軟性淘汰: memory.available None 500Mi、750Mi 或 1Gi,使用與硬逐出相同的節點記憶體層級,並有 30 秒寬限期
軟性移出: nodefs.available 以及 nodefs.inodesFree None 12% 以及 7%,每個都有2分鐘的寬限期
軟驅逐期間 Pod 終止的最大寬限期 未設定 60 秒鐘

Cgroup 強制實施

Setting 未啟用 Node Hardening 使用節點強化
強制執行節點可配置資源 pods pods、kube-reserved 和 system-reserved
Kubelet 與 containerd cgroup system.slice,無限制 kubereserved.slice,記憶體限制於 kube 保留記憶體,CPU 份額與 kube 保留 CPU 成比例
主機服務 cgroup system.slice,無限制 system.slice,記憶體限制於系統保留記憶體,CPU 配額與系統保留 CPU 成比例

由於節點硬化保留更多容量,節點報告的可分配給 Pod 的容量較少。 例如,在一個具備 4 個 vCPU 和 16 GiB 記憶體且使用 Azure CNI 的節點上,啟用節點硬化會降低可分配容量,具體如下:

  • 在預設每節點最多 250 個 pod 的情況下,約需 570 MiB 記憶體、100 毫核心 CPU 和 1 GiB 的臨時儲存空間。
  • 每個節點最多可容納 30 個 pod,約需 1.3 GiB 記憶體、100 毫核心 CPU 及 1 GiB 臨時儲存空間。

軟性驅逐門檻不會降低可分配容量。 只有當 kubelet 開始驅逐 Pod 時,才會改變。

Considerations

在啟用節點硬化前,請考慮以下幾點:

  • 你可以在叢集層級啟用節點強化,並且它適用於叢集中所有 Linux 節點池。 你無法對個別節點池啟用它,也不會影響 Windows 的節點池。
  • 節點報告的可分配容量較少,所以在啟用節點硬化前能裝在節點上的 pod 可能在啟用後就無法容納。 檢視你的 Pod 資源請求和節點池大小。
  • 在 system.slice 中的主機服務共享一個等於系統預留記憶體的硬記憶體上限。 如果你在節點上以 systemd 服務(如安全、監控或日誌轉發代理)運行自己的代理,這些代理都會被計入此限制。 在正式環境使用 Node Hardening 前,先驗證它們的記憶體用量和穩定性。
  • 你在節點池自訂 kubelet 設定的值會覆蓋相應的節點硬化預設值。 欲了解更多資訊,請參閱 自訂節點硬化設定。
  • 如果你後續關閉節點強化,現有節點池即使節點被重新映像化,仍會保留強化的軟驅逐設定。 要移除這些設定,你需要建立新的節點池。 更多資訊請參見「停用節點硬化」。
  • 預設值在功能預覽期間可能會改變。 從非生產叢集開始,並在具代表性的節點壓力條件下驗證你的工作負載。

Prerequisites

  • Azure 訂用帳戶。 如果您沒有帳戶,請建立 免費帳戶。
  • 具有 Linux 節點集區的 AKS 叢集,或具備建立叢集的權限。
  • aks-preview Azure CLI 擴充功能與CustomNodeConfigPreview功能標誌,詳見以下章節。

安裝 aks-preview Azure CLI 擴充功能

  1. 請使用 aks-preview 指令安裝 az extension add 擴充功能。

    az extension add --name aks-preview
    
  2. 請使用 az extension update 指令更新到擴充功能最新版本。

    az extension update --name aks-preview
    

註冊 CustomNodeConfigPreview 功能旗標

  1. 使用CustomNodeConfigPreview指令註冊az feature register功能標誌。

    az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    

    狀態需要幾分鐘的時間才會顯示「已註冊」。

  2. 請使用指令 az feature show 確認註冊狀態。

    az feature show --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    
  3. 當狀態顯示為 已註冊 時,請使用 命令重新整理 az provider register 資源提供者的註冊。

    az provider register --namespace "Microsoft.ContainerService"
    

啟用節點硬化

預覽期間,節點硬化預設未啟用。

在新叢集上啟用節點加固

使用帶有 az aks create 參數的 --enable-node-hardening 指令建立已啟用節點硬化的叢集。

此指令需要 aks-preview 擴充功能和 CustomNodeConfigPreview 功能旗標。 如需詳細資訊,請參閱必要條件。

az aks create \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening \
    --generate-ssh-keys

要確認變更,請參閱 「驗證節點硬化設定」。

在現有叢集上啟用節點強化

透過使用 --enable-node-hardening 指令搭配 az aks update 參數,在現有叢集上啟用節點強化。

此指令需要 aks-preview 擴充功能與 CustomNodeConfigPreview 功能旗標。 如需詳細資訊,請參閱必要條件。

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening

要確認變更,請參閱 「驗證節點硬化設定」。

驗證節點硬化設定

  1. 用指令 az aks get-credentials 取得叢集的認證資料。

    az aks get-credentials --resource-group <resource-group-name> --name <cluster-name>
    
  2. 透過查詢 kubelet 設定端點,檢視節點上的有效 kubelet 預留與驅逐設定。

    kubectl get --raw "/api/v1/nodes/<node-name>/proxy/configz" | jq '.kubeletconfig | {kubeReserved, systemReserved, evictionHard, evictionSoft, evictionSoftGracePeriod, evictionMaxPodGracePeriod, enforceNodeAllocatable}'
    

    在硬化節點上,systemReserved 和 evictionSoft 包含值,而 enforceNodeAllocatable 包含 kube-reserved 和 system-reserved。

  3. 比較節點的總資源量與可分配資源。

    kubectl get node <node-name> -o jsonpath='{.status.capacity}{"\n"}{.status.allocatable}{"\n"}'
    

    在強化節點上,可分配的 CPU、記憶體和臨時儲存空間皆低於其容量。 這個差值等於 資源保留中的 kube 保留值和系統保留值,加上 驅逐閾值中的硬性驅逐閾值。 例如,在一個使用 Azure CNI 的節點上,擁有 4 顆 vCPU 和 16 GiB 記憶體,可分配的 CPU 比容量低 240 毫核心:分別為 140 毫核心的 kube 保留 CPU 和 100 毫核心的系統保留 CPU。

自訂節點硬化設定

你可以透過 自訂 kubelet 設定來覆寫 Linux 節點池的 kube 保留和驅逐預設值。 這些設定需要使用 CustomNodeConfigPreview 功能旗標。 不管叢集上是否啟用節點強化,你都可以使用它們。 AKS 管理系統保留值和 cgroup 強制執行,您無法自訂它們。

每個設定都會覆寫 資源保留 或 驅逐閾值 表格中的一列。 Kube 保留列對應於 kubeReserved 設定。 硬性驅逐資料列對應 hardEvictionThreshold 設定。 軟淘汰列對應於 softEvictionThreshold 和 softEvictionGracePeriod 設定。 最大 pod 終止寬限期對應於 evictionMaxPodGracePeriodInSeconds。

您可以設定下列設定:

Setting Overrides Description
kubeReserved.cpuMillicores Kube 保留 CPU CPU 保留給 Kubernetes 系統守護程序,以毫核心計算。
kubeReserved.memoryMB Kube 保留記憶體 記憶體保留給 Kubernetes 系統守護程序,在 MiB 中。
hardEvictionThreshold.memoryAvailable 強制驅逐: memory.available 可用記憶體的硬性驅離門檻。
hardEvictionThreshold.nodeFsAvailable 強制清除: nodefs.available 可用節點檔案系統空間的硬性驅逐閾值。
hardEvictionThreshold.nodeFsInodesFree 強制驅逐: nodefs.inodesFree 節點檔案系統可用 inode 的硬性驅逐門檻。
softEvictionThreshold.memoryAvailable 軟性淘汰: memory.available 可用記憶體的軟性淘汰門檻。
softEvictionThreshold.nodeFsAvailable 軟性逐出: nodefs.available 可用節點檔案系統空間的軟性驅逐門檻。
softEvictionThreshold.nodeFsInodesFree 軟性淘汰: nodefs.inodesFree 節點檔案系統可用 inode 的軟性驅逐門檻。
softEvictionGracePeriod.memoryAvailable 軟性驅離: memory.available 寬限期 可用記憶體必須維持在軟閾值以下多久,kubelet 才會驅逐 Pod。
softEvictionGracePeriod.nodeFsAvailable 軟性淘汰: nodefs.available 寬限期 可用節點檔案系統空間必須維持在軟閾值以下多久,Kubelet 會驅逐 Pod。
softEvictionGracePeriod.nodeFsInodesFree 軟性驅離: nodefs.inodesFree 寬限期 節點檔案系統可用 inode 必須維持在軟閾值以下多久,Kubelet 才會驅逐 pods。
evictionMaxPodGracePeriodInSeconds 軟性驅逐期間 Pod 終止的最大寬限期 kubelet 允許 pod 在軟淘汰期間終止的最大秒數。
  • 關於每個設定的允許值、最小值及驗證規則,請參見 AKS 的自訂節點設定參數。
  • 對於每個驅逐訊號,設定軟驅逐門檻及其對應的寬限期,並確保每個軟驅逐門檻高於同一訊號的硬驅逐門檻。
  1. 建立一個 kubelet 設定檔,例如 nodehardening-kubelet.json,裡面有你想自訂的設定。 以下範例設定了所有可配置的值。 它將 kube-reserved 保留為 200 毫核心 CPU 與 1,024 MiB 記憶體。 它設定了 10% 可用記憶體、5% 可用檔案系統空間及 512Mi 空閒 inode 的硬性驅逐門檻。 它設定軟性驅逐門檻為 1Gi、12% 和 7%,寬限期為 30 秒、2 分鐘和 2 分鐘。 同時也設定了最多 60 秒的 Pod 終止寬限時間。

    {
      "kubeReserved": {
        "cpuMillicores": 200,
        "memoryMB": 1024
      },
      "hardEvictionThreshold": {
        "memoryAvailable": "512Mi",
        "nodeFsAvailable": "10%",
        "nodeFsInodesFree": "5%"
      },
      "softEvictionThreshold": {
        "memoryAvailable": "1Gi",
        "nodeFsAvailable": "12%",
        "nodeFsInodesFree": "7%"
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "30s",
        "nodeFsAvailable": "2m",
        "nodeFsInodesFree": "2m"
      },
      "evictionMaxPodGracePeriodInSeconds": 60
    }
    
  2. 建立一個 Linux 節點池,使用 az aks nodepool add 參數的 --kubelet-config 命令來使用設定檔。

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./nodehardening-kubelet.json
    

    你也可以用 --kubelet-config 這個參數搭配指令 az aks create ,將設定套用到叢集的初始節點池。

停用節點硬化

使用帶有az aks update參數的--disable-node-hardening指令來停用節點硬化。

此指令需要 aks-preview 擴充功能和 CustomNodeConfigPreview 功能旗標。 如需詳細資訊,請參閱必要條件。

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --disable-node-hardening

停用 Node Hardening 會關閉叢集層級設定,但不會立即改變現有節點。 現有節點會保留所有強化設定,直到重新映像化,例如節點映像升級時。 節點重新建立映像後,會發生以下變更:

  • 恢復為標準 AKS 預設值: Kube 保留和系統保留資源、硬性逐出門檻,以及 cgroup 強制執行。 節點的可分配容量相應增加。
  • 保留: 軟性驅逐門檻、軟性驅逐寬限期,以及軟性驅逐期間 pod 終止的最大寬限期。

你只能在建立叢集或節點池時設定自訂 Kubelet 配置,因此無法移除現有節點池中保留的軟驅逐設定。 要移除這些項目,請建立一個明確取消設定這些項目的新節點池,將你的工作負載移到新的節點池,然後刪除舊的節點池。

  1. 建立一個 kubelet 設定檔,例如 remove-soft-eviction.json。 以下範例將每個軟驅逐閾值和寬限期設為空串,從而關閉該訊號的軟驅逐。 它也會將最大 pod 終止寬限期設為 0,這是標準 AKS 預設值。

    {
      "softEvictionThreshold": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "evictionMaxPodGracePeriodInSeconds": 0
    }
    
  2. 建立一個 Linux 節點池,使用帶有 az aks nodepool add 參數的 --kubelet-config 指令來使用設定檔。

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./remove-soft-eviction.json
    
  3. 先把工作負載移到新的節點池,然後刪除舊的節點池。 欲了解更多資訊,請參閱 調整 AKS 中節點集區的大小。

要確認節點設定,請參閱「驗證節點硬化設定」。 在新節點池中的節點上,evictionSoft 是空的。