本文說明如何設定 Azure Kubernetes Service (AKS) 節點自動布建 (NAP) 節點的節點中斷原則,並詳細說明中斷如何優化資源使用率和成本效率。
NAP 會透過下列方式最佳化叢集:
- 移除或取代未充分利用的節點。
- 整合工作負載以降低成本。
- 尊重中斷預算和維護時段。
- 在需要時提供手動控制。
開始之前
- 請閱讀 AKS 中的節點自動布建 (NAP) 概觀 一文,其中詳細說明 NAP 的運作方式。
- 閱讀 Azure Kubernetes Service (AKS) 中節點自動布建 (NAP) 的網路設定概觀。
NAP 節點的中斷機制如何運作?
Karpenter 會在每個節點及其佈建的節點宣告上設定 Kubernetes 完成項。 完成項會阻止刪除節點物件,而終止控制器會在移除基礎節點宣告之前污染並清空節點。
當節點上的工作負載縮減時,NAP 會使用節點集區規格上的中斷規則來決定何時以及如何移除這些節點,並可能重新排程工作負載以提高效率。
節點中斷方法
NAP 會自動發現符合中斷條件的節點,並在需要時啟動替換節點。 您可以透過 到期、 合併和 漂移等自動化方法、手動方法或外部系統來觸發中斷。
Expiration
到期可讓您設定 NAP 節點的存留期上限。 節點會在達到您為節點集區 spec.disruption.expireAfter 值指定的存留期後標示為過期且中斷。
到期設定範例
下列範例示範如何將 NAP 節點的到期時間設定為 24 小時:
spec:
disruption:
expireAfter: 24h # Expire nodes after 24 hours
Consolidation
NAP 致力於透過識別何時可以刪除節點,因為它們是空的或未充分利用的,或者何時可以將節點替換為價格較低的變體,從而主動降低叢集成本。 此過程稱為 合併。 NAP 主要使用合併來刪除或取代節點,以達到最佳的 Pod 放置位置。
NAP 會執行下列類型的合併,以最佳化資源使用率:
- 空白節點合併:平行刪除任何空白節點。
- 多節點合併:刪除多個節點,可能會啟動單一替換。
- 單一節點合併:刪除任何單一節點、可能會啟動替換節點。
您可以透過節點儲存區規格中的spec.disruption.consolidationPolicy欄位,使用WhenEmpty或WhenEmptyOrUnderUtilized設定來觸發合併。 您也可以設定欄位 consolidateAfter ,這是一個以時間為基礎的條件,用於決定 NAP 在發現合併機會後等待多長時間,然後才中斷節點。
合併組態範例
下列範例示範如何設定 NAP 以在節點空白時合併節點,並在探索合併機會之後等待 30 秒,然後再中斷節點:
disruption:
# Describes which types of nodes NAP should consider for consolidation
# `WhenEmptyOrUnderUtilized`: NAP considers all nodes for consolidation and attempts to remove or replace nodes when it discovers that the node is empty or underutilized and could be changed to reduce cost
# `WhenEmpty`: NAP only considers nodes for consolidation that don't contain any workload pods
consolidationPolicy: WhenEmpty
# The amount of time NAP should wait after discovering a consolidation decision
# Currently, you can only set this value when the consolidation policy is `WhenEmpty`
# You can choose to disable consolidation entirely by setting the string value `Never`
consolidateAfter: 30s
Drift
漂移會處理 NodePool/AKSNodeClass 資源的變更。 中的 NodeClaimTemplateSpec/AKSNodeClassSpec 值會以與設定相同的方式反映。 如果相關聯 NodePool/AKSNodeClass 中的值不符合 NodeClaim 中的值,NodeClaim 會被偵測為「已漂移」。 類似於對 Pod 的上游 deployment.spec.template 關聯性,Karpenter 會以 NodeClaimTemplateSpec 的雜湊來註釋相關聯的 NodePool/AKSNodeClass 以檢查漂移。 Karpenter 會在下列案例中移除 Drifted 狀態條件:
-
Drift功能閘道並未啟用,但NodeClaim已漂移。 -
NodeClaim未漂移,但有狀態條件。
Karpenter 或雲端提供者介面可能會發現
漂移的特殊情況
在特殊情況下,漂移可以對應至多個值,而且必須以不同的方式處理。 已解析的欄位上的漂移可能形成一種情況,即使自訂資源定義(CRD)沒有變更,漂移仍然會發生,或者 CRD 的變更不會導致漂移。
例如,如果一個NodeClaim具有node.kubernetes.io/instance-type: Standard_D2s_v3,且需求從node.kubernetes.io/instance-type In [Standard_D2s_v3]變更為node.kubernetes.io/instance-type In [Standard_D2s_v3, Standard_D4s_v3],那麼NodeClaim不會漂移,因為其值仍與新需求相容。 相反地,如果 NodeClaim 使用 NodeClaimimageFamily,但 spec.imageFamily 欄位有所變更,Karpenter 會將 NodeClaim 偵測為「已漂移」 並輪替節點,以符合該規格。
這很重要
Karpenter 會監視子網路配置變更,並在 vnetSubnetID中的AKSNodeClass被修改時檢測偏移。 在管理自訂網路設定時,了解此行為至關重要。 如需詳細資訊,請參閱 子網路漂移行為。
如需詳細資訊,請參閱 Drift Design。
終止寬限期
您可以使用節點集區規格中的欄位 spec.template.spec.terminationGracePeriod 來設定 NAP 節點的終止寬限期。 此設定可讓您設定 Karpenter 等待 Pod 正常終止的時間長度。 此設定會優先於 Pod 的 terminationGracePeriodSeconds,並會略過 PodDisruptionBudgets 和 karpenter.sh/do-not-disrupt 註解。
終止寬限期設定範例
下列範例示範如何將 NAP 節點的終止寬限期設定為 30 秒:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
terminationGracePeriod: 30s
中斷預算
您可以修改 spec.disruption.budgets 節點集區規格中的欄位,以限制 Karpenter 的中斷速率。 如果您未定義此設定,Karpenter 會預設為一個預算 nodes: 10%。 預算會考慮因任何原因被刪除的節點,它們只會阻止 Karpenter 透過屆滿、漂移、空虛和新設合併自願中斷。
在計算預算是否阻止節點中斷時,Karpenter 會計算節點池中的節點總數,然後減去正在刪除的節點和NotReady的節點。 如果預算配置了百分比值 (例如 20%),則 Karpenter 會將允許的中斷次數計算為 allowed_disruptions = roundup(total * percentage) - total_deleting - total_notready。 對於節點集區中的多個預算,Karpenter 會採用每個預算的最小值 (最嚴格)。
排程和持續時間欄位
使用預算時,您可以選擇設定 schedule 和 duration 欄位以建立基於時間的預算。 這些欄位可讓您定義維護時段或中斷限制更嚴格的特定時間範圍。
-
Schedule 使用 cron 作業語法搭配特殊巨集,例如
@yearly、@monthly、@weekly、@daily、@hourly。 -
Duration 支援複合持續時間,例如
10h5m、30m或160h。 持續時間和排程必須一起定義。
時間表和持續時間範例
維護時間框架預算
防止工作時間中斷:
budgets:
- nodes: "0"
schedule: "0 9 * * 1-5" # 9 AM Monday-Friday
duration: 8h # For 8 hours
僅在週末發生的中斷
只允許在週末發生中斷。
budgets:
- nodes: "50%"
schedule: "0 0 * * 6" # Saturday midnight
duration: 48h # All weekend
- nodes: "0" # Block all other times
漸進式推出預算
允許提高中斷率:
budgets:
- nodes: "1"
schedule: "0 2 * * *" # 2 AM daily
duration: 2h
- nodes: "3"
schedule: "0 4 * * *" # 4 AM daily
duration: 4h
預算組態範例
下列 NodePool 規格已設定三個預算:
- 第一個預算允許節點集區擁有的 20% 節點要立刻中斷。
- 第二個預算充當上限,當節點超過 25 個時,只允許 5 次中斷。
- 最後預算在每天的前 10 分鐘內防止干擾。
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
expireAfter: 720h # 30 * 24h = 720h
budgets:
- nodes: "20%" # Allow 20% of nodes to be disrupted
- nodes: "5" # Cap at maximum 5 nodes
- nodes: "0" # Block all disruptions during maintenance window
schedule: "@daily" # Scheduled daily
duration: 10m # Duration of 10 minutes
手動節點中斷
您可以使用kubectl或刪除NodePool資源來手動中斷 NAP 節點。
使用 kubectl 移除節點
您可以使用命令 kubectl delete node 手動移除節點。 您可以使用標籤刪除特定節點、所有 NAP 受控節點或特定節點集區中的節點,例如:
# Delete a specific node
kubectl delete node $NODE_NAME
# Delete all NAP-managed nodes
kubectl delete nodes -l karpenter.sh/nodepool
# Delete nodes from a specific nodepool
kubectl delete nodes -l karpenter.sh/nodepool=$NODEPOOL_NAME
刪除 NodePool 資源
NodePool 透過擁有者推薦而擁有 NodeClaims。 當您刪除相關聯的 NodePool 時,NAP 會透過串聯刪除來正常終止節點。
使用註釋控制中斷
您可以使用註釋來阻止或停用特定 Pod、節點或整個節點集區的中斷。
Pod 控制項
藉由設定 karpenter.sh/do-not-disrupt: "true" 註釋,阻止 NAP 中斷特定 Pod:
apiVersion: apps/v1
kind: Deployment
spec:
template:
metadata:
annotations:
karpenter.sh/do-not-disrupt: "true"
此標註可防止到期、合併和漂移的自發性中斷。 不過,這不會防止從外部系統中短或透過 kubectl 或 NodePool 刪除手動中斷。
節點控制項
防止 NAP 中斷特定節點的運作:
apiVersion: v1
kind: Node
metadata:
annotations:
karpenter.sh/do-not-disrupt: "true"
節點集區控制項
停用 NodePool 中所有節點的中斷:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
metadata:
annotations:
karpenter.sh/do-not-disrupt: "true"
後續步驟
如需 AKS 中節點自動布建的詳細資訊,請參閱下列文章: