返回文章列表

Kubernetes架構深入解析容器映像與Pod運作

本文深入解析 Kubernetes 架構,從容器映像檔到 Pod 的運作機制,探討 etcd、kube-scheduler、kubelet 等核心元件的功能與互動,並說明容器執行環境的選擇與組態,以及容器執行介面 CRI 的作用。同時,文章也涵蓋了 cloud-controller-manager

容器技術 雲端原生

Kubernetes 叢集仰賴 etcd 儲存所有狀態與資源資訊,kube-apiserver 的每次讀寫操作都與 etcd 互動。etcd 的高用性對於叢集的穩定運作至關重要。kube-scheduler 負責為 Pod 選擇合適的工作節點,透過演算法和組態,將 Pod 排程到最佳節點。kube-controller-manager 則包含多個控制器,確保叢集實際狀態與 etcd 中的期望狀態一致。cloud-controller-manager 管理 Kubernetes 與底層雲基礎設施的互動,處理雲端資源供應。容器引擎和容器執行環境是容器化應用的基礎,Kubernetes 使用 CRI 與容器執行環境通訊,支援 containerd 和 CRI-O 等多種執行環境。kubelet 作為工作節點的核心元件,與本地容器執行環境互動,並透過 kube-apiserver 取得 Pod 資訊。OCI 標準則確保了容器映像和執行環境的互操作性,RuntimeClass 則允許為不同 Pod 分配不同的執行環境組態。

Kubernetes架構深度解析:從容器映像到運作中的Pod

etcd資料儲存系統的重要性

在深入瞭解Kubernetes的架構時,我們不能忽視etcd的重要性。etcd是一個開源的分散式鍵值儲存系統,用於儲存Kubernetes叢集的狀態和資源資訊。雖然etcd不是Kubernetes專案的一部分,但它是Kubernetes運作的核心元件之一。

當你呼叫kube-apiserver時,每一次的讀取或寫入操作都會與etcd進行互動。etcd就像是Kubernetes叢集的心臟,如果etcd的資料遺失,整個叢集將無法運作。因此,瞭解etcd的工作原理和使用方式對於管理Kubernetes叢集至關重要。

etcd的基本特性

  • 分散式鍵值儲存:etcd是一個分散式的鍵值儲存系統,可以水平擴充套件以滿足高用性的需求。
  • 持久化儲存:與Redis或Memcached不同,etcd的資料是儲存在磁碟上的,因此即使重啟機器,資料也不會遺失。
  • REST API:etcd預設監聽2379埠,提供REST API供其他元件互動。

佈署etcd的選擇

在自管理的Kubernetes環境中,你可以選擇將etcd佈署在容器中或作為系統服務。etcd可以與kube-apiserver及其他控制平面元件佈署在同一台機器上,這是預設的簡單佈署方式。此外,也可以選擇使用獨立的etcd叢集,以提高可靠性和可用性。

佈署選項

  1. 與控制平面元件共置:這是預設的佈署方式,etcd與kube-apiserver等元件佈署在控制平面節點上。
  2. 獨立的etcd叢集:對於需要更高可靠性的環境,可以選擇佈署獨立的etcd叢集。

操作etcd叢集

關於單節點或多節點etcd叢集的詳細資訊,可以參考官方Kubernetes檔案。對於想要深入瞭解etcd工作原理的人,可以使用線上提供的免費etcd playground進行實驗和學習。

kube-scheduler的作用

kube-scheduler負責為新建立的Pod選擇一個適當的工作節點。當Pod被建立時,它們最初是未被排程的,也就是說尚未指定工作節點。kube-scheduler會定期查詢kube-apiserver以找出尚未被排程的Pod,然後執行演算法選擇一個工作節點,並更新Pod物件中的nodeName屬性。

kube-scheduler的工作流程

  1. 查詢未排程的Podkube-scheduler定期查詢kube-apiserver以找出nodeName屬性為空的Pod。
  2. 選擇工作節點:根據預定的演算法和組態,選擇一個合適的工作節點。
  3. 更新Pod物件:透過kube-apiserver更新Pod物件的nodeName屬性,使其被排程到選定的工作節點上。
此圖示展示了etcd在Kubernetes架構中的角色

內容解密:

