Containerd 容器运行时完整入门:原理、安装、ctr/nerdctl/crictl 实操

随着 Kubernetes 弃用 docker‑shim,Containerd正式成为 K8s 主流容器运行时。它剥离自 Docker Engine,捐献给 CNCF,轻量稳定,是云原生必备组件。本文从发展历史、架构、部署、三套客户端工具实操完整梳理 Containerd。

一、什么是 Containerd

Containerd 是工业级容器运行守护进程,不直接面向普通终端用户,主要供上层编排工具调用(Kubernetes、Swarm、Mesos)。

  1. 工作模式:以 daemon 运行,对外暴露 gRPC API;单机只管理本机容器。
  2. 分工:Containerd 负责拉取镜像、存储、网络、生命周期管理;真正创建执行容器交给符合 OCI 标准的runc。
  3. OCI 规范:Open Container Initiative,统一镜像格式与容器执行规范,runc 是 OCI 参考实现。

📜 Containerd 前世今生

  1. 2013 Docker 问世;Google 联合红帽、IBM 推动把 Docker 底层libcontainer捐赠给 OCI,改名runc。同时成立 CNCF 基金会,把内部 Borg 开源为 Kubernetes,主打大规模容器编排。
  2. Docker 推出 Swarm 试图做编排,但市场竞争不敌 K8s;2017 Docker 宣布原生支持 K8s,并将内部核心组件 Containerd 捐赠 CNCF。
  3. K8s 早期使用 Docker 时需要docker‑shim垫片,把 CRI 接口转成 Docker API。
  4. K8s 1.20 开始不再维护 docker‑shim,Containerd 直接适配 CRI 接口,正式成为 Kubernetes 首选容器运行时。

简单理解:Docker 是完整的 PaaS 工具栈;Containerd 是底层容器运行底座,K8s 直接对接 Containerd,不再绕 Docker。

性能优势

benchmark 测试对比 docker‑shim、cri‑o、containerd,容器启动、停止、删除综合性能优于 Docker 和 CRI‑O。

二、Containerd 核心架构

整体采用 C/S 客户端‑服务端架构,gRPC 对外提供 API,整体全部基于插件化设计,各个功能模块解耦。

两大核心子系统

  1. Bundle:容器 rootfs、配置、元数据;负责从镜像解压、打包容器文件系统。
  2. Runtime:执行 Bundle,真正创建运行容器。

重要插件

  • Content Plugin:保存镜像不可变原始数据;
  • Snapshot Plugin:镜像分层快照,类似 Docker graphdriver;
  • Metadata Plugin:元数据管理容器、镜像;
  • GC Plugin:垃圾回收清理无用镜像资源;
  • Runtime Plugin:对接 runc,管理容器任务进程;
  • Metrics:暴露监控指标。

整体划分为三大模块:

  1. Storage 存储层:Content、Snapshot 管理镜像分层;
  2. Metadata 元数据层:Images、Containers 保存元数据;
  3. Runtime 运行层:Tasks 调用 runc 和操作系统交互,启动容器进程。

💡关键概念区分

  • container(静态容器):仅配置、rootfs,没有运行进程,只是数据对象;
  • task(任务):容器内真正运行的用户进程,只有 task 启动后容器才真正运行。

ctr 操作必须区分 container 和 task,这一点和 docker 不一样。

三、Containerd 安装(CentOS Stream8)

两种部署方式:YUM 源安装、二进制包安装。

方式 1:YUM 安装(简单,生产常用)

#安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2 vim
#添加阿里云docker源,源中包含containerd.io
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache

#安装
yum -y install containerd.io

#开机自启并立即启动
systemctl enable containerd --now
systemctl status containerd

#验证
ctr version

方式 2:二进制安装(适合离线,K8s 集群推荐 cri‑containerd‑cni 包)

cri‑containerd‑cni包含 containerd、cni 网络插件,K8s 环境优先选用;普通 containerd 二进制不带 runc,需要单独安装 runc。

#下载
wget https://github.com/containerd/containerd/releases/download/v1.6.32/cri-containerd-cni-1.6.32-linux-amd64.tar.gz

tar xf cri-containerd-cni-1.6.32-linux-amd64.tar.gz -C containerd/

