从Docker到Containerd:用nerdctl无缝迁移容器工作流
当Kubernetes宣布逐步弃用Docker支持时,许多开发者感到不安——不是担心技术演进,而是忧虑那些已经融入肌肉记忆的Docker命令该如何替代。作为容器生态的核心引擎,Containerd虽然轻量高效,但其原生客户端ctr的命令体系与Docker CLI差异显著。本文将揭示如何通过nerdctl工具重建熟悉的操作体验,并分享我们在生产环境中的实战经验。
1. 为什么需要Containerd兼容工具?
在Kubernetes 1.20版本后,默认运行时转向Containerd已成定局。这个由Docker分离出来的核心组件,经过CNCF的孵化已发展成云原生基石。但技术转型的阵痛真实存在:
-
认知成本
:ctr命令需要指定namespace(如
-n k8s.io),镜像和容器管理方式与Docker不同 - 功能缺失 :原生Containerd不支持镜像构建(docker build)、容器网络管理等高频功能
- 生态割裂 :CI/CD流水线中大量基于Docker CLI的脚本需要重构
我们团队在早期迁移时,曾因ctr的以下特性导致效率下降:
# 对比命令差异
$ docker ps -a # 查看所有容器
$ ctr -n k8s.io containers ls # 仅显示运行中容器
$ ctr -n k8s.io tasks ls # 查看实际运行的task
2. nerdctl:Docker CLI的完美替身
作为Containerd的友好前端,nerdctl(v0.22+)实现了90%的Docker命令兼容性。安装只需三个步骤:
# 在Linux系统安装最新版
wget https://github.com/containerd/nerdctl/releases/download/v1.2.0/nerdctl-1.2.0-linux-amd64.tar.gz
tar Cxzvvf /usr/local nerdctl-1.2.0-linux-amd64.tar.gz
ln -s /usr/local/containerd/bin/nerdctl /usr/bin/nerdctl
2.1 核心功能对比
| 操作类型 | Docker命令 | nerdctl命令 | ctr命令 |
|---|---|---|---|
| 镜像管理 |
docker images
|
nerdctl images
|
ctr -n k8s.io images ls
|
| 容器运行 |
docker run
|
nerdctl run
|
ctr -n k8s.io run
|
| 构建镜像 |
docker build
|
nerdctl build
| 不支持 |
| 容器网络 |
docker network
|
nerdctl network
| 不支持 |
| 日志查看 |
docker logs
|
nerdctl logs
|
crictl logs
|
注意 :nerdctl默认使用
k8s.io命名空间,与Kubernetes运行时保持统一,无需额外指定参数
3. 关键场景迁移指南
3.1 镜像构建方案
虽然Containerd原生不支持构建,但nerdctl通过集成BuildKit实现了完美替代。以下是我们的CI流水线改造示例:
# 传统Docker方式
docker build -t myapp:1.0 .
docker push my-registry.com/myapp:1.0
# 迁移后方案
nerdctl build --buildkit-host=unix:///run/buildkit/buildkitd.sock -t my-registry.com/myapp:1.0 .
nerdctl push my-registry.com/myapp:1.0
若需更复杂的构建控制,可搭配buildctl直接操作BuildKit:
buildctl build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=my-registry.com/myapp:1.0,push=true
3.2 容器网络管理
nerdctl支持CNI网络插件,能创建与Docker兼容的bridge网络:
# 创建自定义网络
nerdctl network create my-bridge --driver=bridge --subnet=10.15.0.0/16
# 运行容器并接入网络
nerdctl run -d --name web --network my-bridge nginx:alpine
# 验证网络连通性
nerdctl exec web ping db.my-bridge
4. 生产环境进阶实践
4.1 多架构镜像支持
在ARM与x86混合集群中,nerdctl的buildx扩展表现出色:
nerdctl buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:multi-arch \
--push .
4.2 与Kubernetes的深度集成
通过配置
/etc/containerd/config.toml
实现镜像自动同步:
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
4.3 性能调优建议
我们在压测中发现以下配置可提升20%容器启动速度:
# 调整containerd运行时参数
sudo systemctl edit containerd
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=
ExecStart=/usr/bin/containerd --config /etc/containerd/config.toml \
--log-level info \
--metrics-interval=0 \
--snapshotter=overlayfs
5. 常见问题解决方案
Q:如何查看容器详细配置?
A:使用
nerdctl inspect
替代
docker inspect
,或通过crictl获取CRI格式数据:
nerdctl inspect web | jq .[0].Config
crictl inspect 容器ID
Q:容器日志如何持久化?
A:修改containerd配置启用日志轮转:
[plugins."io.containerd.grpc.v1.cri".containerd]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
迁移过程中,我们总结出三个关键检查点:
-
确认
nerdctl version显示与containerd版本兼容 -
测试
nerdctl run --rm alpine ping -c 1 google.com验证基础功能 -
对比
docker stats与nerdctl stats的输出格式差异
4765




被折叠的 条评论
为什么被折叠?