此圖示展示了Kubernetes中各元件之間的互動關係。其中:

  • kube-apiserver是所有操作的入口,負責處理來自其他元件的請求,並與etcd進行資料互動。
  • kube-scheduler定期查詢kube-apiserver以找出未排程的Pod,並更新其nodeName屬性以完成排程。
  • kubectl是使用者與Kubernetes叢集互動的主要工具,透過發起HTTP請求到kube-apiserver來執行各種操作。

Kubernetes架構:從容器映像檔到執行中的Pod

kube-scheduler元件的作用與組態

kube-scheduler元件負責輪詢kube-apiserver元件以發現尚未排程的Pod。該元件會根據某些可選的組態值進行決策,以選擇適當的工作節點執行Pod。以下是一些影響Pod排程的重要特性:

  • 節點選擇器(Node Selector)
  • 節點親和性與反親和性(Node Affinity and Anti-Affinity)
  • 汙點與容忍度(Taint and Toleration)

此外,還有進階的排程技術可以完全繞過kube-scheduler元件。這些技術將在後續章節中進行探討。

kube-scheduler的安裝與高用性組態

kube-scheduler可以安裝在專用機器或與kube-apiserver相同的機器上。由於該元件的資源消耗較低,因此安裝過程相對簡單。然而,為了確保高用性,建議在多台機器上安裝kube-scheduler。如果叢集中沒有正常運作的kube-scheduler元件,新建立的Pod將無法被排程,從而導致大量Pod處於待定狀態。

程式碼例項:自定義kube-scheduler

import random

class CustomScheduler:
    def __init__(self, nodes):
        self.nodes = nodes

    def schedule(self, pod):
        # 簡單的隨機排程邏輯
        selected_node = random.choice(self.nodes)
        return selected_node

# 使用範例
nodes = ["node1", "node2", "node3"]
scheduler = CustomScheduler(nodes)
pod = "example-pod"
selected_node = scheduler.schedule(pod)
print(f"Pod {pod} 已排程到 {selected_node}")

內容解密:

  1. 自定義排程器類別:定義了一個名為CustomScheduler的類別,該類別接受一個節點列表作為初始化引數。
  2. 排程邏輯實作schedule方法實作了一個簡單的隨機排程邏輯,從節點列表中隨機選擇一個節點來執行指定的Pod。
  3. 使用範例:建立了一個CustomScheduler例項,並傳入一個節點列表。然後,呼叫schedule方法為一個示例Pod進行排程,並輸出結果。

kube-controller-manager元件的作用

kube-controller-manager是一個包含多種功能的單一二進位制檔案,負責執行所謂的協調迴圈(Reconciliation Loop)。它嘗試保持叢集的實際狀態與儲存在etcd中的期望狀態一致。kube-controller-manager內部包含多個控制器,例如:

  • 節點控制器(Node Controller)
  • 複製控制器(Replication Controller)
  • 端點控制器(Endpoints Controller)
  • 服務帳戶控制器(Service Account Controller)
  • 名稱空間控制器(Namespace Controller)
  • 佈署控制器(Deployment Controller)
  • 狀態集控制器(StatefulSet Controller)
  • DaemonSet控制器(DaemonSet Controller)
  • 任務控制器(Job Controller)
  • 水平Pod自動縮放控制器(Horizontal Pod Autoscaler Controller)
  • Pod垃圾收集器(Pod Garbage Collector)

Plantumlkube-controller-manager內部控制器

此圖示展示了kube-controller-manager內部的多個控制器。

內容解密:

  1. kube-controller-manager簡介:介紹了kube-controller-manager的基本功能和作用。
  2. 內部控制器列表:列出了kube-controller-manager內部包含的多個控制器及其功能。
  3. Plantuml圖表說明:使用Plantuml圖表展示了kube-controller-manager與其內部控制器的關係。

cloud-controller-manager元件的作用與組態

cloud-controller-manager是一個管理Kubernetes與底層雲基礎設施之間互動的元件。它處理雲資源的供應和管理,以促進Kubernetes工作負載的執行。cloud-controller-manager專門為特定的雲提供商執行相關的控制器。

cloud-controller-manager元件包含的控制器

  • 節點控制器(Node Controller):檢查節點是否在雲端被刪除
  • 路由控制器(Route Controller):在底層雲基礎設施中建立路由
  • 服務控制器(Service Controller):管理雲提供商負載平衡器的建立、更新和刪除

