K8S 1.20 棄用 Docker 評估之 Docker CLI 的替代產品

背景

2020 年 12 月初,Kubernetes 在其最新的 Changelog 中宣佈,自 Kubernetes 1.20 之後將棄用 Docker 作爲容器運行時。

棄用 Docker 帶來的,可能是一系列的改變,包括不限於:

  • 容器鏡像構建工具
  • 容器 CLI
  • 容器鏡像倉庫
  • 容器運行時

專題文章《K8S 1.20 棄用 Docker 評估》會從多方面分析由此帶來的變動和影響,上一篇:《K8S 1.20 棄用 Docker 評估之 Docker 和 OCI 鏡像格式的差別》 主要介紹 鏡像格式的變化,今天來介紹 Docker CLI 的替代產品及個人推薦。

Docker 命令簡介

這裏通過簡單介紹 Docker CLI 的命令,來引出 Docker 作爲一個容器的完整 all-in-one 工具箱,具體包括了這麼幾大類:容器、鏡像及鏡像倉庫、容器網絡的能力。

容器類常用命令

  1. 重命名:docker rename [CONTAINER_NAME] [NEW_CONTAINER_NAME]
  2. 運行:docker run [IMAGE] [COMMAND]
  3. 刪除:docker rm [CONTAINER]
  4. 啓動:docker start [CONTAINER]
  5. 停止:docker stop [CONTAINER]
  6. 重啓:docker restart [CONTAINER]
  7. Kill:docker kill [CONTAINER]
  8. Attach:docker attach [CONTAINER]
  9. 運行狀態:docker ps
  10. 日誌:docker logs [CONTAINER]
  11. Inspect:docker inspect [OBJECT_NAME/ID]
  12. Events:docker events [CONTAINER]
  13. Top:docker top [CONTAINER]
  14. Stats:docker stats [CONTAINER]

鏡像類常用命令

  1. 構建:docker build [URL]
  2. 打 Tag:docker tag
  3. 登錄 DockerHub:docker login
  4. Pull:docker pull [IMAGE]
  5. Push:docker push [IMAGE]
  6. 導入鏡像:docker import [URL/FILE]
  7. 從容器創建鏡像:docker commit [CONTAINER] [NEW_IMAGE_NAME]
  8. 刪除鏡像:docker rmi [IMAGE]
  9. 加載鏡像:docker load [TAR_FILE/STDIN_FILE]
  10. 保存鏡像到 tar 包:docker save [IMAGE] > [TAR_FILE]
  11. 列出鏡像:docke image ls
  12. 鏡像歷史:docker history [IMAGE]

Docker 配置類命令

docker config

容器網絡類常用命令

  1. 列出網絡:docker network ls
  2. 連接:docker network connect [NETWORK] [CONTAINER]
  3. 斷開連接:docker network disconnect [NETWORK] [CONTAINER]

容器卷類常用命令

  1. 列出卷:docker volume ls
  2. 創建卷:docker volume create
  3. 刪除卷:docker volume rm

小結

在 K8S 場景下,容器網絡類操作以及容器卷類的操作基本上都由 kubelet 來實現了,我們日常不需要太過關注。

容器類操作、容器工具的配置,在 K8S 裏,也是由 kubelet 來實現了,但是如果我們需要在個人機器上測試及調試,且不用 Docker 的話,那麼是需要找一個替代品。

至於鏡像類常用命令,特別是構建過程,K8S 默認不會涉及這一塊,那麼不用 Docker 的話,容器構建工具也是需要找一個替代品的。

Docker 替代品

Docker 運行時替代品

runC 實現主要是2個:

目前主流的選擇是:containerd,包括 K8S 社區和 Rancher 等。CRI-O 主要被 RedHat 的 OpenShift 4 採用。

除此之前的還有其他非 runC 的運行時,如:KatagVisor 等,使用較少,但也在增長。

Docker CLI 替代

Docker 鏡像構建替代品

Docker 鏡像構建替代品可選項有:

替代品懶人方案 - RedHat 開源的 3 件套:Buildah、Podman 和 Skopeo

先不提 K8S CRI 的替代。要替換掉 Docker,典型有以下方案:

  • Docker 貢獻的:nerdctl + buildkit
  • RedHat 開源的:Buildah、Podman 和 Skopeo

