nerdctl:用 Docker 的姿势操作 containerd,但别指望完全替代
containNERD CTL - 适用于 Containerd 的 Docker 兼容 CLI,支持 Compose、Rootless、eStargz、OCIcrypt、IPFS 等
秒懂
- 它是什么?
- nerdctl 是 containerd 官方的 Docker 兼容命令行工具,支持 Compose、rootless 和多种实验性快照器。本文拆解它的适用场景、真实限制,以及和 Docker CLI 的本质差异。
- 适合谁用?
- nerdctl 适合两类人:一是想在 containerd 上体验 Docker 工作流,且需要 lazy-pulling、ocicrypt、IPFS 等实验功能的开发者;二是需要调试本地 Kubernetes 集群,想用 `--namespace k8s.io` 直接看容器日志的运维人员。不适合生产环境完全依赖 Docker 生态的人,因为 Compose 支持只覆盖常用子集,且 `nerdctl build` 依赖外部 BuildKit daemon,多了一个故障点。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 2 天前。
- 用什么语言写的?
- 主要是 Go(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月14日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是 Docker 装不下的功能
nerdctl 直接对接 containerd,绕过了 dockerd 这一层。这样做的直接好处是,你可以用到 Docker CLI 里根本没有的命令。比如 `nerdctl --snapshotter=stargz run IMAGE` 实现按需拉取镜像,`nerdctl image encrypt SRC DST` 做镜像加密,`nerdctl run ipfs://CID` 从 IPFS 网络拉镜像。这些功能不是锦上添花,而是 containerd 生态里独有的机制。README 里明确写了,nerdctl 的目标是让用户实验 containerd 的 cutting-edge 功能,而不是和 Docker 竞争。所以如果你只是想在 containerd 上跑常规容器,用 nerdctl 也行,但它的价值恰恰在于那些 Docker 没有的选项。
架构:一个 CLI,三个外部依赖
nerdctl 本身只是一个二进制,它依赖 containerd 作为核心运行时。要跑 `nerdctl run`,你必须安装 CNI 插件,版本建议 v1.1.0 以上。要跑 `nerdctl build`,你得额外启动 BuildKit daemon。要跑 rootless 模式,又需要 RootlessKit。这些依赖不是可选的,而是功能的前置条件。README 里说得很清楚,`nerdctl-full-<VERSION>.tar.gz` 会包含这些组件,但 `nerdctl-<VERSION>.tar.gz` 不会。这意味着如果你只下载了基础包,`nerdctl run` 可能直接报错。这种设计让 nerdctl 更像一个前端,真正的逻辑分散在 containerd、BuildKit、CNI 插件里。好处是模块化,坏处是排障时你要面对多个组件的日志。
上手:三条命令,三种安装路径
安装方式有几种。Linux 上可以用 brew:`brew install nerdctl`。macOS 上 brew 不支持,得用 Lima 虚拟机:`brew install lima`,然后 `limactl start`,最后 `lima nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine`。Windows 上可以用 Scoop:`scoop install nerdctl`。跑起来之后,基本用法和 Docker 几乎一样:`nerdctl run -it --rm alpine` 启动一个容器,`nerdctl build -t foo /some-dockerfile-directory` 构建镜像。如果你有 docker-compose.yaml,直接 `nerdctl compose -f ./examples/compose-wordpress/docker-compose.yaml up`。这里有个细节:`nerdctl build` 需要 BuildKit daemon 在跑,否则命令会失败。README 给出的示例是 `nerdctl build -o type=local,dest=. /some-dockerfile-directory`,这会把构建产物直接输出到本地目录,适合调试。
rootless 模式:绕过 slirp,但需要额外配置
rootless 是 nerdctl 的一个卖点,README 里特意标了“without slirp overhead”,指的是用 bypass4netns 来加速网络。启用方式是在 `nerdctl run` 时加 `--annotation nerdctl/bypass4netns=true`。但这不是默认行为,你需要先安装 RootlessKit,版本要求 v0.10.0 以上,推荐 v3.0.0 以上。安装后执行 `containerd-rootless-setuptool.sh install`,然后才能用 `nerdctl run -d -p 8080:80 --name nginx nginx:alpine` 这样的命令。这里有个明显的权衡:rootless 模式降低了权限要求,但引入了一个额外的 setup 工具和版本依赖。如果你在 CI 环境里跑 rootless,还得确保 RootlessKit 的版本和 nerdctl 兼容。文档里没有提到具体的兼容性矩阵,所以升级 nerdctl 时最好同时检查 RootlessKit 的 release notes。
调试 Kubernetes:一个被低估的用法
README 里提到 nerdctl 可能对调试 Kubernetes 集群有用,但明确说这不是主要目标。实际用法是 `nerdctl --namespace k8s.io ps -a`,这样可以列出 kubelet 管理的所有容器,包括 pause 容器。然后 `nerdctl --namespace k8s.io logs -f <container-id>` 可以直接看日志,不需要 `kubectl logs`。这个功能的价值在于,当 Kubernetes 的 API server 不可用,或者 kubelet 卡住时,你还能用 nerdctl 直接和 containerd 交互。另一个场景是给本地 Kubernetes 构建镜像:`nerdctl --namespace k8s.io build -t foo /some-dockerfile-directory`,然后用 `imagePullPolicy: Never` 的 Pod 直接引用,省掉了 registry 这一步。注意,所有 Kubernetes 容器都在 `k8s.io` 这个 containerd namespace 里,和 Kubernetes 的 namespace 无关。这个设计容易让人混淆,但用一次就记住了。
局限:Compose 支持不是完整的 Docker Compose
nerdctl 支持 `nerdctl compose up`,但 README 里没有承诺 100% 兼容所有 docker-compose.yaml 字段。实际使用中,如果 Compose 文件里用了 Docker 特有的扩展,比如 `x-` 自定义字段或者某些不常见的网络模式,nerdctl 可能直接忽略或报错。另外,`nerdctl build` 依赖 BuildKit,而 BuildKit 的版本直接影响功能完整性。README 明确说,`nerdctl system prune` 在 BuildKit 低于 v0.11.0 时无法正常工作。这意味着如果你在旧环境上,某些清理命令会静默失败。还有一个限制是 IPFS 功能,README 强调你的主机不会自动连接到 P2P 网络,除非你显式安装并运行 IPFS daemon。这算是个安全设计,但也意味着你要额外维护一个 IPFS 节点。
替代方案:Docker CLI 和 crictl 的对比
最直接的替代是 Docker CLI,它背后也是 containerd,但多了一个 dockerd 层。Docker CLI 的 Compose 支持更成熟,插件生态更丰富,但代价是你无法直接访问 containerd 的命名空间和快照器。另一个替代是 crictl,它是 Kubernetes 社区的标准 CRI 工具,专门用于调试 kubelet 管理的容器。crictl 支持 `crictl ps`、`crictl logs`,但它不提供镜像构建功能,也没有 Compose 支持。nerdctl 的定位恰好介于两者之间:它有 Docker 的 UX,但直接操作 containerd 的 namespace 和 snapshotter。如果你需要 lazy-pulling 或 ocicrypt,crictl 和 Docker CLI 都做不到,只有 nerdctl 这类工具能直接指定 `--snapshotter=stargz`。这就是它的不可替代性。
维护成本:非核心项目,升级需谨慎
nerdctl 是 containerd 的非核心子项目,这意味着它不在 containerd 的核心发布周期里。版本更新频率不低,最近有 v2.4.0-beta.0、v2.3.5、v2.3.4,但 beta 版本的存在说明 API 可能变动。许可证是 Apache-2.0,商用没问题,但你需要检查依赖组件的许可证,比如 BuildKit 是 Apache-2.0,CNI 插件是 Apache-2.0,RootlessKit 是 Apache-2.0,这些都没问题。升级成本主要来自版本兼容性:README 建议 CNI v1.1.0 以上、BuildKit v0.11.0 以上、RootlessKit v0.10.0 以上,但这些建议没有给出具体的测试矩阵。最稳妥的做法是升级 nerdctl 时同时升级所有依赖,或者直接下载 `nerdctl-full` 包,里面包含了所有组件,避免版本错配。
编辑结论
nerdctl 适合两类人:一是想在 containerd 上体验 Docker 工作流,且需要 lazy-pulling、ocicrypt、IPFS 等实验功能的开发者;二是需要调试本地 Kubernetes 集群,想用 `--namespace k8s.io` 直接看容器日志的运维人员。不适合生产环境完全依赖 Docker 生态的人,因为 Compose 支持只覆盖常用子集,且 `nerdctl build` 依赖外部 BuildKit daemon,多了一个故障点。采用前先验证三件事:第一,你的 CNI 插件版本是否不低于 v1.1.0,否则 `nerdctl run` 可能无法创建网络;第二,你的 BuildKit 版本是否不低于 v0.11.0,否则 `nerdctl system prune` 等操作会失效;第三,如果使用 rootless 模式,确认 RootlessKit 版本不低于 v0.10.0。nerdctl 的定位是实验前沿 containerd 功能,不是 Docker 的免费平替,这个边界决定了一切。
社区笔记