Kubernetes Pod 實現解析
Pod 是 Kubernetes 中最小的運行單位,它可以包含一個或多個 container。Pod 的實現原理主要涉及以下幾個方面:
- 容器技術 : 實現隔離和獨立運行
- 共享網絡和存儲 : Pod 中的所有容器共享相同的網絡和存儲空間
- Pod 調度 : 調度器會監測節點的資源利用率,將 Pod 調度到適合的節點上運行。
- 生命週期管理 : 當 Pod 發生故障或需要擴展時,控制器會自動創建、刪除或調整 Pod 的數量。
在 Kubernetes 中,Pod 是容器組的概念,爲應用程序提供了一個更加靈活的運行環境,負責管理容器的生命周期和資源。
簡介
Pod 通過 Linux Namespace、cgroups 和容器化技術實現,容器的本質是一個特殊的 process ,其創建了 NameSpace 隔離不同 Pod 運行環境;並用 Cgroups 控制資源開銷,還借助了一些 Linux 網路虛擬化技術解決了網路通信的問題,Pod 所做的則是讓多個容器加入同一個 NameSpace 以實現資源共享。
cgroups(Control Groups)是 Linux 內核提供的一個機制,它可以限制、監視和分配系統資源,也就是可以用來限制,控制與隔離 Process 所使用到的系統資源。
運用 Docker 來模擬 Pod 的實現原理
目標是部屬兩個容器,其中可以彼此共享資源。
首先啓動 nginx 容器:
docker run -d --name nginx --ipc="shareable" nginx
默認情況下,Docker 的 IPC Namespace 是私有的,我們可以使用 --ipc="shareable"
來指定允許共享。
接下來啓動 busybox 容器:
docker run -d --name busybox --net=container:nginx --ipc=container:nginx --pid=container:nginx yauritux/busybox-curl /bin/sh -c 'while true; do sleep 1h; done;'
Docker 在 run container 的時候,會創建一個 docker 模式的網路架構,再來通過 container:NAME_or_ID
來把新創建的 container ,使它共用 ```NAME_or_ID`` 容器的
- 網路命名空間
- 同一個網路棧
- 對外使用同一個 IP 位址或者 MAC 位址進行通信
故上述為啓動 busybox 容器,並且把 busybox 容器加入到 nginx 容器內,其中 NET、IPC、PID 全部共享 NameSpace 。兩個容器都啓動後,可以使用
docker exec -it busybox ps
可進入 busybox 容器中並看到 process 列表。這時會發現可以看到 nginx 容器的進程 ! 這代表現在兩個容器處於共享資源的狀態。
因為 Namespace 是由 nginx 容器創建的,若 nginx 停止運行,那麼 busybox 容器也會終止。
kubernetes pod 實現解析
承上操作,成功的讓兩個 container 共享資源,但發現容器之間有 dependency。要保證每個容器都是等價關係,就不可以讓其中的業務容器充當共享的基礎容器。Kubernetes 考慮到了這一點,故產生了一個 Pause 容器來當作 Infra container 。
Pause container
Pause container ,又稱 Infra container 。其功用就是在 Pod 創建時首先啓動,並創建基礎 Namespace。 等 Pause 容器啓動完成後,其它容器才接着啓動,並加入以 Pause 容器為基礎的 Namespace。這樣每個 container 就都在同一個 Namespace 下,可以訪問同一 Pod 中其他容器的資源了。
pause 容器的創建用的是 docker 的 none 網路模式。 CRI 只負責給 pause 容器生成一個 network namespace , CNI 會完成 pause 容器的網路配置。
Pause 容器的本質就是一個獨立的 Process ,作用是 保證即使 Pod 中沒有任何其他 Container 運行也不會被刪除,因爲這時候還有 Pause 容器在運行。
因此 Pause container 的生命週期就相當於是整個 Pod 的生命週期。
創建過程可以查看 kubelet source code,其中第 4 步的創建 Sandbox,實際就是創建 Pause 容器。
鏡像非常小,才幾百 KB 而已。,性能開銷幾乎可以忽略的。
pause container 啟動後,就永遠處於暫停狀態,這也是稱為 pause container 的原因。