我推薦的是:RedHat 開源的 3 件套:Buildah、Podman 和 Skopeo,理由如下:

  • 功能齊全、強大:Buildah、Podman 和 Skopeo 可以完全覆蓋 Docker 的功能,並且還額外提供一些 Docker 沒有但是非常實用的功能,比如 docker 格式鏡像轉換爲 oci 格式等。
  • 穩定、安全:這 3 套工具,早在 2019 年就開始大規模的應用在 RedHat 的 OpenShift 4 上面了,歷經多個版本迭代,安全 bug 修復較快,穩定性和安全有保障。
  • 平滑繼承:目前主流的企業 Linux 就是 RHEL 和 CentOS,它們的高版本自帶這 3 個工具,甚至默認通過 alias 將 docker 命令映射爲這些工具,可以平滑繼承。
  • 可以集成到現有的 K8S 或 CICD 系統中
  • 在無根(rootless)模式下運行 - 無根容器更安全,因爲它們運行時無需添加權限
  • 不需要守護進程 - 這些工具在閒置時資源要求要小得多,因爲當您沒有運行容器時,Podman 沒有運行,而 Docker 的守護進程總是運行。
  • 原生 systemd 集成 - Podman 允許您創建 systemd unit 文件,並運行容器作爲系統服務

下面做一些簡單的介紹。

Buildah Podman Skopeo 3 件套介紹

RedHat 提供了一組在沒有容器引擎的情況下可以運行的命令行工具。它們是:

  • podman - 用於直接管理 pod 和容器鏡像(runstopstartpsattachexec 等)
  • Buildah - 用於構建、推送和簽名容器鏡像
  • Skopeo - 用於複製、檢查、刪除和簽名鏡像

由於這些工具與 Open Container Initiative(OCI) 兼容,所以它們可以用來管理由 Docker 和其他與 OCI 兼容的容器 。另外,它們特別適用於直接在 Red Hat Enterprise Linux 或 CentOS 中運行在單節點用例。

Buildah 、Podman、Skopeo 工具都更加輕量級,並專注於一組特性。

Podman 簡介

配置

通過配置文件:/etc/containers/registries.conf$HOME/.config/containers/registries.conf 配置。示例:

[registries.search]
registries = ['quay.io', 'docker.io']

[registries.insecure]
registries = ['insecure-registry.example.com']

[registries.block]
registries = []

鏡像操作

配置好了之後可以

  1. 登錄鏡像倉庫:podman login docker.io
  2. 搜索鏡像:podman search quay.io/postgresql-10
  3. Pull 鏡像:podman pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
  4. Push 鏡像:podman push registry.example.com:5000/postgresql/postgresql
  5. 列出鏡像:podman images
  6. 查看鏡像:podman inspect docker.io/postgresql
  7. 打 Tag:podman tag docker.io/postgresql:10 mypg:10
  8. Save 鏡像:podman save -o myrsyslog.tar registry.redhat.io/rhel8/rsyslog:latest
  9. Load 鏡像:podman load -i myrsyslog.tar
  10. 刪除鏡像:podman rmi registry.example.com:5000/postgresql/postgresql

容器操作

  1. 列出容器:podman ps -a
  2. 停止容器:podman stop mypg
  3. 運行容器:podman run [options] image [command [arg ...]]
  4. 啓動容器:podman start mypg
  5. Inspect 容器:podman inspect 64ad94586c74
  6. 容器中執行命令:podman exec -it mypg /bin/bash
  7. Attach:podman attach mypg
  8. 導出容器:podman export -o mypg.tar 64ad94586c74
  9. 導入容器:podman import mypg.tar mypg-imported
  10. Kill:podman kill --signal="SIGHUP" 64ad94586c74
  11. 刪除:podman rm peaceful_hopper
  12. Top:podman pod top mypod
  13. Stats:podman pod stats -a --no-stream
  14. Inspect:podman pod inspect mypod

卷操作

  1. 創建:podman volume create hostvolume
  2. Inspect:podman volume inspect hostvolume
  3. 掛載:podman run -it --name myubi1 -v hostvolume:/containervolume1 registry.access.redhat.com/ubi8/ubi /bin/bash

