containerd, nerdctl
Contents
containerd, nerdctl
archlinux install containerd
| |
| |
ubuntu install containerd
https://gist.github.com/Faheetah/4baf1e413691bc4e7784fad16d6275a9 https://www.techrepublic.com/article/install-containerd-ubuntu/
| |
containerd
containerd 是一个行业标准的容器运行时,最初由 Docker 开发并后来捐赠给 Cloud Native Computing Foundation (CNCF)。它是一个守护进程,专门用来管理容器的完整生命周期,包括镜像传输和存储、容器执行和监督、低级存储和网络附件等。
主要特性
- 简单性:专注于容器运行时的核心功能,API 简洁明了
- 稳定性:作为生产级容器运行时,经过大规模部署验证
- 可移植性:支持 Linux 和 Windows 平台
- 扩展性:通过插件系统支持各种存储和网络解决方案
守护进程与容器隔离
containerd 确实也是一个守护进程,但它通过以下机制大大改善了 Docker 早期存在的守护进程单点故障问题:
containerd-shim 机制
- containerd 为每个容器启动一个独立的 containerd-shim 进程
- shim 作为容器的父进程,负责:
- 保持容器的 stdio 和其他文件描述符打开
- 向 containerd 报告容器的退出状态
- 管理容器的生命周期(无需守护进程持续参与)
关键优势
- 容器独立性:即使 containerd 守护进程崩溃或重启,已运行的容器不会受影响
- 无守护进程依赖:容器运行时不依赖守护进程持续存在,shim 接管容器生命周期
- 平滑升级:可以升级 containerd 而不影响正在运行的容器
- 故障隔离:单个容器的问题不会影响其他容器或守护进程
对比 Docker 早期问题
- Docker 早期:所有容器都依赖 dockerd 守护进程,dockerd 崩溃会导致所有容器失控
- containerd:通过 shim 机制实现了容器与守护进程的解耦,大大提高了可靠性
完全无守护进程的方案
如果需要完全无守护进程的容器运行时,可以考虑:
- Podman:无守护进程架构,容器作为用户进程的子进程运行
- 缺点:某些高级功能(如网络管理)实现较复杂
- 在 Kubernetes 中:Podman 不能直接作为 Kubernetes 的 CRI 运行时使用,因为它本身不实现 CRI 接口。但可以通过 CRI-O(由 Podman 团队开发)在 K8s 中获得类似的无守护进程体验
与 Docker 的关系
containerd 是 Docker Engine 的核心组件之一。Docker 使用 containerd 来实际管理容器,而 Docker 本身提供了更高级的功能,如 Docker Compose、Docker Swarm 等。从 Docker 1.11 开始,Docker 将容器运行时功能拆分出来形成了 containerd。
在 Kubernetes 中的应用
Kubernetes 可以直接使用 containerd 作为容器运行时接口(CRI (Container Runtime Interface)),这样就不需要通过 Docker 这个中间层,从而提高了性能和稳定性。这也是为什么 Kubernetes 从 1.24 版本开始移除了对 dockershim 的支持,推荐使用 containerd。
Kubernetes 支持的 CRI 运行时
除了 containerd,Kubernetes 还支持以下 CRI 运行时:
1. CRI-O
- 专门为 Kubernetes 设计的轻量级容器运行时
- 由红帽(Red Hat)主导开发
- 严格遵循 Kubernetes CRI 和 OCI 标准
- 性能优异,资源占用少
- 适合生产环境,特别是 OpenShift 平台
- 注意:CRI-O 仅设计用于 Kubernetes 环境,不适合独立使用(没有提供类似 docker/nerdctl 的命令行工具)
2. Docker Engine (通过 cri-dockerd)
- Kubernetes 1.24+ 移除了内置的 dockershim
- 需要使用 cri-dockerd 作为适配器
- cri-dockerd 是一个独立组件,提供 Docker Engine 的 CRI 接口
- 适合已有 Docker 基础设施的环境
- 独立使用:✅ 完全可以,Docker 本身就是独立的容器平台,提供完整的 CLI 工具(docker 命令)
3. Kata Containers
- 基于虚拟化的容器运行时
- 提供更强的安全隔离(每个容器运行在独立的轻量级虚拟机中)
- 适合多租户环境或对安全要求极高的场景
- 性能开销相对较高
- 独立使用:⚠️ 理论可以,但不推荐,Kata Containers 是作为低层运行时(OCI runtime),需要配合 containerd 或 CRI-O 等高层运行时使用
4. gVisor (runsc)
- Google 开发的容器沙箱运行时
- 提供应用层的系统调用拦截和模拟
- 增强安全性,限制容器对主机内核的访问
- 适合不信任的工作负载
- 独立使用:⚠️ 理论可以,但不推荐,gVisor 也是作为低层运行时(OCI runtime),通常需要配合 containerd 或 Docker 使用
5. Mirantis Container Runtime (原 Docker Enterprise)
- 企业级容器运行时
- 提供商业支持和额外的企业特性
- 独立使用:✅ 可以,本质上是 Docker 的企业版本,提供完整的独立使用能力
CRI 运行时独立使用能力总结
| 运行时 | 能否脱离 K8s 使用 | 说明 |
|---|---|---|
| containerd | ✅ 完全可以 | 通过 nerdctl 命令行工具,类似 docker 使用体验 |
| CRI-O | ❌ 不可以 | 专为 Kubernetes 设计,无独立使用的命令行工具 |
| Docker Engine | ✅ 完全可以 | 本身就是独立容器平台,docker 命令功能最丰富 |
| Kata Containers | ⚠️ 不推荐 | 是低层运行时,需要配合 containerd/Docker 使用 |
| gVisor | ⚠️ 不推荐 | 是低层运行时,需要配合 containerd/Docker 使用 |
| Mirantis Runtime | ✅ 可以 | Docker 企业版,具备完整独立使用能力 |
本地开发推荐
如果要在本地开发环境(非 Kubernetes)运行容器:
- Docker:最成熟,生态最完善,功能最丰富
- containerd + nerdctl:轻量级,性能好,与 K8s 生产环境一致
- Podman:无守护进程,Rootless 容器,更安全
不推荐:CRI-O(仅用于 K8s)、Kata/gVisor(需要高层运行时配合)
Podman 与 Kubernetes
Podman 不能直接作为 Kubernetes 的 CRI 运行时使用,原因如下:
- 缺少 CRI 接口:Podman 本身不实现 Kubernetes 的 CRI (Container Runtime Interface) 规范
- 设计目标不同:Podman 主要设计用于本地开发和单机环境,而非集群编排
- 无守护进程架构:虽然这是 Podman 的优势,但与 Kubernetes 期望的守护进程模式不兼容
在 Kubernetes 中的替代方案
如果您喜欢 Podman 的无守护进程理念,可以在 Kubernetes 中使用:
- CRI-O:由 Podman 的开发团队(Red Hat)创建,专为 Kubernetes 设计
- CRI-O 和 Podman 共享很多底层代码和技术
- CRI-O 可以看作是 Podman 在 Kubernetes 环境中的"对应版本”
Podman 的使用场景
✅ 适合使用 Podman 的场景:
- 本地开发和测试
- CI/CD 流水线中构建镜像
- 单机容器部署
- 需要 Rootless 容器(无需 root 权限)
- 替代 Docker Desktop
❌ 不适合使用 Podman 的场景:
- 作为 Kubernetes 的容器运行时
- 需要 Kubernetes 编排的生产环境
CRI 运行时选择建议
- 生产环境推荐:containerd 或 CRI-O(性能好、稳定、社区活跃)
- 高安全需求:Kata Containers 或 gVisor
- 已有 Docker 环境:Docker Engine + cri-dockerd
- OpenShift 平台:CRI-O(默认选择)
Kubernetes 运行时组合的主流选择
在 Kubernetes 生产环境中,最常见的运行时组合是:
推荐组合(主流选择)
containerd + runc(最流行)
- 高层运行时:containerd
- 低层运行时:runc
- 这是目前 Kubernetes 社区最推荐的配置
- CNCF 官方支持,社区最活跃
- 性能好,稳定性高
CRI-O + runc(Red Hat/OpenShift 首选)
- 高层运行时:CRI-O
- 低层运行时:runc
- OpenShift 默认配置
- 专为 Kubernetes 优化
是的,runc 是 Kubernetes 环境中低层运行时的主流选择!
几乎所有 Kubernetes 集群(无论使用 containerd 还是 CRI-O)默认都使用 runc 作为低层运行时。
特殊需求的替代组合
- 高安全环境:containerd/CRI-O + gVisor (runsc) 或 Kata Containers
- 性能优化:containerd/CRI-O + crun(更快、更轻量)
为什么 runc 是主流?
- 成熟稳定:经过大规模生产环境验证
- OCI 标准:作为 OCI 运行时的标准参考实现
- 广泛支持:所有主流 CRI 运行时都默认支持
- 社区活跃:CNCF 项目,持续维护和更新
- 兼容性好:与各种容器镜像和应用完全兼容
runc
runc 是一个底层的容器运行时,它是 OCI (Open Container Initiative) 运行时规范的标准实现。
什么是 runc
- OCI 运行时规范实现:runc 实现了 OCI 运行时规范,定义了如何运行容器
- CLI 工具:提供了命令行工具来生成和运行容器
- 轻量级:专注于容器的创建和执行,没有镜像管理、网络等高级功能
- 低层操作:直接与 Linux 内核交互,使用 namespace、cgroup 等技术隔离容器
在容器生态中的位置
容器运行时分为两个层次:
高层运行时 (High-level Container Runtime)
- containerd、CRI-O、Docker
- 负责:镜像管理、镜像传输、镜像解压、存储管理、网络管理等
- 最终调用低层运行时来实际运行容器
低层运行时 (Low-level Container Runtime)
- runc、crun、kata-runtime、runsc (gVisor)
- 负责:容器的实际创建和执行
- 直接与操作系统内核交互
工作流程
在 Kubernetes 环境中的完整调用链:
| |
是的,容器在 Kubernetes 中运行时也会使用 runc!
无论您使用 containerd 还是 CRI-O 作为 Kubernetes 的 CRI 运行时,它们默认都会调用 runc 作为底层运行时来实际创建和运行容器。
Kubernetes 中的运行时层次
- Kubernetes 层:kubelet 通过 CRI 接口与容器运行时通信
- 高层运行时:containerd 或 CRI-O 处理镜像、网络、存储等
- Shim 层:containerd-shim 或 conmon (CRI-O) 管理容器生命周期
- 低层运行时:runc 实际创建容器进程
- 内核层:Linux namespace、cgroup 等实现隔离
实际例子
当您在 Kubernetes 中运行一个 Pod 时:
| |
幕后发生的事情:
- kubelet 接收到创建 Pod 的请求
- kubelet 通过 CRI 接口调用 containerd/CRI-O
- containerd/CRI-O 拉取镜像、准备存储和网络
- containerd/CRI-O 启动 containerd-shim
- containerd-shim 调用 runc 创建容器
- runc 使用 Linux namespace 和 cgroup 创建隔离的容器进程
- 您的 nginx 应用在容器中运行
可以替换 runc 吗?
是的!在 Kubernetes 中也可以替换 runc:
- 使用 crun:更快、更轻量(C 语言实现)
- 使用 kata-runtime:基于 VM 的更强隔离
- 使用 gVisor (runsc):增强的安全沙箱
配置方法:在 containerd 或 CRI-O 的配置文件中指定使用不同的低层运行时。
主要功能
- 创建容器:根据 OCI 规范的配置文件创建容器
- 启动容器:启动容器中的进程
- 生命周期管理:暂停、恢复、停止、删除容器
- 资源隔离:使用 Linux namespace 和 cgroup 实现隔离
历史
- 最初由 Docker 公司开发
- 2015 年,Docker 将 runc 捐赠给 OCI,作为容器运行时的标准参考实现
- 现在几乎所有主流容器运行时(containerd、CRI-O、Podman)都使用 runc 作为默认的低层运行时
runc 的替代品
- crun:用 C 语言编写,比 runc (Go 语言) 更快、资源占用更少
- kata-runtime:基于虚拟化的运行时,提供更强的隔离
- runsc (gVisor):Google 的沙箱运行时,提供额外的安全层
为什么需要 runc
容器运行时的分层设计带来了诸多好处:
- 模块化:高层运行时专注于管理功能,低层运行时专注于执行
- 标准化:通过 OCI 规范,不同的高层运行时可以使用相同的低层运行时
- 可替换性:可以根据需求替换不同的低层运行时(如 runc、crun、kata-runtime)
- 职责分离:每个组件专注于自己的核心功能
CNI(Container Network Interface)
CNI(Container Network Interface)是一套容器网络的规范和插件系统,用于配置 Linux 容器的网络接口。
什么是 CNI
- 网络接口规范:定义了容器运行时如何调用网络插件来配置容器网络
- 插件架构:通过可执行文件形式的插件实现具体的网络功能
- CNCF 项目:由 Cloud Native Computing Foundation 维护
- 标准化:Kubernetes、containerd、CRI-O、Podman 等都支持 CNI
CNI Plugins 是什么
CNI Plugins 是一组实现 CNI 规范的可执行文件,每个插件负责不同的网络功能。
主要插件类型
1. Main 插件(主网络插件)
- bridge:创建网桥,将容器连接到网桥
- ipvlan:基于 Linux IPvlan 创建虚拟网络接口
- macvlan:基于 Linux Macvlan 创建虚拟网络接口
- ptp:创建点对点(veth pair)连接
- host-device:将已存在的设备移入容器
2. IPAM 插件(IP 地址管理)
- dhcp:通过 DHCP 服务器分配 IP 地址
- host-local:从预定义的地址池中分配 IP(最常用)
- static:分配静态 IP 地址
3. Meta 插件(元插件,辅助功能)
- portmap:配置端口映射(iptables 规则)
- bandwidth:限制网络带宽
- firewall:配置防火墙规则
- tuning:调整网络接口参数
CNI 工作流程
当容器启动时,容器运行时会调用 CNI 插件:
| |
Kubernetes 中的 CNI
在 Kubernetes 中:
- kubelet 通过 CNI 插件为 Pod 配置网络
- 常用的 Kubernetes CNI 解决方案:
- Calico:网络策略 + 路由
- Flannel:简单的 overlay 网络
- Weave:overlay 网络 + 网络策略
- Cilium:基于 eBPF 的高级网络
- Canal:Flannel + Calico 网络策略
CNI Plugins 与 Calico、Flannel 的关系
分层架构
CNI 生态系统采用分层架构:
| |
关系类型
1. CNI Plugins = 基础组件
- CNI plugins(如 bridge, host-local)是底层的网络配置工具
- 只负责单机上的容器网络配置:
- 创建 veth pair(虚拟网卡对)
- 配置 Linux bridge
- 分配 IP 地址
- 设置路由表
- 无法解决跨节点通信
2. Calico/Flannel = 完整网络方案
- 是高级的 Kubernetes 网络解决方案
- 内部会调用基础的 CNI plugins
- 额外提供:
- 跨节点网络:Pod 跨主机通信
- 网络策略:访问控制(Calico 提供,Flannel 不提供)
- 路由管理:BGP 路由(Calico)或 VXLAN 封装(Flannel)
- 服务发现:集成 kube-proxy
具体示例
Flannel 的工作方式:
| |
Calico 的工作方式:
| |
对比总结
| 特性 | CNI Plugins | Flannel | Calico |
|---|---|---|---|
| 定位 | 基础工具 | 完整网络方案 | 完整网络方案 |
| 作用范围 | 单机容器网络 | 集群跨节点网络 | 集群跨节点网络 |
| 网络模式 | bridge/veth 创建 | VXLAN/UDP overlay | BGP 路由 |
| 网络策略 | ❌ | ❌ | ✅ |
| IP 管理 | host-local IPAM | 子网分配 + host-local | IPAM 池 + host-local |
| 依赖关系 | 独立工具 | 调用 CNI plugins | 调用 CNI plugins |
| 复杂度 | 简单 | 中等 | 较高 |
| 性能 | - | 较低(封装开销) | 高(纯路由) |
实际部署中的调用链
Flannel 示例:
| |
Calico 示例:
| |
为什么需要这种分层?
职责分离:
- CNI plugins 专注于本地网络操作
- 高级方案专注于集群级网络
标准化:
- 所有方案都遵循 CNI 规范
- 可以复用基础的 CNI plugins
灵活性:
- 可以选择不同的高级网络方案
- 底层 CNI plugins 保持一致
可维护性:
- 基础组件稳定(CNI plugins)
- 高级功能独立演进(Calico/Flannel)
总结
简单来说:
- CNI plugins = 螺丝刀、扳手(基础工具)
- Calico/Flannel = 汽车装配线(完整解决方案,内部使用基础工具)
关键点:
- Calico 和 Flannel 都依赖基础的 CNI plugins
- CNI plugins 无法独立实现 Kubernetes 集群网络
- 安装 Calico/Flannel 时,仍需要安装 CNI plugins
- Calico/Flannel 是更高层次的网络抽象和管理方案
与 containerd/runc 的类比
这种关系完全类似于 containerd 与 runc 的关系:
容器运行时分层:
| |
网络运行时分层:
| |
对比表格:
| 维度 | 容器运行时 | 网络实现 |
|---|---|---|
| 高层组件 | containerd / CRI-O | Calico / Flannel |
| 低层组件 | runc / crun | CNI plugins (bridge, host-local) |
| 高层职责 | 镜像管理、存储管理、调度 | 跨节点通信、网络策略、路由管理 |
| 低层职责 | 容器进程创建、namespace/cgroup | 网络接口创建、IP 分配、路由配置 |
| 依赖关系 | containerd 调用 runc | Calico/Flannel 调用 CNI plugins |
| 独立性 | runc 无法独立管理容器生命周期 | CNI plugins 无法实现跨节点网络 |
| 标准化 | OCI Runtime Spec | CNI Specification |
核心相似点:
分层抽象:
- containerd 处理高级功能,runc 处理底层执行
- Calico/Flannel 处理集群网络,CNI plugins 处理本地网络
职责分离:
- containerd 不直接创建容器,委托给 runc
- Calico/Flannel 不直接配置网络接口,委托给 CNI plugins
标准化接口:
- OCI 规范定义了 containerd 如何调用 runc
- CNI 规范定义了 Calico/Flannel 如何调用 CNI plugins
可替换性:
- runc 可以替换为 crun、kata-runtime
- CNI plugins 可以被不同的高级方案复用
形象比喻:
- containerd : runc = 指挥官 : 士兵(执行具体命令)
- Calico/Flannel : CNI plugins = 建筑设计师 : 泥瓦匠(执行具体操作)
关键理解:
无论是容器运行时还是网络实现,都采用了相同的分层设计模式:
- 高层组件:提供完整的解决方案和高级功能
- 低层组件:提供基础的、原子化的操作能力
- 标准接口:通过规范(OCI/CNI)实现解耦和可替换性
这种设计模式在容器生态系统中非常常见,体现了Unix 哲学:“做一件事,并做好它”。
CNI 插件的职责
- 网络接口创建:为容器创建虚拟网络接口
- IP 地址分配:为容器分配 IP 地址
- 路由配置:配置容器的网络路由
- 网络清理:容器删除时清理网络资源
CNI 配置文件
CNI 配置通常存储在 /etc/cni/net.d/ 目录下,格式为 JSON:
| |
安装 CNI Plugins
| |
为什么需要 CNI Plugins
- 标准化:统一的网络配置接口,支持多种容器运行时
- 模块化:不同插件负责不同功能,可以组合使用
- 可扩展:可以开发自定义 CNI 插件
- 解耦:容器运行时不需要内置网络功能
与容器运行时的关系
- containerd:依赖 CNI plugins 来配置容器网络
- CRI-O:使用 CNI plugins 为 Kubernetes Pod 配置网络
- Docker:有自己独特的网络实现历史
单机环境 vs Kubernetes 集群环境
重要区分:CNI plugins 的使用场景取决于环境类型
单机环境(本地开发/测试):
| |
在单机环境下:
- CNI plugins 中的 bridge 插件创建本地网桥(如
cni0) - host-local 插件从配置的子网分配 IP 地址
- 容器之间通过 bridge 在同一台机器上通信
- 无需跨节点网络,因此不需要 Calico/Flannel
Kubernetes 集群环境:
| |
在 Kubernetes 集群中:
- CNI plugins 仍然负责本地网络配置
- Calico/Flannel 负责跨节点 Pod 通信
- 两者协同工作,缺一不可
实际安装示例对比
单机环境安装(仅需 CNI plugins):
| |
Kubernetes 集群安装(需要 CNI plugins + Calico):
| |
为什么单机不需要 Calico/Flannel?
无跨节点需求:
- 单机环境中,所有容器在同一台机器上
- 通过本地 bridge 就能互相通信
- 不需要 Calico 的 BGP 路由或 Flannel 的 VXLAN 封装
CNI plugins 足够:
- bridge 插件创建虚拟网桥
- host-local 分配 IP 地址
- portmap 配置端口映射
- 这些功能对单机环境已经够用
Calico/Flannel 的功能是多余的:
- 跨节点路由:单机没有多个节点
- 网络策略:单机环境通常不需要
- 分布式 IPAM:单机用 host-local 就够了
网络配置文件示例
单机环境的 CNI 配置 (/etc/cni/net.d/10-mynet.conf):
| |
这个简单配置就能让单机容器正常联网!
总结对比
| 特性 | 单机环境 | Kubernetes 集群 |
|---|---|---|
| CNI plugins | ✅ 必需 | ✅ 必需 |
| Calico/Flannel | ❌ 不需要 | ✅ 必需 |
| 网络范围 | 单机本地 | 跨节点集群 |
| 网络复杂度 | 简单(bridge) | 复杂(BGP/VXLAN) |
| 典型用例 | 开发测试 | 生产集群 |
关键理解:
- 单机用 containerd:只装 CNI plugins 就够了
- Kubernetes 集群:CNI plugins + Calico/Flannel 都要装
- Calico/Flannel 是为解决跨节点通信而设计的,单机用不上
Docker 的网络实现历史
Docker 早期(2013-2015)
- Docker 自己内置实现网络功能
- 没有使用 CNI 规范(CNI 那时还不存在)
- 网络功能直接集成在 Docker daemon 中
- 支持 bridge、host、none 等基本网络模式
Docker 1.7+(2015)引入 libnetwork
- Docker 开发了自己的网络库:libnetwork
- libnetwork 实现了 Docker 的网络模型(Container Network Model - CNM)
- 与 CNI 是不同的规范,两者互不兼容:
- CNM(Container Network Model):Docker 的网络模型
- CNI(Container Network Interface):Kubernetes/CNCF 的网络标准
- libnetwork 提供了更丰富的网络功能(overlay、macvlan 等)
Docker 现状(2020+)
- Docker 默认仍使用 libnetwork(不是 CNI)
- 但 Docker 20.10+ 可以通过配置支持 CNI plugins
- 在 Kubernetes 中使用 Docker 时,通过 dockershim/cri-dockerd 桥接到 CNI
CNM vs CNI 的区别
| 特性 | CNM (Docker) | CNI (Kubernetes/CNCF) |
|---|---|---|
| 发起者 | Docker Inc. | CoreOS/CNCF |
| 设计理念 | 面向 Docker 生态 | 容器运行时无关 |
| 网络模型 | Sandbox-Endpoint-Network | 插件链式调用 |
| 使用者 | Docker、Docker Swarm | Kubernetes、containerd、CRI-O、Podman |
| 插件格式 | Go plugin/Remote driver | 独立可执行文件 |
| 标准化 | Docker 私有 | CNCF 开放标准 |
为什么 Kubernetes 选择 CNI 而非 CNM?
- 时间因素:CNI 在 Kubernetes 早期就被采用
- 简单性:CNI 设计更简单,插件是独立可执行文件
- 中立性:CNCF 标准,不绑定特定厂商
- 灵活性:更容易集成和扩展
- 社区支持:CNCF 项目,社区驱动
Docker 网络实现的演变
| |
实际影响
- 使用 Docker 独立运行:使用 libnetwork,无需 CNI plugins
- 使用 containerd 独立运行:需要 CNI plugins
- 在 Kubernetes 中:
- 使用 containerd/CRI-O:直接使用 CNI
- 使用 Docker(通过 cri-dockerd):Docker 内部用 libnetwork,cri-dockerd 桥接到 CNI
这也是为什么:
- 安装 Docker 时不需要安装 CNI plugins
- 安装 containerd 时必须安装 CNI plugins
- 两者的网络配置方式完全不同
总结
CNI Plugins 是容器网络配置的基础组件:
- 提供容器网络接口的创建、配置和管理
- 是 Kubernetes 网络的基础
- 通过插件化设计实现灵活的网络方案
- containerd、CRI-O 等容器运行时都依赖它来配置网络
没有 CNI plugins,容器将无法连接到网络!
| |
https://www.zhangjiee.com/blog/2021/container-runtime.html https://www.zhangjiee.com/blog/2018/different-from-docker-and-vm.html https://www.zhangjiee.com/blog/2018/an-overall-view-on-docker-ecosystem-containers-moby-swarm-linuxkit-containerd-kubernete.html https://www.zhangjiee.com/blog/2021/kubernetes-vs-docker.html
containerd config
sudo vim /etc/containerd/config.toml
| |
/etc/containerd/certs.d/192.168.50.10:5000/hosts.toml
| |
nerdctl
nerdctl 是 containerd 的命令行客户端工具,它提供了与 Docker CLI 兼容的用户体验。
什么是 nerdctl
- containerd 的 CLI 工具:nerdctl 全称是 “non-enterprise control”(或 containerd ctl)
- Docker 兼容:命令语法与 docker 命令高度兼容,降低学习成本
- CNCF 项目:由 containerd 社区开发和维护
- 功能丰富:支持 Docker 不支持的一些高级功能
主要特性
1. Docker 兼容性
nerdctl 的命令与 docker 几乎完全兼容,可以无缝切换:
| |
2. 增强功能
nerdctl 支持一些 Docker 不支持的高级特性:
- 懒加载镜像(Lazy Pulling):使用 stargz/eStargz 格式,加快镜像拉取
- 镜像加密:支持加密容器镜像
- 镜像签名:支持 cosign 镜像签名验证
- P2P 镜像分发:支持 IPFS 分布式镜像存储
- Rootless 模式:无需 root 权限运行容器
- 多种运行时:可配置使用不同的 OCI 运行时(runc、crun、gVisor 等)
3. Kubernetes 一致性
- 与 Kubernetes 使用相同的 containerd 运行时
- 本地开发环境与生产环境(K8s)保持一致
- 便于调试 Kubernetes 相关问题
与 Docker 的对比
| 特性 | Docker | nerdctl |
|---|---|---|
| 底层运行时 | dockerd + containerd | containerd 直接 |
| 守护进程 | 需要 dockerd | 只需 containerd |
| 命令兼容性 | - | 兼容 docker 命令 |
| 镜像格式 | OCI | OCI + 增强格式(stargz) |
| 镜像加密 | ❌ | ✅ |
| 懒加载 | ❌ | ✅ |
| Rootless | 部分支持 | 完整支持 |
| K8s 一致性 | 不同运行时 | 相同运行时 |
| 资源占用 | 较高 | 较低 |
为什么使用 nerdctl?
- 学习成本低:如果熟悉 docker 命令,可以直接使用 nerdctl
- 性能更好:直接使用 containerd,减少中间层
- 与 K8s 一致:本地环境和 Kubernetes 使用相同的容器运行时
- 更轻量:不需要额外的 dockerd 守护进程
- 功能更强:支持镜像加密、懒加载等高级特性
常用命令示例
| |
安装说明
nerdctl 已经在文档的安装部分中提到:
| |
高级用法
| |
总结
nerdctl 是 containerd 的命令行工具,提供与 Docker 兼容的命令接口,让用户可以:
- 像使用 docker 一样使用 containerd
- 获得更好的性能和更轻量的资源占用
- 享受与 Kubernetes 一致的运行时环境
- 使用镜像加密、懒加载等高级特性
如果您在使用 containerd 作为容器运行时,nerdctl 是最佳的命令行工具选择。
私有容器仓库
Author -
LastMod 2025-06-03