K8s 和 Docker 的關系與管理邏輯詳解
一、先搞懂:Docker 和 K8s 分別是做什么的?
- Docker(容器工具):好比「集裝箱工廠」,負責把應用和依賴打包成標準化容器(類似集裝箱),讓應用能在任何環境中運行(一次打包,到處運行)。
- K8s(Kubernetes,容器編排工具):好比「集裝箱碼頭調度系統」,當有大量集裝箱(容器)需要管理時,K8s 負責調度、分配資源、保證容器正常運行,解決單個 Docker 無法處理的「大規模集群管理」問題。
二、K8s 與 Docker 的關系:不是替代,而是「分工合作」
- Docker 是基礎,K8s 是上層調度:
- Docker 解決「如何打包和運行單個容器」的問題。
- K8s 解決「如何在集群中管理成千上萬個容器」的問題,比如:
- 容器掛了自動重啟(自愈);
- 按流量自動增減容器數量(擴縮容);
- 把容器分配到最合適的服務器上(調度);
- 讓多個容器之間能互相訪問(服務發現)。
三、K8s 如何管理 Docker?核心組件與流程
K8s 不直接管理 Docker,而是通過中間層?Container Runtime Interface(CRI,容器運行時接口)?間接控制。以 Docker 為例,其管理邏輯如下:
1. K8s 的「調度 - 執行」架構
K8s 控制平面(Master)? ? ? ?→ 工作節點(Worker Node)
├─ 調度容器去哪運行? ? ? ? ? ? ? ? └─ Docker 負責實際運行容器
- 控制平面(Master):
- API Server:接收用戶部署請求(如「運行 3 個 Web 容器」),并轉化為標準格式(Pod)。
- Scheduler:根據節點資源(CPU、內存)和容器需求,決定把容器放在哪個節點上。
- Controller Manager:監控容器狀態,比如發現容器掛了就通知重新部署。
- 工作節點(Worker Node):
- Kubelet:節點上的「管家」,接收控制平面的指令,通過 CRI 調用 Docker 運行容器。
- Docker Engine:實際創建和運行容器,管理容器的生命周期。
?
2. CRI:K8s 與 Docker 溝通的「翻譯官」
- 為什么需要 CRI?:K8s 設計時希望支持多種容器運行時(如 Docker、Containerd、CRI-O),所以定義了 CRI 接口,讓不同運行時按統一標準對接。
- CRI 如何對接 Docker?:
- 早期 K8s 直接調用 Docker API,但后來為了解耦,引入了?containerd-shim?作為中間層:
- Kubelet 通過 CRI 發送請求(如「運行容器」)到 containerd-shim。
- containerd-shim 調用 Docker 的底層組件(containerd)創建容器。
- Docker 負責容器的運行,containerd-shim 負責將狀態返回給 Kubelet。
- 早期 K8s 直接調用 Docker API,但后來為了解耦,引入了?containerd-shim?作為中間層:
3. K8s 管理 Docker 的最小單位:Pod
- Pod 是什么?:K8s 中容器的「打包單元」,一個 Pod 可以包含 1 個或多個容器(通常是緊密協作的容器,如 Web 服務 + 日志收集器)。
- Pod 與 Docker 容器的關系:
- 每個 Pod 對應一組 Docker 容器,這些容器共享網絡和存儲資源(比如同一個 Pod 里的容器可以通過?localhost?互相訪問)。
- K8s 部署時,先創建 Pod 對象,Kubelet 再通過 Docker 創建 Pod 里的所有容器。
四、舉個生活例子:K8s 如何像「快遞站」管理 Docker 容器?
- 場景:你開了一家網店,需要處理大量訂單(容器)。
- Docker = 快遞盒:把每個訂單的商品(應用)打包成獨立快遞盒(容器),保證商品不受損壞(環境隔離)。
- K8s = 快遞站調度系統:
- 接收訂單(API Server):用戶下單(部署請求),系統記錄需要多少個快遞盒(容器數量)。
- 分配快遞員(Scheduler):根據快遞員(節點)的工作量(資源),安排最合適的人去打包(運行容器)。
- 監控快遞狀態(Controller Manager):如果某個快遞員生病(節點故障),調度系統會把訂單轉給其他快遞員(容器遷移)。
- 快遞盒打包(Docker):快遞員接到任務后,用標準快遞盒(Docker)打包商品,確保每個包裹一致。
五、K8s 管理 Docker 的核心功能:不止于「運行」
- 服務發現與負載均衡:
- K8s 為一組容器(如 Web 服務)創建一個「服務(Service)」,自動分配域名和 IP,讓其他容器能找到它們,同時分攤流量(負載均衡)。
- 彈性伸縮:
- 當訪問量增加時,K8s 自動通知 Docker 創建更多容器;訪問量減少時,刪除多余容器,避免資源浪費。
- 滾動更新與回滾:
- 升級應用時,K8s 會先啟動新容器,再逐步替換舊容器,保證服務不中斷;如果升級失敗,能一鍵回滾到舊版本。
- 存儲管理:
- K8s 可以為容器分配共享存儲(如 NFS、云硬盤),即使容器在節點間遷移,數據也不會丟失。
containerd 和 dockerd 的關系:從 “母子” 到 “獨立協作”
1. 技術演進:dockerd 曾是 containerd 的 “包裝層”
-
containerd 的本質:它是一個底層容器運行時,負責管理容器的生命周期(創建、運行、停止)、鏡像管理、存儲和網絡接口等核心功能,相當于容器世界的 “基建工程師”。
-
dockerd 的角色:Docker 早期版本中,
dockerd
是用戶直接交互的命令行工具(比如docker run
),但它內部依賴containerd
來執行實際的容器操作。可以理解為:dockerd
是給containerd
穿了一層 “用戶友好的外套”,讓用戶不用關心底層復雜邏輯。 -
關系類比:
containerd
像手機的操作系統內核(如 Android 內核),dockerd
像手機的操作界面(如 MIUI/EMUI),用戶通過界面(dockerd)操作,但真正干活的是內核(containerd)。
2. 如今:獨立組件的協作模式
-
Docker 架構升級:隨著容器技術發展,Docker 將
containerd
剝離為獨立項目(2017 年捐贈給 CNCF),現在dockerd
和containerd
是兩個獨立運行的進程,但仍需協作:dockerd
負責接收用戶命令(如docker run
),并將請求轉發給containerd
;containerd
負責執行容器操作,完成后將結果返回給dockerd
,再由dockerd
反饋給用戶。
-
類比場景:
點外賣時,用戶通過 App(dockerd)下單,App 將訂單發給商家后廚(containerd),后廚做好飯菜后交給 App,再由 App 通知用戶取餐。
3. 為什么 K8s 更傾向于直接使用 containerd?
- K8s 作為容器編排工具,更關注底層容器運行時的效率和穩定性,而
containerd
比dockerd
更輕量、更標準化(符合 OCI 容器標準)。因此,K8s 從 1.24 版本開始推薦直接使用containerd
作為容器運行時,跳過dockerd
這一層,就像手機用戶繞過定制界面直接使用原生系統,減少性能損耗。
參考:
Docker 上 Kubernetes 的入門到進階指南:構建和管理你的容器化應用_kubernetes docker 先裝誰?-CSDN博客
深入理解K8s與Docker的關系:容器化技術的雙雄-CSDN博客