Kubernetes架構:從容器映像檔到執行中的Pod

容器引擎與容器執行環境

容器引擎是一種軟體平台,負責建立、執行和管理容器的生命週期。它提供了一個比容器執行環境更抽象的層,簡化了容器的管理並提高了開發者的可存取性。知名的容器引擎包括Podman、Docker Engine和CRI-O。另一方面,容器執行環境是一種基礎軟體元件,負責在後端建立、執行和管理容器,當它接收到容器引擎或容器協調器的指令時。它提供了容器運作所需的基本功能,包括映像檔載入、容器建立、資源分配和容器生命週期管理。containerd、runc、dockerd和Mirantis Container Runtime都是知名的容器執行環境。

內容解密:

  • 容器引擎提供高層級的功能,如映像檔建立、註冊和管理工具,而容器執行環境則處理底層的容器執行和管理。
  • Kubernetes不再侷限於使用Docker作為預設的容器執行環境;它現在可以使用多種其他容器執行環境,如containerd和CRI-O。

為何選擇containerd或CRI-O?

選擇containerd或CRI-O作為Kubernetes的容器執行環境有幾個原因:

  • 專注與靈活性:containerd和CRI-O專注於容器執行環境的功能,使它們比Docker更輕量級,也可能更安全。這種專注也使得它們能夠與Kubernetes等容器協調平台無縫整合。
  • 與Kubernetes的相容性:Kubernetes正在逐步淘汰Docker作為預設的執行環境。選擇containerd或CRI-O可以確保與Kubernetes環境更原生、更高效的整合。

容器執行介面(CRI)

Kubernetes使用CRI來與所選的容器執行環境進行通訊。CRI是一個外掛介面,使kubelet能夠與多種容器執行環境無縫整合。這種靈活性使得使用者可以根據特定的環境需求選擇最佳的容器執行環境。

CRI的重要API

CRI中定義的一組API允許kubelet與容器執行環境高效地互動。這些API涵蓋了建立、啟動、停止和刪除容器,以及管理Pod沙箱和網路等基本操作。

Linux機器上的已知容器執行端點

執行環境Unix域Socket路徑
containerdunix:///var/run/containerd/containerd.sock
CRI-Ounix:///var/run/crio/crio.sock
Docker Engine(使用cri-dockerd)unix:///var/run/cri-dockerd.sock

Kubernetes與Docker

在Kubernetes v1.24之前的版本中,Kubernetes直接與Docker Engine整合,這得益於一個名為dockershim的元件。然而,這種特定的整合已經被廢棄,Kubernetes現在鼓勵使用符合CRI標準的執行環境。

內容解密:

  • Kubernetes放棄了對Docker的直接支援,轉而支援符合CRI標準的容器執行環境,如containerd和CRI-O。
  • 這種轉變使得Kubernetes能夠更好地與各種容器執行環境整合,提高了其靈活性和可擴充套件性。

從容器映像到執行中的 Pod:Kubernetes架構深入解析

Kubernetes 的架構設計允許其支援多種容器執行環境,確保了系統的彈性和相容性。即使Docker 的使用方式發生了變化,由Docker產生的映像仍然可以在任何執行環境中持續運作於叢集中。關於此相容性的更多資訊,請參閱 Kubernetes官方部落格文章

因此,任何執行containerd的Linux機器都可以作為構建Kubernetes工作節點的基礎。本文後續章節將討論Windows計算節點的相關內容。

開源容器倡議(OCI)

開源容器倡議(OCI)是一個定義容器映像、容器、容器執行環境和容器註冊中心標準的開源專案。這項努力旨在建立跨容器系統的互操作性和相容性,以確保在不同環境中一致的容器執行。此外,容器執行環境介面(CRI)與OCI協同工作,為kubelet與容器執行環境之間的通訊提供標準化介面。OCI定義了CRI支援的容器映像和執行環境的標準,從而促進了Kubernetes中高效的容器管理和佈署。

容器RuntimeClass

Kubernetes的RuntimeClass允許您為不同的Pod定義和分配不同的容器執行環境組態。這使得您能夠在應用程式的效能和安全性之間取得平衡。例如,您可以排程高安全性的工作負載使用硬體虛擬化執行環境,以獲得更強的隔離效果,即使這意味著效能稍慢。RuntimeClass還允許您對特定的Pod使用相同的執行環境但採用不同的設定。要利用這一點,您需要在節點上組態CRI(安裝方式有所不同),並在Kubernetes中建立相應的RuntimeClass資源。

