節點

Kubernetes 透過將容器放入 Pod 中以在節點上執行,來執行您的 工作負載。節點可以是虛擬或實體機器,取決於叢集。每個節點都由 控制平面 管理,並包含執行 Pod 所需的服務。

通常,叢集中有多個節點;在學習或資源受限的環境中,您可能只有一個節點。

節點上的 元件 包括 kubelet容器執行期,以及 kube-proxy

管理

將節點新增至 API 伺服器 主要有兩種方式

  1. 節點上的 kubelet 自行向控制平面註冊
  2. 您 (或其他人類使用者) 手動新增節點物件

在您建立節點 物件,或節點上的 kubelet 自行註冊後,控制平面會檢查新的節點物件是否有效。例如,如果您嘗試從以下 JSON 清單建立節點

{
  "kind": "Node",
  "apiVersion": "v1",
  "metadata": {
    "name": "10.240.79.157",
    "labels": {
      "name": "my-first-k8s-node"
    }
  }
}

Kubernetes 在內部建立節點物件 (表示法)。Kubernetes 檢查是否有 kubelet 向 API 伺服器註冊,且與節點的 metadata.name 欄位相符。如果節點健康 (即所有必要的服務都在執行中),則它有資格執行 Pod。否則,該節點將被叢集活動忽略,直到它變得健康。

節點物件的名稱必須是有效的 DNS 子網域名稱

節點名稱唯一性

名稱 識別節點。兩個節點不能同時具有相同的名稱。Kubernetes 也假設具有相同名稱的資源是相同的物件。在節點的情況下,隱含地假設使用相同名稱的執行個體將具有相同的狀態 (例如網路設定、根磁碟內容) 和屬性,例如節點標籤。如果執行個體在未變更其名稱的情況下被修改,則可能會導致不一致。如果節點需要大幅更換或更新,則需要先從 API 伺服器中移除現有的節點物件,並在更新後重新新增。

節點的自我註冊

當 kubelet 旗標 --register-node 為 true (預設值) 時,kubelet 將嘗試向 API 伺服器註冊自己。這是慣用的模式,大多數發行版都使用此模式。

對於自我註冊,kubelet 以以下選項啟動

  • --kubeconfig - 用於向 API 伺服器驗證自身身份的憑證路徑。

  • --cloud-provider - 如何與 雲端供應商 通訊以讀取關於自身的元資料。

  • --register-node - 自動向 API 伺服器註冊。

  • --register-with-taints - 使用給定的 污點 清單註冊節點 (逗號分隔 <key>=<value>:<effect>)。

    如果 register-node 為 false,則為 No-op。

  • --node-ip - 節點的選用逗號分隔 IP 位址清單。您只能為每個位址系列指定單一位址。例如,在單堆疊 IPv4 叢集中,您可以將此值設定為 kubelet 應為節點使用的 IPv4 位址。請參閱 設定 IPv4/IPv6 雙堆疊,以瞭解執行雙堆疊叢集的詳細資訊。

    如果您未提供此引數,kubelet 會使用節點的預設 IPv4 位址(如果有的話);如果節點沒有 IPv4 位址,則 kubelet 會使用節點的預設 IPv6 位址。

  • --node-labels - 標籤,用於在叢集中註冊節點時新增(請參閱 NodeRestriction 許可控制外掛程式 強制的標籤限制)。

  • --node-status-update-frequency - 指定 kubelet 將其節點狀態發佈到 API 伺服器的頻率。

當啟用節點授權模式NodeRestriction 許可控制外掛程式時,kubelet 僅被授權建立/修改它們自己的節點資源。

手動節點管理

您可以使用 kubectl 建立和修改節點物件。

當您想要手動建立節點物件時,請設定 kubelet 標記 --register-node=false

您可以修改節點物件,而無需考慮 --register-node 的設定。例如,您可以在現有的節點上設定標籤或將其標記為不可排程。

您可以結合節點上的標籤和 Pod 上的節點選取器來控制排程。例如,您可以限制 Pod 僅在可用節點的子集上執行。

將節點標記為不可排程可防止排程器將新的 Pod 放置到該節點上,但不會影響節點上現有的 Pod。這在節點重新啟動或其他維護之前的準備步驟中非常有用。

若要將節點標記為不可排程,請執行

kubectl cordon $NODENAME

請參閱 安全地排空節點 以取得更多詳細資訊。

節點狀態

節點的狀態包含以下資訊

您可以使用 kubectl 來檢視節點的狀態和其他詳細資訊

kubectl describe node <insert-node-name-here>

請參閱 節點狀態 以取得更多詳細資訊。

節點心跳訊號

由 Kubernetes 節點傳送的心跳訊號,可協助您的叢集判斷每個節點的可用性,並在偵測到故障時採取行動。

對於節點,有兩種形式的心跳訊號

  • 更新節點的 .status
  • 租約物件在 kube-node-lease 命名空間內。每個節點都有一個相關聯的租約物件。

節點控制器

節點控制器是 Kubernetes 控制平面元件,用於管理節點的各個方面。

節點控制器在節點的生命週期中有多個角色。第一個是在節點註冊時為節點指派 CIDR 區塊(如果已開啟 CIDR 指派)。

第二個是保持節點控制器的內部節點清單與雲端供應商的可用機器清單同步。當在雲端環境中執行且節點不健康時,節點控制器會詢問雲端供應商該節點的 VM 是否仍然可用。如果不可用,節點控制器會從其節點清單中刪除該節點。