Buildah 操作

  1. 構建鏡像:buildah bud -t caseycui/webserver .
  2. 多階段構建:buildah bud -t multi -f ~/Containerfile.multifrom .

Skopeo 簡介

[圖片上傳失敗...(image-857d00-1677550474665)]

Skepeo 非常強大,其中的一些功能非常使用,特別是在 Docker 向 OCI 轉變的階段。舉例說明:

在鏡像拉取到本地前,Inspect 遠程鏡像的信息:

# skopeo inspect docker://registry.redhat.io/ubi8/ubi-init
{
    "Name": "registry.redhat.io/ubi8/ubi8-init",
    "Digest": "sha256:c6d1e50ab...",
    "RepoTags": [
        "8.2-13-source",
        "8.0-15",
        "8.1-28",
        ...
        "latest"
    ],
   "Created": "2020-12-10T07:16:37.250312Z",
    "DockerVersion": "1.13.1",
    "Labels": {
        "architecture": "x86_64",
        "build-date": "2020-12-10T07:16:11.378348",
        "com.redhat.build-host": "cpt-1007.osbs.prod.upshift.rdu2.redhat.com",
        "com.redhat.component": "ubi8-init-container",
        "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI",
        "description": "The Universal Base Image Init is designed to run an init system as PID 1 for running multi-services inside a container
        ...

鏡像複製,除了本地和鏡像倉庫之間的複製外,還支持複製到更多場景(如:S3 等):

$ skopeo copy \
docker://registry.access.redhat.com/ubi8:8.1-397-source \
dir:$HOME/TEST
...
Copying blob 477bc8106765 done
Copying blob c438818481d3 done
Copying blob 26fe858c966c done
Copying blob ba4b5f020b99 done
Copying blob f7d970ccd456 done
Copying blob ade06f94b556 done
Copying blob cc56c782b513 done
Copying blob dcf9396fdada done
Copying blob feb6d2ae2524 done
Copying config dd4cd669a4 done
Writing manifest to image destination
Storing signatures

使用認證文件進行操作:skopeo inspect --creds=./auth.json docker://$IMAGE

❗️ 實用功能: docker 格式鏡像和 oci 格式鏡像相互轉換:

skopeo copy oci:/tmp/myimage docker://registry.example.com/myimage
podman run docker://registry.example.com/myimage

skopeo copy docker://registry.example.com/myimage oci:/tmp/myimage 
podman run oci:/tmp/myimage  

❗️ 實用功能: 打成 docker 格式的 tar 包或 oci 格式的 tar 包:

skopeo copy docker://registry.fedoraproject.org/fedora:latest docker-archive:/tmp/fedora.img
podman run docker-archive:/tmp/fedora.img echo hello

skopeo copy docker-archive:/tmp/fedora.img oci-archive:/tmp/fedora-oci.img
podman run oci-archive:/tmp/fedora-oci.img echo hello

小結

通過上面也能看到,podman 基本上能替換 docker 的所有命令,而且命令的參數、格式等基本上和 docker cli 是一致的,替換和學習成本都不高。

總結

其實說實話,Docker CLI 的替換得分情況:

  1. K8S Node 上,CRI 已經從 Docker 替換爲 containerd 或 CRI-O,那麼這時候 K8S Node 上已經沒有 docker cli 了,那麼我推薦你使用:nerdctl + buildkit (Node 上一般也不會進行鏡像構建操作吧?鏡像構建操作一般在 CICD 機器上或容器中)或 Buildah + Podman + Skopeo 三件套。其中 Skopeo 在 Docker 替換爲其他的過程中用途還是挺大的;
  2. 個人電腦、開發測試機、CICD 節點等非 K8S Node 上:建議還是使用 Docker。省心省力和熟悉。打出來的鏡像 K8S 也能用。

👍️ 小提示

另外無論是選擇 nerdctl 還是 podman,最好通過 alias 僞裝成 docker命令,爲開發和用戶提供一致的體驗。

以上。

三人行, 必有我師; 知識共享, 天下爲公. 本文由東風微鳴技術博客 EWhisper.cn 編寫.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章