1. 为什么需要nerdctl替代Docker?
在容器技术领域,Docker长期占据主导地位,但近年来nerdctl作为containerd的官方客户端工具逐渐崭露头角。nerdctl由containerd团队直接维护,与Docker CLI保持高度兼容的同时,提供了更轻量、更贴近底层容器运行时的工作方式。
我最初接触nerdctl是因为Docker Desktop在Linux环境下的各种兼容性问题。特别是在一些资源受限的开发环境中,Docker Engine的完整套件显得过于臃肿。而nerdctl直接基于containerd工作,省去了dockerd这一中间层,使得容器操作更加高效直接。
提示:如果你正在使用Kubernetes环境,nerdctl与k8s的容器运行时containerd天然兼容,这为开发到生产的全流程提供了更一致的体验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. nerdctl的安装与基础配置
2.1 主流系统安装指南
nerdctl的安装方式因操作系统而异,以下是常见环境的安装方法:
Linux系统(以Ubuntu为例):
bash复制# 首先安装containerd
sudo apt-get update && sudo apt-get install -y containerd
# 下载nerdctl二进制文件
wget https://github.com/containerd/nerdctl/releases/download/v1.0.0/nerdctl-1.0.0-linux-amd64.tar.gz
tar -xvf nerdctl-1.0.0-linux-amd64.tar.gz
sudo mv nerdctl /usr/local/bin/
# 验证安装
nerdctl --version
macOS(通过Homebrew):
bash复制brew install nerdctl
Windows(WSL2环境):
bash复制# 在WSL2的Linux发行版中按照上述Linux方法安装
# 需要确保WSL2已启用并配置好containerd
2.2 关键配置项解析
安装完成后,通常需要配置以下内容:
- 镜像加速器(国内用户必备):
bash复制mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 编辑config.toml,在[plugins."io.containerd.grpc.v1.cri".registry.mirrors]下添加:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io", "https://your.mirror.com"]
- 用户权限配置:
bash复制# 将当前用户加入docker组(如果存在)或直接配置containerd权限
sudo usermod -aG docker $USER
# 或者
sudo chmod 666 /run/containerd/containerd.sock
3. nerdctl与Docker命令对照手册
3.1 容器生命周期管理
| Docker命令 | nerdctl等效命令 | 重要差异说明 |
|---|---|---|
docker run |
nerdctl run |
支持几乎相同的参数,但网络配置略有不同 |
docker start |
nerdctl start |
行为一致 |
docker stop |
nerdctl stop |
行为一致 |
docker rm |
nerdctl rm |
行为一致 |
docker ps |
nerdctl ps |
默认输出格式更简洁 |
实际使用示例:
bash复制# 运行一个Nginx容器
nerdctl run -d --name my-nginx -p 8080:80 nginx:alpine
# 查看运行中的容器
nerdctl ps
# 进入容器执行命令
nerdctl exec -it my-nginx sh
3.2 镜像管理
| Docker命令 | nerdctl等效命令 | 注意事项 |
|---|---|---|
docker pull |
nerdctl pull |
需要正确配置registry mirror |
docker images |
nerdctl images |
输出格式略有不同 |
docker rmi |
nerdctl rmi |
行为一致 |
docker build |
nerdctl build |
需要安装buildkit组件 |
镜像操作实战:
bash复制# 拉取镜像
nerdctl pull ubuntu:20.04
# 构建镜像(需要先安装buildkit)
nerdctl build -t my-app .
# 查看镜像列表
nerdctl images
3.3 网络与存储
nerdctl的网络模型与Docker有所不同,这是迁移时需要特别注意的部分:
bash复制# 创建网络
nerdctl network create my-network
# 查看网络列表
nerdctl network ls
# 使用特定网络运行容器
nerdctl run -d --net=my-network --name=app1 my-image
存储卷操作:
bash复制# 创建卷
nerdctl volume create my-vol
# 使用卷
nerdctl run -v my-vol:/data --name=test1 alpine
4. 高级功能与特殊场景处理
4.1 容器日志管理
nerdctl的日志处理与Docker有所不同,特别是在日志驱动方面:
bash复制# 查看容器日志
nerdctl logs -f my-container
# 配置日志驱动(需要在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
4.2 容器资源限制
资源限制的配置方式与Docker类似但更贴近cgroups:
bash复制# 限制CPU和内存
nerdctl run -it --cpus 2 --memory 1g --name=limited-container alpine
# 查看容器资源使用
nerdctl stats
4.3 与Kubernetes集成
nerdctl与k8s的集成更加无缝,特别是在使用containerd作为运行时的情况下:
bash复制# 使用nerdctl构建镜像后直接推送到k8s使用的registry
nerdctl build -t registry.local:5000/my-app:v1 .
nerdctl push registry.local:5000/my-app:v1
# 然后在k8s中直接使用该镜像
kubectl run my-app --image=registry.local:5000/my-app:v1
5. 常见问题排查与优化
5.1 权限问题处理
当遇到权限错误时,可以尝试以下解决方案:
bash复制# 常见错误:permission denied while trying to connect to containerd socket
# 解决方案1:更改socket权限(临时)
sudo chmod 666 /run/containerd/containerd.sock
# 解决方案2:将用户加入docker组
sudo usermod -aG docker $USER
5.2 网络连接问题
如果遇到镜像拉取失败或网络问题:
- 检查containerd的配置文件中的registry mirrors设置
- 验证DNS配置:
bash复制nerdctl run --rm alpine cat /etc/resolv.conf
- 检查防火墙规则
5.3 性能优化建议
- 镜像层优化:
bash复制# 使用--squash参数减少镜像层数(需要buildkit支持)
nerdctl build --squash -t optimized-image .
- IO性能优化:
bash复制# 使用更高效的存储驱动
# 在/etc/containerd/config.toml中配置:
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
- 内存管理:
bash复制# 限制容器swap使用
nerdctl run -it --memory 1g --memory-swap 1g alpine
6. 从Docker迁移到nerdctl的实践经验
在实际迁移过程中,我总结了以下关键点:
-
环境检查清单:
- 确认containerd版本(建议1.5+)
- 检查内核模块(overlay、bridge等)
- 验证cgroups配置
-
脚本兼容性处理:
bash复制# 为保持兼容性,可以创建docker别名 alias docker=nerdctl -
数据迁移步骤:
bash复制# 导出Docker容器 docker export my-container > my-container.tar # 在nerdctl中导入 cat my-container.tar | nerdctl import - my-image:imported -
CI/CD流水线调整:
- 更新构建节点上的容器运行时
- 修改镜像构建和推送命令
- 调整资源限制参数
注意:在Kubernetes环境中,从Docker切换到containerd+nerdctl通常只需要调整节点运行时配置,不需要修改应用部署描述文件。
7. 生产环境部署建议
对于生产环境使用nerdctl,我有以下建议:
-
版本控制策略:
- 固定nerdctl和containerd版本
- 使用版本管理工具(如asdf)管理多版本
-
安全加固措施:
bash复制# 启用用户命名空间隔离 # 在/etc/containerd/config.toml中配置: [plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] NoNewPrivileges = true -
监控与日志收集:
- 配置containerd的日志驱动为json-file
- 使用Prometheus监控容器指标
bash复制# 暴露containerd指标 # 在配置文件中启用: [metrics] address = "0.0.0.0:1338" -
备份与恢复方案:
bash复制# 定期备份重要容器 nerdctl commit my-container my-container-backup nerdctl save my-container-backup > my-container-backup.tar # 恢复容器 nerdctl load < my-container-backup.tar
8. 开发者工作流优化
使用nerdctl可以优化开发者的日常工作流:
-
快速环境搭建:
bash复制# 一键创建开发环境 nerdctl run -d --name=dev-env -v $(pwd):/workspace -p 3000:3000 dev-image -
多架构构建支持:
bash复制# 构建多平台镜像(需要buildx) nerdctl build --platform=linux/amd64,linux/arm64 -t multi-arch-image . -
本地Registry管理:
bash复制# 启动本地registry nerdctl run -d -p 5000:5000 --name=registry registry:2 # 推送镜像到本地registry nerdctl tag my-image localhost:5000/my-image nerdctl push localhost:5000/my-image -
与IDE集成:
- 配置VS Code的Dev Containers使用nerdctl
- 调整IntelliJ的Docker设置指向nerdctl
在实际项目中,我发现nerdctl特别适合以下场景:
- 资源受限的开发环境
- 需要与Kubernetes保持一致的本地开发
- 追求极致性能的CI/CD流水线
- 需要精细控制容器运行时的场景