#复制二进制文件
cp containerd/usr/local/bin/* /usr/local/bin
#systemd服务文件
cp containerd/etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service

#生成默认配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml

#安装独立runc
wget https://github.com/opencontainers/runc/releases/download/v1.3.0/runc.amd64
mv runc.amd64 /usr/sbin/runc
chmod +x /usr/sbin/runc
runc -v

#启动
systemctl daemon-reload
systemctl enable containerd --now
ctr version

配置文件核心路径:

  • 配置:/etc/containerd/config.toml
  • 数据目录:/var/lib/containerd
  • socket:/run/containerd/containerd.sock

四、ctr 原生 cli 实操(containerd 自带)

⚠️注意:ctr 是 debug 管理工具,不保证向后兼容。区分静态container和动态task进程。

镜像管理 ctr images

#查看镜像
ctr images ls

#拉取镜像(完整镜像地址,不支持简写nginx:latest)
ctr images pull hub.myrmirror.com/library/nginx:latest

#挂载镜像查看内部文件系统
ctr images pull xxx/nginx:latest
ctr images mount xxx/nginx:latest /mnt
ls /mnt
umount /mnt

#导出镜像
ctr images export --platform linux/amd64 nginx.tar xxx/nginx:latest

#导入镜像
ctr images import --platform linux/amd64 nginx.tar

#打tag
ctr images tag xxx/nginx:latest nginx:latest

#删除镜像
ctr images rm nginx:latest

容器生命周期 ctr container /ctr task

#1 创建静态容器(没有运行进程)
ctr container create nginx:latest nginx1
ctr container ls

#2 启动task,真正运行进程,-d后台
ctr task start -d nginx1
ctr task ls

#进入容器
ctr task exec --exec-id $RANDOM -t nginx1 /bin/sh

#一步直接运行容器(create+start)
ctr run -d --net-host nginx:latest nginx2

#暂停/恢复
ctr task pause nginx2
ctr task resume nginx2

#停止进程task
ctr task kill nginx2
ctr task ls

#先删除task,再删除静态容器
ctr task delete nginx2
ctr container delete nginx2

Namespace 命名空间隔离

containerd 的 namespace 用于隔离镜像、容器资源,和 Linux 内核 namespace 不是同一个。

  • 默认命名空间:default;docker 使用 moby 命名空间。
#查看ns
ctr namespace ls

#创建ns
ctr namespace create myns

#在指定ns操作镜像容器,-n指定命名空间
ctr -n myns images pull xxx/nginx:latest
ctr -n myns container create xxx/nginx:latest mynginx
ctr -n myns task start -d mynginx

#删除ns(ns内资源需要先清理)
ctr namespace rm myns

对接私有 Harbor 仓库

http 非安全仓库,需要--plain‑http参数

#hosts解析harbor域名
vim /etc/hosts
192.168.108.30 my.harbor.com

#拉取harbor镜像
ctr image pull --plain-http 192.168.108.30/cloud/nginx:latest

#上传镜像到harbor
ctr images tag nginx:latest my.harbor.com/cloud/nginx:latest
ctr image push --platform linux/amd64 --plain-http --user "images_admin:Cloud12#$" my.harbor.com/cloud/nginx:latest

五、nerdctl:兼容 Docker 语法的 containerd 客户端

ctr命令晦涩难用,nerdctl 提供 docker 一模一样命令体验,日常测试环境强烈推荐。

安装 nerdctl

#下载nerdctl
wget https://github.com/containerd/nerdctl/releases/download/v1.4.0/nerdctl-1.4.0-linux-amd64.tar.gz
tar -xf nerdctl-1.4.0-linux-amd64.tar.gz -C /usr/bin/

#安装cni网络插件
mkdir -p /opt/cni/bin
wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
tar -xf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin

#命令补全
nerdctl completion bash > /etc/bash_completion.d/nerdctl
source /etc/bash_completion.d/nerdctl

配置镜像加速(新版 containerd 推荐 certs.d 目录方式)

#/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
mkdir -p /etc/containerd/certs.d/docker.io
vim /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://你的镜像加速器地址"
[host."https://你的镜像加速器地址"]
capabilities = ["pull", "resolve"]

systemctl restart containerd

nerdctl 常用命令(几乎等同于 docker)

#镜像管理
nerdctl pull busybox
nerdctl images
nerdctl rmi busybox
nerdctl save busybox -o busybox.tar
nerdctl load -i busybox.tar
nerdctl tag busybox mybusybox
nerdctl image prune -a

#容器管理
nerdctl run -d --name nginx -p 8080:80 nginx
nerdctl ps
nerdctl ps -a
nerdctl exec -it nginx bash
nerdctl logs nginx
nerdctl stop nginx
nerdctl start nginx
nerdctl restart nginx
nerdctl rm nginx
nerdctl commit nginx nginx:v2

#网络
nerdctl network ls
nerdctl network inspect bridge

#存储卷
nerdctl volume ls
nerdctl run -d -v myvol:/data busybox sleep infinity

#命名空间
nerdctl namespace ls

小技巧:alias docker=nerdctl,直接把 nerdctl 当做 docker 命令使用。

六、crictl:Kubernetes CRI 官方调试工具

crictl是 K8s CRI 接口客户端,kubelet 底层调用它操作 Containerd,生产 K8s 节点排错必备。

作用:站在 Kubernetes 视角查看 Pod、容器、镜像;不能像 nerdctl 随意跑独立容器。

安装配置

#配置k8s yum源
vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/repodata/repomd.xml.key

yum install -y cri-tools

编辑/etc/crictl.yaml指定后端为 containerd

runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 5
debug: false

crictl 常用命令

#镜像
crictl pull nginx
crictl images
crictl rmi <imageid>

#pod管理(k8s中pod是sandbox沙盒)
crictl pods
crictl runp #运行pod沙盒

#容器
crictl ps
crictl ps -a
crictl exec -it <containerid> sh
crictl logs <containerid>
crictl stats
crictl stop <containerid>
crictl rm <containerid>

#查看运行时版本
crictl version

七、ctr /nerdctl/crictl 三者对比总结

表格

工具开发者适用场景特点
ctrcontainerd 项目自带底层调试 containerd 原生资源区分 container/task,命令反直觉,不保证兼容
nerdctl社区 Akihiro Suda单机测试,想要 docker 使用习惯兼容 docker cli,支持网络、卷,适合开发测试
crictlKubernetes SIGK8s 集群排错调试遵循 CRI 接口,看到的是 Pod/Sandbox 视角,生产 k8s 节点必备

简单选型建议:

  1. K8s 节点排查问题优先使用 crictl;
  2. 单机测试 containerd,优先使用 nerdctl;
  3. 研究底层原理,才使用原生ctr。

八、总结

  1. Containerd 是 CNCF 毕业项目,K8s 官方推荐容器运行时,替代 docker‑shim;
  2. 架构插件化,gRPC 对外提供 API,runc 完成真正容器执行,遵循 OCI 标准;
  3. 区分静态container和运行态task,是 ctr 最大的坑;
  4. 三套客户端各司其职:ctr 底层、nerdctl 模拟 docker、crictl 面向 K8s CRI;
  5. 配置镜像加速,新版本 containerd 推荐certs.d目录方式。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