
可以像 Docker 一样方便的使用 Containerd 吗?
作者 |阳明
来源 | k8s技术圈(ID:kube100)
前面我们介绍了可以使用 ctr 操作管理 containerd 镜像容器,但是大家都习惯了使用 docker cli,ctr 使用起来可能还是不太顺手,为了能够让大家更好的转到 containerd 上面来,社区提供了一个新的命令行工具:nerdctl(https://github.com/containerd/nerdctl)。nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容 docker compose 的语法的,这就大大提高了直接将 containerd 作为本地开发、测试或者单机容器部署使用的效率。
安装
同样直接在 GitHub Release 页面下载对应的压缩包解压到 PATH 路径下即可:
安装完成后接下来学习下 nerdctl 命令行工具的使用。
命令
Run&Exec
🐳nerdctl run
和 docker run 类似可以使用 nerdctl run 命令运行容器,例如:
可选的参数使用和 docker run 基本一致,比如 -i、-t、--cpus、--memory 等选项,可以使用 nerdctl run --help 获取可使用的命令选项:
🐳nerdctl exec
同样也可以使用 exec 命令执行容器相关命令,例如:
容器管理
🐳nerdctl ps:列出容器
使用 nerdctl ps 命令可以列出所有容器。
同样可以使用 -a 选项显示所有的容器列表,默认只显示正在运行的容器,不过需要注意的是 nerdctl ps 命令并没有实现 docker ps 下面的 --filter、--format、--last、--size 等选项。
🐳nerdctl inspect:获取容器的详细信息。
可以看到显示结果和 docker inspect 也基本一致的。
🐳nerdctl logs:获取容器日志
查看容器日志是我们平时经常会使用到的一个功能,同样我们可以使用 nerdctl logs 来获取日志数据:
同样支持 -f、-t、-n、--since、--until 这些选项。
🐳nerdctl stop:停止容器
🐳nerdctl rm:删除容器
要强制删除同样可以使用 -f 或 --force 选项来操作。
镜像管理
🐳nerdctl images:镜像列表
也需要注意的是没有实现 docker images 的一些选项,比如 --all、--digests、--filter、--format。
🐳nerdctl pull:拉取镜像
🐳nerdctl push:推送镜像
当然在推送镜像之前也可以使用 nerdctl login 命令登录到镜像仓库,然后再执行 push 操作。
可以使用 nerdctl login --username xxx --password xxx 进行登录,使用 nerdctl logout 可以注销退出登录。
🐳nerdctl tag:镜像标签
使用 tag 命令可以为一个镜像创建一个别名镜像:
🐳nerdctl save:导出镜像
使用 save 命令可以导出镜像为一个 tar 压缩包。
🐳nerdctl rmi:删除镜像
🐳nerdctl load:导入镜像
使用 load 命令可以将上面导出的镜像再次导入:
使用 -i 或 --input 选项指定需要导入的压缩包。
镜像构建
镜像构建是平时我们非常重要的一个需求,我们知道 ctr 并没有构建镜像的命令,而现在我们又不使用 Docker 了,那么如何进行镜像构建了,幸运的是 nerdctl 就提供了 nerdctl build 这样的镜像构建命令。
🐳nerdctl build:从 Dockerfile 构建镜像
比如现在我们定制一个 nginx 镜像,新建一个如下所示的 Dockerfile 文件:
然后在文件所在目录执行镜像构建命令:
可以看到有一个错误提示,需要我们安装 buildctl 并运行 buildkitd,这是因为 nerdctl build 需要依赖 buildkit 工具。
buildkit 项目也是 Docker 公司开源的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:
- 服务端 buildkitd:当前支持 runc 和 containerd 作为 worker,默认是 runc,我们这里使用 containerd
- 客户端 buildctl:负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求
buildkit 是典型的 C/S 架构,客户端和服务端是可以不在一台服务器上,而 nerdctl 在构建镜像的时候也作为 buildkitd 的客户端,所以需要我们安装并运行 buildkitd。
所以接下来我们先来安装 buildkit:
这里我们使用 Systemd 来管理 buildkitd,创建如下所示的 systemd unit 文件:
然后启动 buildkitd:
现在我们再来重新构建镜像:
nerdctl 构建镜像
构建完成后查看镜像是否构建成功:
我们可以看到已经有我们构建的 nginx:nerdctl 镜像了,不过出现了一个 WARN[0000] unparsable image name "xxx" 的 Warning 信息,在镜像列表里面也可以看到有一个镜像 tag 为空的镜像,和我们构建的镜像 ID 一样,在 nerdctl 的 github issue 上也有提到这个问题:https://github.com/containerd/nerdctl/issues/177,不过到现在为止还没有 FIX,幸运的是这只是一个⚠️,不会影响我们的使用。
接下来使用上面我们构建的镜像来启动一个容器进行测试:
这样我们就使用 nerdctl + buildkitd 轻松完成了容器镜像的构建。
当然如果你还想在单机环境下使用 Docker Compose,在 containerd 模式下,我们也可以使用 nerdctl 来兼容该功能。同样我们可以使用 nerdctl compose、nerdctl compose up、nerdctl compose logs、nerdctl compose build、nerdctl compose down 等命令来管理 Compose 服务。这样使用 containerd、nerdctl 结合 buildkit 等工具就完全可以替代 docker 在镜像构建、镜像容器方面的管理功能了。
