Docker 向全面集成 containerd 又邁進一步
Docker 在剛剛發佈的 Docker Desktop 4.12.0[1] 中,加入了實驗特性:進一步集成 containerd,使用 containerd 來管理和存儲鏡像。
爲什麼說是 “進一步集成”?這就要翻翻 Docker 和 containerd 的歷史了。
containerd 的誕生
containerd 最早出現在 Docker Engine 中,後來爲了將 Docker Engine 做得更加輕量、快速和健壯,在 2016 年 Docker 將 containerd 從 daemon(dockerd
) 中獨立出來,並完成了與 daemon 的集成。獨立出來的 containerd 全面支持 OCI(Open Container Initiative[2])資源的啓動和生命週期的管理,也因此 containerd 可以支持 runc(前身是 Docker 中的 libcontainer,後來捐贈給 LF)以外的其他 OCI 實現。2017 年 Docker 將 containerd 捐獻給 CNCF;2019 年 2 月,containerd 畢業。
containerd 獨立出來之後,發送到 Docker Engine 的請求:
-
Docker daemon 完成鏡像管理的操作(拉取、更新鏡像)
-
daemon 會爲創建容器進行準備工作(創建 OCI bundles[3]):鏡像的信息和運行時的信息。
-
daemon 調用 containerd 的 API。
-
收到請求的 containerd 不會直接去操作容器(不直接作爲容器的父進程,防止 containerd 掛掉影響容器),而是先創建一個 container-shim 進程。
-
container-shim 調用 runc cli[4] 來運行容器,並啓動 Unix domain socket 暴露 API 提供給 containerd 進行容器的管理。
隨着 containerd 的不斷演進,除了容器創建和容器聲明週期管理以外,從 1.1 開始 containerd 加入了 CRI(Container Runtime Interface)的支持。
CRI
在《源碼解析 kubectl port-forward 工作原理》[5] 中層提到 kubelet 會調用 rumtime service 的 gRPC 接口,除了用於 portforward 流的 stream server 以外,其實還有實現 CRI 接口 RuntimeService
[6] 和 ImageService
[7] 的 RuntimeServiceServer
和 ImageServiceServer
。
RuntimeServiceServer
用於接收並處理容器及其生命週期相關的操作,而 ImageServiceServer
則是用來處理鏡像相關的操作。containerd 提供了鏡像拉取、刪除、檢查、存儲等功能。
既然 containerd 可以進行鏡像的管理,而且 Docker 已經在使用,Docker 也沒有必要自己繼續維護一套相同的功能。
切換到 containerd 的鏡像管理
在 Docker Desktop 的設置中啓動 containerd 管理鏡像後,運行 docker info
會發現存儲的驅動從原來的 overlay2
變成了 containerd 的 stargz
。
切換前:
切換後:
既然使用了 containerd 的 snapshotters 來管理存儲(掛在容器的根文件系統),就可以支持多種 snapshotters,比如 stargz[8] 的延遲拉取。
此外,得益於 containerd 原生支持多平臺鏡像的存儲,還是因爲 snapshotters 的原因,可以使用 docker 來構建多平臺的鏡像了。
#切換前
docker buildx build -t demo --no-cache --platform linux/amd64,linux/arm64 .
[+] Building 0.0s (0/0)
error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
總結
使用 containerd 作爲 Docker 的鏡像管理目前還處於實驗性階段,不可避免會存在問題,使用時請謹慎對待。
隨着 Docker Swarm 在容器編排之戰中的落敗,Kubernetes 的話語權也越來越強。在 Kubernetes 1.24.0 中移除了 docker shim 代碼,看起來更像是 containerd 取代了 Docker 曾經的地位,而 Docker 也越來越名聲不顯。從趨勢來看,Docker 未來將會完全集成 containerd。
參考
-
Extending Docker’s Integration with containerd[9]
-
Docker containerd integration[10]
-
Learning Containers From The Bottom Up[11]
參考資料
[1]
Docker Desktop 4.12.0: https://docs.docker.com/desktop/release-notes/#docker-desktop-4120
[2]
Open Container Initiative: https://www.opencontainers.org
[3]
OCI bundles: https://chromium.googlesource.com/external/github.com/docker/containerd/+/refs/tags/v0.2.0/docs/bundle.md
[4]
runc cli: https://github.com/opencontainers/runc
[5]
《源碼解析 kubectl port-forward 工作原理》: https://atbug.com/how-kubectl-port-forward-works/
[6]
RuntimeService
: https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto#L34
[7]
ImageService
: https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto#L128
[8]
stargz: https://github.com/containerd/stargz-snapshotter
[9]
Extending Docker’s Integration with containerd: https://www.docker.com/blog/extending-docker-integration-with-containerd/
[10]
Docker containerd integration: https://www.docker.com/blog/docker-containerd-integration/
[11]
Learning Containers From The Bottom Up: https://iximiuz.com/en/posts/container-learning-path/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/QXorU3GgItbg3GUpDOQ5qA