第三個是監控節點的健康狀況。節點控制器負責

  • 在節點變得無法連線的情況下,更新節點 .status 欄位中的 Ready 狀況。在這種情況下,節點控制器將 Ready 狀況設定為 Unknown
  • 如果節點仍然無法連線:觸發無法連線節點上所有 Pod 的 API 起始的驅逐。預設情況下,節點控制器在將節點標記為 Unknown 和提交第一個驅逐請求之間等待 5 分鐘。

預設情況下,節點控制器每 5 秒檢查每個節點的狀態。可以使用 kube-controller-manager 元件上的 --node-monitor-period 標記來設定此期間。

驅逐的速率限制

在大多數情況下,節點控制器將驅逐速率限制為每秒 --node-eviction-rate(預設值為 0.1),這表示它每 10 秒不會從超過 1 個節點驅逐 Pod。

當給定可用性區域中的節點變得不健康時,節點驅逐行為會發生變化。節點控制器會檢查區域中同時不健康(Ready 狀況為 UnknownFalse)的節點百分比

  • 如果狀況不良節點的比例至少為 --unhealthy-zone-threshold(預設值為 0.55),則會降低驅逐速率。
  • 如果叢集很小(即擁有的節點小於或等於 --large-cluster-size-threshold 個節點 - 預設值為 50),則會停止驅逐。
  • 否則,驅逐速率會降低至每秒 --secondary-node-eviction-rate(預設值為 0.01)。

這些策略按可用性區域實作的原因是,一個可用性區域可能會與控制平面分割,而其他區域仍然連線。如果您的叢集沒有跨越多個雲端供應商可用性區域,則驅逐機制不會考慮每個區域的不可用性。

跨可用性區域分散節點的一個主要原因是,當一個完整區域關閉時,工作負載可以轉移到健康的區域。因此,如果一個區域中的所有節點都不健康,則節點控制器會以 --node-eviction-rate 的正常速率進行驅逐。極端情況是當所有區域都完全不健康時(叢集中沒有任何節點是健康的)。在這種情況下,節點控制器會假設控制平面與節點之間的連線存在問題,並且不執行任何驅逐。(如果發生中斷且某些節點重新出現,則節點控制器會從其餘不健康或無法連線的節點驅逐 Pod)。

節點控制器也負責驅逐在具有 NoExecute 污點的節點上執行的 Pod,除非這些 Pod 容許該污點。節點控制器也會新增與節點問題(例如節點無法連線或未就緒)對應的污點。這表示排程器不會將 Pod 放置在不健康的節點上。

資源容量追蹤

節點物件追蹤有關節點資源容量的資訊:例如,可用記憶體量和 CPU 數量。 自我註冊的節點會在註冊期間報告其容量。如果您手動新增節點,則需要在新增節點時設定節點的容量資訊。

Kubernetes 排程器確保節點上的所有 Pod 都有足夠的資源。排程器會檢查節點上容器的請求總和是否不大於節點的容量。請求總和包括 kubelet 管理的所有容器,但不包括容器執行階段直接啟動的任何容器,也不包括在 kubelet 控制之外執行的任何程序。

節點拓撲

功能狀態: Kubernetes v1.27 [stable](預設啟用:true)

如果您已啟用 TopologyManager 功能閘道,則 kubelet 可以在做出資源指派決策時使用拓撲提示。請參閱 控制節點上的拓撲管理策略 以取得更多資訊。

交換記憶體管理

功能狀態: Kubernetes v1.30 [beta](預設啟用:true)

若要在節點上啟用交換空間,必須在 kubelet 上啟用 NodeSwap 功能閘道(預設為 true),並且必須將 --fail-swap-on 命令列標記或 failSwapOn 組態設定 設定為 false。若要允許 Pod 使用交換空間,swapBehavior 在 kubelet 組態中不應設定為 NoSwap(這是預設行為)。

使用者也可以選擇性地設定 memorySwap.swapBehavior 以指定節點將如何使用交換記憶體。例如,

memorySwap:
  swapBehavior: LimitedSwap
  • NoSwap(預設):Kubernetes 工作負載將不會使用交換空間。
  • LimitedSwap:Kubernetes 工作負載對交換記憶體的使用受到限制。只有 Burstable QoS 的 Pod 才允許使用交換空間。

如果未指定 memorySwap 的組態且功能閘道已啟用,則預設情況下,kubelet 將套用與 NoSwap 設定相同的行為。

使用 LimitedSwap,不屬於 Burstable QoS 分類的 Pod(即 BestEffort/Guaranteed Qos Pod)被禁止使用交換記憶體。為了維護上述安全性和節點健康保證,當 LimitedSwap 生效時,不允許這些 Pod 使用交換記憶體。

在詳細說明交換限制的計算之前,有必要定義以下術語

  • nodeTotalMemory:節點上可用的實體記憶體總量。
  • totalPodsSwapAvailable:節點上可供 Pod 使用的交換記憶體總量(某些交換記憶體可能保留供系統使用)。
  • containerMemoryRequest:容器的記憶體請求。

交換限制配置為:(containerMemoryRequest / nodeTotalMemory) * totalPodsSwapAvailable

重要的是要注意,對於 Burstable QoS Pod 中的容器,可以透過指定等於記憶體限制的記憶體請求來選擇不使用交換空間。以這種方式配置的容器將無法存取交換記憶體。

交換空間僅在cgroup v2中支援,不支援 cgroup v1。

如需更多資訊,並協助測試和提供意見反應,請參閱關於 Kubernetes 1.28:NodeSwap 畢業為 Beta1KEP-2400 及其 設計提案的部落格文章。

下一步

深入瞭解以下內容