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 镜像构建替代品可选项有:
Buildah:RedHat 主导
BuildKit:Moby 之下,由 Docker 贡献。
Kaniko:Google 主导。
先不提 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 替换为其他的过程中用途还是挺大的;👍️ 小提示:
另外无论是选择 nerdctl 还是 podman,最好通过 alias 伪装成 docker命令,为开发和用户提供一致的体验。
以上。
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.