2020 年 12 月初,Kubernetes 在其最新的 Changelog 中宣佈,自 Kubernetes 1.20 之後將棄用 Docker 作為容器執行時。
棄用 Docker 帶來的,可能是一系列的改變,包括不限於:
專題文章《K8S 1.20 棄用 Docker 評估》會從多方面分析由此帶來的變動和影響,上一篇:《K8S 1.20 棄用 Docker 評估之 Docker 和 OCI 映象格式的差別》 主要介紹 映象格式的變化,今天來介紹 Docker CLI 的替代產品及個人推薦。
這裡通過簡單介紹 Docker CLI 的命令,來引出 Docker 作為一個容器的完整 all-in-one 工具箱,具體包括了這麼幾大類:容器、映象及映象倉庫、容器網路的能力。
docker rename [CONTAINER_NAME] [NEW_CONTAINER_NAME]
docker run [IMAGE] [COMMAND]
docker rm [CONTAINER]
docker start [CONTAINER]
docker stop [CONTAINER]
docker restart [CONTAINER]
docker kill [CONTAINER]
docker attach [CONTAINER]
docker ps
docker logs [CONTAINER]
docker inspect [OBJECT_NAME/ID]
docker events [CONTAINER]
docker top [CONTAINER]
docker stats [CONTAINER]
docker build [URL]
docker tag
docker login
docker pull [IMAGE]
docker push [IMAGE]
docker import [URL/FILE]
docker commit [CONTAINER] [NEW_IMAGE_NAME]
docker rmi [IMAGE]
docker load [TAR_FILE/STDIN_FILE]
docker save [IMAGE] > [TAR_FILE]
docke image ls
docker history [IMAGE]
docker config
docker network ls
docker network connect [NETWORK] [CONTAINER]
docker network disconnect [NETWORK] [CONTAINER]
docker volume ls
docker volume create
docker volume rm
在 K8S 場景下,容器網路類操作以及容器卷類的操作基本上都由 kubelet 來實現了,我們日常不需要太過關注。
容器類操作、容器工具的設定,在 K8S 裡,也是由 kubelet 來實現了,但是如果我們需要在個人機器上測試及偵錯,且不用 Docker 的話,那麼是需要找一個替代品。
至於映象類常用命令,特別是構建過程,K8S 預設不會涉及這一塊,那麼不用 Docker 的話,容器構建工具也是需要找一個替代品的。
runC 實現主要是2個:
目前主流的選擇是:containerd,包括 K8S 社群和 Rancher 等。CRI-O 主要被 RedHat 的 OpenShift 4 採用。
除此之前的還有其他非 runC 的執行時,如:Kata 和 gVisor 等,使用較少,但也在增長。
Docker 映象構建替代品可選項有:
先不提 K8S CRI 的替代。要替換掉 Docker,典型有以下方案:
我推薦的是:RedHat 開源的 3 件套:Buildah、Podman 和 Skopeo,理由如下:
下面做一些簡單的介紹。
RedHat 提供了一組在沒有容器引擎的情況下可以執行的命令列工具。它們是:
run
、stop
、start
、ps
、attach
、exec
等)由於這些工具與 Open Container Initiative(OCI) 相容,所以它們可以用來管理由 Docker 和其他與 OCI 相容的容器 。另外,它們特別適用於直接在 Red Hat Enterprise Linux 或 CentOS 中執行在單節點用例。
Buildah 、Podman、Skopeo 工具都更加輕量級,並專注於一組特性。
通過組態檔:/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 = []
設定好了之後可以
podman login docker.io
podman search quay.io/postgresql-10
podman pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
podman push registry.example.com:5000/postgresql/postgresql
podman images
podman inspect docker.io/postgresql
podman tag docker.io/postgresql:10 mypg:10
podman save -o myrsyslog.tar registry.redhat.io/rhel8/rsyslog:latest
podman load -i myrsyslog.tar
podman rmi registry.example.com:5000/postgresql/postgresql
podman ps -a
podman stop mypg
podman run [options] image [command [arg ...]]
podman start mypg
podman inspect 64ad94586c74
podman exec -it mypg /bin/bash
podman attach mypg
podman export -o mypg.tar 64ad94586c74
podman import mypg.tar mypg-imported
podman kill --signal="SIGHUP" 64ad94586c74
podman rm peaceful_hopper
podman pod top mypod
podman pod stats -a --no-stream
podman pod inspect mypod
podman volume create hostvolume
podman volume inspect hostvolume
podman run -it --name myubi1 -v hostvolume:/containervolume1 registry.access.redhat.com/ubi8/ubi /bin/bash
buildah bud -t caseycui/webserver .
buildah bud -t multi -f ~/Containerfile.multifrom .
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 的替換得分情況:
nerdctl
+ buildkit
(Node 上一般也不會進行映象構建操作吧?映象構建操作一般在 CICD 機器上或容器中)或 Buildah + Podman + Skopeo 三件套。其中 Skopeo 在 Docker 替換為其他的過程中用途還是挺大的;