K8S 1.20 弃用 Docker 评估之 Docker CLI 的替代产品
本文最后更新于:2024年7月24日 晚上
背景
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 工具箱,具体包括了这么几大类:容器、镜像及镜像仓库、容器网络的能力。
容器类常用命令
- 重命名:
docker rename [CONTAINER_NAME] [NEW_CONTAINER_NAME]
- 运行:
docker run [IMAGE] [COMMAND]
- 删除:
docker rm [CONTAINER]
- 启动:
docker start [CONTAINER]
- 停止:
docker stop [CONTAINER]
- 重启:
docker restart [CONTAINER]
- Kill:
docker kill [CONTAINER]
- Attach:
docker attach [CONTAINER]
- 运行状态:
docker ps
- 日志:
docker logs [CONTAINER]
- Inspect:
docker inspect [OBJECT_NAME/ID]
- Events:
docker events [CONTAINER]
- Top:
docker top [CONTAINER]
- Stats:
docker stats [CONTAINER]
镜像类常用命令
- 构建:
docker build [URL]
- 打 Tag:
docker tag
- 登录 DockerHub:
docker login
- Pull:
docker pull [IMAGE]
- Push:
docker push [IMAGE]
- 导入镜像:
docker import [URL/FILE]
- 从容器创建镜像:
docker commit [CONTAINER] [NEW_IMAGE_NAME]
- 删除镜像:
docker rmi [IMAGE]
- 加载镜像:
docker load [TAR_FILE/STDIN_FILE]
- 保存镜像到 tar 包:
docker save [IMAGE] > [TAR_FILE]
- 列出镜像:
docke image ls
- 镜像历史:
docker history [IMAGE]
Docker 配置类命令
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 的话,容器构建工具也是需要找一个替代品的。
Docker 替代品
Docker 运行时替代品
runC 实现主要是 2 个:
- containerd: Docker 的公司贡献的
- CRI-O: RedHat 主导
目前主流的选择是:containerd,包括 K8S 社区和 Rancher 等。CRI-O 主要被 RedHat 的 OpenShift 4 采用。
除此之前的还有其他非 runC 的运行时,如:Kata 和 gVisor 等,使用较少,但也在增长。
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 和容器镜像(
run
、stop
、start
、ps
、attach
、exec
等) - 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
配置。示例:
1 |
|
镜像操作
配置好了之后可以
- 登录镜像仓库:
podman login docker.io
- 搜索镜像:
podman search quay.io/postgresql-10
- Pull 镜像:
podman pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
- Push 镜像:
podman push registry.example.com:5000/postgresql/postgresql
- 列出镜像:
podman images
- 查看镜像:
podman inspect docker.io/postgresql
- 打 Tag:
podman tag docker.io/postgresql:10 mypg:10
- Save 镜像:
podman save -o myrsyslog.tar registry.redhat.io/rhel8/rsyslog:latest
- Load 镜像:
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
- Inspect 容器:
podman inspect 64ad94586c74
- 容器中执行命令:
podman exec -it mypg /bin/bash
- Attach:
podman attach mypg
- 导出容器:
podman export -o mypg.tar 64ad94586c74
- 导入容器:
podman import mypg.tar mypg-imported
- Kill:
podman kill --signal="SIGHUP" 64ad94586c74
- 删除:
podman rm peaceful_hopper
- Top:
podman pod top mypod
- Stats:
podman pod stats -a --no-stream
- Inspect:
podman pod inspect mypod
卷操作
- 创建:
podman volume create hostvolume
- Inspect:
podman volume inspect hostvolume
- 挂载:
podman run -it --name myubi1 -v hostvolume:/containervolume1 registry.access.redhat.com/ubi8/ubi /bin/bash
Buildah 操作
- 构建镜像:
buildah bud -t caseycui/webserver .
- 多阶段构建:
buildah bud -t multi -f ~/Containerfile.multifrom .
Skopeo 简介
Skepeo 非常强大,其中的一些功能非常使用,特别是在 Docker 向 OCI 转变的阶段。举例说明:
在镜像拉取到本地前,Inspect 远程镜像的信息:
1 |
|
镜像复制,除了本地和镜像仓库之间的复制外,还支持复制到更多场景(如:S3 等):
1 |
|
使用认证文件进行操作:skopeo inspect --creds=./auth.json docker://$IMAGE
❗️ 实用功能: docker 格式镜像和 oci 格式镜像相互转换:
1 |
|
❗️ 实用功能: 打成 docker 格式的 tar 包或 oci 格式的 tar 包:
1 |
|
小结
通过上面也能看到,podman 基本上能替换 docker 的所有命令,而且命令的参数、格式等基本上和 docker cli 是一致的,替换和学习成本都不高。
总结
其实说实话,Docker CLI 的替换得分情况:
- K8S Node 上,CRI 已经从 Docker 替换为 containerd 或 CRI-O,那么这时候 K8S Node 上已经没有 docker cli 了,那么我推荐你使用:
nerdctl
+buildkit
(Node 上一般也不会进行镜像构建操作吧?镜像构建操作一般在 CICD 机器上或容器中)或 Buildah + Podman + Skopeo 三件套。其中 Skopeo 在 Docker 替换为其他的过程中用途还是挺大的; - 个人电脑、开发测试机、CICD 节点等非 K8S Node 上:建议还是使用 Docker。省心省力和熟悉。打出来的镜像 K8S 也能用。
👍️ 小提示 :
另外无论是选择 nerdctl 还是 podman,最好通过 alias 伪装成 docker 命令,为开发和用户提供一致的体验。
以上。