kubelet:工作節點的核心元件

kubelet是計算節點上最重要的元件,因為它負責與安裝在計算節點上的本地容器執行環境互動。

kubelet僅作為系統守護程式執行,不能在容器內運作。它必須直接在主機系統上執行,通常透過systemd進行管理。這使得kubelet與其他Kubernetes元件有所不同,強調了它必須在主機上執行的獨特需求。

當kubelet啟動時,預設會讀取位於/etc/kubernetes/kubelet.conf的設定檔。該設定檔指定了kubelet運作所需的兩個重要值:

  • kube-apiserver元件的端點
  • 本地容器執行環境的Unix通訊端

一旦計算節點加入叢集,kubelet就會充當kube-apiserver和本地容器執行環境之間的橋樑。kubelet不斷向kube-apiserver傳送HTTP請求,以檢索需要啟動的Pod資訊。

kubelet的工作機制

預設情況下,每20秒,kubelet就會對kube-apiserver元件執行一次GET請求,以列出在etcd中建立且指定給該節點的Pod。一旦收到來自kube-apiserver的HTTP回應主體中的Pod規格,kubelet就可以將其轉換為將針對指定UNIX通訊端執行的容器規格。其結果是在計算節點上使用本地容器執行環境(例如containerd)建立您的容器。

Kubernetes中的監控機制(稱為watch機制)精確定義了Kubernetes如何在工作節點上大規模執行和刪除容器。有兩個關鍵點需要注意:

  • kubelet和kube-apiserver必須能夠透過HTTP相互通訊。因此,在計算節點和控制平面節點之間必須開啟HTTPS埠6443。
  • 由於它們執行在同一台機器上,kubelet、CRI和容器執行環境透過使用UNIX通訊端進行介面互動。

#### 內容解密:

  • kubelet 是 Kubernetes 節點代理,負責管理節點上的容器。
  • 它需要讀取設定檔 /etc/kubernetes/kubelet.conf 以取得必要組態。
  • kubelet 透過 HTTP 請求與 kube-apiserver 通訊,以取得 Pod 資訊。
  • 透過轉換 Pod 規格為容器規格,並呼叫本地容器執行環境來建立和管理容器。

Kubernetes叢集中的每個工作節點都需要其自己的kubelet,這導致隨著節點數量的增加,對kube-apiserver的HTTP輪詢活動也隨之增加。在大型叢集中,尤其是那些擁有數百台機器的叢集,這種增加的活動可能會對kube-apiserver的效能產生不利影響,並可能導致影響API可用性的情況。因此,有效的擴充套件對於確保kube-apiserver和其他控制平面元件的高用性至關重要。

此外,請注意,您完全可以繞過Kubernetes,直接在工作節點上建立容器,而無需使用kubelet。kubelet的唯一工作是使其本地容器執行環境反映儲存在etcd中的組態。因此,如果您手動在工作節點上建立容器,kubelet將無法管理它。然而,將容器執行環境通訊端暴露給容器化工作負載是一種安全風險。它繞過了Kubernetes的安全機制,是攻擊者的常見目標。一個關鍵的安全實踐是防止容器掛載這個通訊端,以保護您的Kubernetes叢集。

結語

本章探討了Kubernetes架構中的關鍵元件,包括OCI標準、RuntimeClass、以及kubelet的工作原理。這些元件共同構成了Kubernetes叢集的核心,使其能夠高效、安全地管理和執行容器化應用程式。在下一章中,我們將學習關於kube-proxy元件的更多內容,它在Kubernetes叢集中扮演著至關重要的角色。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Kubernetes架構深入解析容器映像與Pod運作

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

此圖示說明瞭 Kubernetes 節點上的主要元件及其相互關係。

  1. Kubernetes Node 是整個節點的抽象表示。
  2. kubelet 是節點上的代理,負責與 kube-apiserver 通訊並管理本地的容器執行環境。
  3. Container Runtime 是實際執行容器的執行環境,例如 containerd
  4. kube-apiserver 是 Kubernetes 的核心 API 服務,提供叢集狀態的存取介面。
  5. etcd 是 Kubernetes 使用的分散式鍵值儲存,用於儲存叢集的所有組態和狀態資訊。