一、Containerd 核心介绍
1.1 前言
Containerd 是一款轻量级、工业级标准化容器运行时,专注于容器生命周期管理,主打稳定、轻量化、高兼容,是目前 Kubernetes 生态的默认容器运行时。
核心发展背景与定位:
- 2016 年随 Docker 1.11 内置发布,后续从 Docker 引擎中彻底剥离,成为 CNCF 独立开源项目,功能完全独立演进。
- 定位底层运行时,不面向终端用户,主要对接 Kubernetes、Swarm、Mesos 等容器编排平台。
- 以守护进程(Daemon)运行,通过标准 gRPC API 对外提供容器管理能力,单节点负责本机所有容器、镜像、存储、网络管理。
- 遵循 OCI 开放容器规范,具体容器运行由 runC 实现,解耦架构更轻量、更稳定。
- 独立演进后,版本迭代不受 Docker 约束,专注容器运行时核心能力,适配云原生大规模场景。
1.2 Containerd 前世今生(云原生生态演变)
1. 2013 年 Docker 问世,凭借轻量化容器技术快速垄断市场,威胁 Google 内部 Borg 系统生态。
2. Google 联合 RedHat、IBM 施压 Docker,将核心底层技术 libcontainer 捐赠给 OCI 中立社区,重构为标准容器运行时 runC,统一容器运行规范。
3. 为制衡 Docker 生态垄断,Google 牵头成立 CNCF 云原生计算基金会,开源内部 Borg 系统,推出 Kubernetes,主打大规模容器编排场景。
4. 2016 年 Docker 推出 Swarm 编排工具,试图一统容器生态,但市场验证后不敌 Kubernetes。
5. 2017 年 Docker 宣布原生支持 Kubernetes,同时将核心运行时 Containerd 捐赠给 CNCF,彻底剥离上层业务与底层运行时。
6. 2020 年 Kubernetes 1.20 正式废弃 Docker 适配垫片(shim),Containerd 成为 K8s 官方默认容器运行时,彻底替代 Docker。
1.3 Containerd 整体架构
1.3.1 架构设计理念
Containerd 采用标准 C/S 客户端/服务端架构,服务端通过 gRPC 提供稳定 API,客户端调用 API 实现所有容器管理操作。整体采用插件化、模块化解耦设计,不同职责拆分独立子系统与插件,扩展性极强。
核心两大子系统:
- Bundle 子系统:负责镜像解析、解压、打包,生成容器运行所需的文件系统、配置、元数据。
- Runtime 子系统:基于 Bundle 资源,调用 runC 完成容器创建、启动、运行、销毁等生命周期管理。
1.3.2 核心常用插件
- Content Plugin:存储镜像所有不可变内容,提供镜像内容寻址访问能力。
- Snapshot Plugin:管理镜像分层文件系统快照,等同于 Docker 的 graphdriver,实现镜像分层复用。
- Metrics Plugin:暴露组件监控指标,支持运维监控告警。
1.3.3 架构三大核心模块
Containerd 整体划分为三大核心模块,各司其职:
- Storage 存储层:负责镜像、快照、容器数据持久化。
- Metadata 元数据层:存储容器、镜像、命名空间等核心元数据。
- Runtime 运行层:对接 runC,实现容器进程调度与运行管理。
1.3.4 性能优势
通过 bucketbench 工具对 Docker、CRI-O、Containerd 容器启停、删除性能对比测试:Containerd 整体性能优于 Docker 和 CRI-O,启动更快、资源占用更低、稳定性更强,适配大规模集群场景。
二、Containerd 安装部署(CentOS7)
提供两种主流安装方式:YUM 快速安装、二进制生产级安装(K8s 集群推荐)。
2.1 YUM 快速安装
2.1.1 配置阿里云 YUM 源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看 containerd 安装包
yum list | grep containerd2.1.2 执行安装
yum -y install containerd.io2.1.3 启动服务并设置开机自启
# 查看安装结果
rpm -qa | grep containerd
# 开机自启 & 启动服务
systemctl enable containerd
systemctl start containerd
# 查看运行状态
systemctl status containerd2.1.4 验证可用性
ctr version输出客户端、服务端版本信息即为安装成功。
2.2 二进制生产级安装(推荐 K8s 环境)
2.2.1 安装包区别
containerd-xxx:单机测试包,不含 runC,需手动安装。cri-containerd-cni-xxx:K8s 专用包,内置 runC、CNI 网络插件、CRI 适配文件。
2.2.2 下载并解压安装包
# 下载 v1.6.0 稳定版
wget https://github.com/containerd/containerd/releases/download/v1.6.0/cri-containerd-cni-1.6.0-linux-amd64.tar.gz
# 解压
tar xf cri-containerd-cni-1.6.0-linux-amd64.tar.gz2.2.3 部署二进制文件与服务配置
# 复制二进制命令到系统环境
cp usr/local/bin/* /usr/local/bin/
# 复制 systemd 服务文件
cp etc/systemd/system/containerd.service /usr/lib/systemd/system/2.2.4 生成并优化配置文件
# 创建配置目录
mkdir /etc/containerd
# 生成默认配置
containerd config default > /etc/containerd/config.toml优化配置核心改动:替换 pause 镜像、配置国内镜像加速器(docker/ gcr/ quay/ 私有 Harbor)、开启 overlayfs 快照、适配 systemd 资源管理。
优化后完整配置核心片段:
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = -999
[grpc]
address = "/run/containerd/containerd.sock"
[plugins.cri]
sandbox_image = "easzlab/pause-amd64:3.2"
systemd_cgroup = false
[plugins.cri.containerd]
snapshotter = "overlayfs"
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com"]
[plugins.cri.registry.mirrors."gcr.io"]
endpoint = ["https://gcr.mirrors.ustc.edu.cn"]
[plugins.cri.registry.mirrors."quay.io"]
endpoint = ["https://quay.mirrors.ustc.edu.cn"]
[plugins.cri.registry.mirrors."harbor.kubemsb.com"]
endpoint = ["http://harbor.kubemsb.com"]2.2.5 启动服务并验证
systemctl daemon-reload
systemctl enable containerd
systemctl start containerd
systemctl status containerd
ctr version2.2.6 独立安装 runC
二进制包内置 runC 对 seccomp 支持不完善,建议手动安装官方 runC:
# 下载 runC v1.1.0
wget https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64
# 部署并授权
mv runc.amd64 /usr/sbin/runc
chmod +x /usr/sbin/runc
# 验证
runc -v三、Containerd 镜像全生命周期管理
3.1 核心命令区分
- ctr images:Containerd 原生镜像管理命令(单机使用)
- crictl images:K8s 专用 CRI 标准镜像命令
- 区别 Docker:Docker 镜像命令为
docker images,ctr 命令必须写完整镜像仓库地址
3.2 常用镜像操作实战
3.2.1 查看镜像
ctr images ls3.2.2 拉取镜像
# 拉取多平台镜像
ctr images pull --all-platforms docker.io/library/nginx:alpine
# 指定 amd64 平台
ctr images pull --platform linux/amd64 docker.io/library/nginx:alpine3.2.3 镜像挂载(查看内部文件)
# 挂载镜像到 /mnt
ctr images mount docker.io/library/nginx:alpine /mnt
# 卸载
umount /mnt3.2.4 镜像导出/导入
# 导出镜像
ctr images export --all-platforms nginx.img docker.io/library/nginx:alpine
# 导入镜像
ctr images import nginx.img3.2.5 镜像删除
ctr images rm docker.io/library/nginx:alpine3.2.6 镜像打标签
ctr images tag docker.io/library/nginx:alpine nginx:alpine
# 校验镜像完整性
ctr images check四、Containerd 容器全生命周期管理
4.1 核心概念区分
- 静态容器(container):仅初始化容器资源、配置、文件系统,无运行进程,无法对外提供服务。
- 动态容器(task):静态容器启动进程后生成,真正运行、可访问的容器实例。
4.2 基础容器操作
4.2.1 查看容器/任务
# 查看静态容器
ctr container ls
ctr c ls
# 查看运行任务
ctr task ls
ctr t ls4.2.2 创建静态容器并启动
# 创建静态容器
ctr c create docker.io/library/nginx:alpine nginx1
# 启动任务(后台运行)
ctr task start -d nginx14.2.3 一键运行动态容器
# --net-host 共享宿主机网络
ctr run -d --net-host docker.io/library/nginx:alpine nginx24.2.4 进入容器终端
# exec-id 自定义唯一ID
ctr task exec --exec-id $RANDOM -t nginx2 /bin/sh4.2.5 容器暂停/恢复
# 暂停容器
ctr task pause nginx2
# 恢复容器
ctr task resume nginx24.2.6 容器停止/删除
# 停止容器进程
ctr task kill nginx2
# 删除任务
ctr task del nginx2
# 删除静态容器
ctr c del nginx2五、对接私有镜像仓库 Harbor
5.1 前置配置
5.1.1 域名解析
所有 Containerd 节点配置 Harbor 域名解析:
vim /etc/hosts
192.168.10.165 harbor.kubemsb.com5.1.2 配置仓库镜像源
前文优化配置已内置 Harbor 镜像源,修改后重启服务:
systemctl restart containerd5.2 镜像上传至私有仓库
# 拉取官方镜像
ctr images pull --platform linux/amd64 docker.io/library/nginx:latest
# 打私有仓库标签
ctr images tag docker.io/library/nginx:latest harbor.kubemsb.com/library/nginx:latest
# 推送镜像(http 协议需加 --plain-http)
ctr images push --platform linux/amd64 --plain-http -u admin:Harbor12345 harbor.kubemsb.com/library/nginx:latest
# 从私有仓库拉取镜像
ctr images pull --plain-http harbor.kubemsb.com/library/nginx:latest六、Namespace 命名空间隔离
Containerd 命名空间用于隔离容器、镜像资源,不同命名空间资源相互独立,常用于多租户、多业务隔离。
# 查看所有命名空间
ctr ns ls
# 创建命名空间
ctr ns create kubemsb
# 删除命名空间
ctr ns rm kubemsb
# 指定命名空间操作镜像/容器
ctr -n kubemsb images pull docker.io/library/nginx:latest
ctr -n kubemsb c create docker.io/library/nginx:latest nginx-app默认命名空间:
default、k8s.io(K8s 专用)。七、CNI 网络配置(容器外网访问)
默认 Containerd 容器仅拥有 lo 本地回环网卡,无法访问外网,需配置 CNI 容器网络插件实现网桥网络。
7.1 部署 CNI 工具与插件
# 下载 CNI 核心工具
wget https://github.com/containernetworking/cni/archive/refs/tags/v1.0.1.tar.gz
# 下载 CNI 插件
wget https://github.com/containernetworking/plugins/releases/download/v1.0.1/cni-plugins-linux-amd64-v1.0.1.tgz
# 解压部署
tar xf v1.0.1.tar.gz && mv cni-1.0.1 /home/cni
mkdir /home/cni-plugins
tar xf cni-plugins-linux-amd64-v1.0.1.tgz -C /home/cni-plugins
# 安装依赖
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum -y install jq7.2 配置网络规则
创建网桥网络配置,网段
10.66.0.0/16:# 网桥配置
vim /etc/cni/net.d/10-mynet.conf
{
"cniVersion": "1.0.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.66.0.0/16",
"routes": [{"dst": "0.0.0.0/0"}]
}
}
# 回环网络配置
vim /etc/cni/net.d/99-loopback.conf
{
"cniVerion": "1.0.0",
"name": "lo",
"type": "loopback"
}7.3 生成网桥网络并绑定容器
# 生成 cni0 网桥
cd /home/cni/scripts
CNI_PATH=/home/cni-plugins ./priv-net-run.sh echo "Hello World"
# 运行测试容器
ctr images pull docker.io/library/busybox:latest
ctr run -d docker.io/library/busybox:latest busybox
# 获取容器PID与网络命名空间
pid=$(ctr tasks ls | grep busybox | awk '{print $2}')
netnspath=/proc/$pid/ns/net
# 为容器配置网络
CNI_PATH=/home/cni-plugins ./exec-plugins.sh add $pid $netnspath配置后容器自动获取
10.66.0.0/16 网段 IP,可正常访问宿主机、外网。八、容器数据持久化(目录挂载)
通过 bind 挂载实现宿主机与容器数据互通,实现数据持久化:
# 创建带挂载的静态容器
ctr c create docker.io/library/busybox:latest busybox3 --mount type=bind,src=/tmp,dst=/hostdir,options=rbind:rw
# 启动容器进程
ctr task start -d busybox3 bash
# 进入容器测试读写
ctr task exec --exec-id $RANDOM -t busybox3 sh
echo "hello world" > /hostdir/test.txt
exit
# 宿主机验证文件
cat /tmp/test.txt九、容器命名空间共享
支持新容器复用已有容器的 PID、网络等命名空间,实现容器间资源互通:
# 获取目标容器PID
pid=$(ctr tasks ls | grep busybox3 | awk '{print $2}')
# 共享PID命名空间创建新容器
ctr c create --with-ns "pid:/proc/$pid/ns/pid" docker.io/library/busybox:latest busybox4
ctr task start -d busybox4 bash十、Docker 集成 Containerd
Docker 底层默认依赖 Containerd,可手动指定接管,所有 Docker 容器实际由 Containerd 管理。
10.1 安装 Docker 并修改配置
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce修改 docker.service 启动参数,指定 Containerd 套接字:
ExecStart=/usr/bin/dockerd --containerd /run/containerd/containerd.sock --debug10.2 启动服务并验证
systemctl daemon-reload
systemctl enable docker
systemctl start docker
# 运行docker容器
docker run -d nginx:latest
# containerd 查看docker容器(moby命名空间)
ctr ns ls
ctr -n moby c ls
ctr -n moby task ls验证结论:Docker 运行的容器会被放置在
moby 命名空间,由 Containerd 统一管理。十一、核心总结
- 定位:Containerd 是云原生标准底层容器运行时,替代 Docker,适配 K8s 生产环境,轻量、稳定、高性能。
- 架构:插件化 C/S 架构,OCI 标准兼容,runC 负责容器运行,自身专注镜像、生命周期、存储网络管理。
- 核心能力:镜像管理、容器生命周期、CNI 网络、数据持久化、命名空间隔离、私有仓库对接。
- 生态兼容:支持 Docker 集成、K8s 原生适配、主流镜像加速器与私有仓库,是目前企业生产环境首选容器运行时。
