个人随笔
目录
轻量级工业级容器运行时 Containerd 超全实战笔记
2026-06-27 18:07:43
一、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 containerd

2.1.2 执行安装

yum -y install containerd.io

2.1.3 启动服务并设置开机自启

# 查看安装结果
rpm -qa | grep containerd
# 开机自启 & 启动服务
systemctl enable containerd
systemctl start containerd
# 查看运行状态
systemctl status containerd

2.1.4 验证可用性

ctr version
输出客户端、服务端版本信息即为安装成功。

2.2 二进制生产级安装(推荐 K8s 环境)

2.2.1 安装包区别

  • containerd-xxx:单机测试包,不含 runC,需手动安装。
  • cri-containerd-cni-xxxK8s 专用包,内置 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.gz

2.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 version

2.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 ls

3.2.2 拉取镜像

# 拉取多平台镜像
ctr images pull --all-platforms docker.io/library/nginx:alpine
# 指定 amd64 平台
ctr images pull --platform linux/amd64 docker.io/library/nginx:alpine

3.2.3 镜像挂载(查看内部文件)

# 挂载镜像到 /mnt
ctr images mount docker.io/library/nginx:alpine /mnt
# 卸载
umount /mnt

3.2.4 镜像导出/导入

# 导出镜像
ctr images export --all-platforms nginx.img docker.io/library/nginx:alpine
# 导入镜像
ctr images import nginx.img

3.2.5 镜像删除

ctr images rm docker.io/library/nginx:alpine

3.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 ls

4.2.2 创建静态容器并启动

# 创建静态容器
ctr c create docker.io/library/nginx:alpine nginx1
# 启动任务(后台运行)
ctr task start -d nginx1

4.2.3 一键运行动态容器

# --net-host 共享宿主机网络
ctr run -d --net-host docker.io/library/nginx:alpine nginx2

4.2.4 进入容器终端

# exec-id 自定义唯一ID
ctr task exec --exec-id $RANDOM -t nginx2 /bin/sh

4.2.5 容器暂停/恢复

# 暂停容器
ctr task pause nginx2
# 恢复容器
ctr task resume nginx2

4.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.com

5.1.2 配置仓库镜像源

前文优化配置已内置 Harbor 镜像源,修改后重启服务:
systemctl restart containerd

5.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
默认命名空间:defaultk8s.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 jq

7.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 --debug

10.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 统一管理。

十一、核心总结

  1. 定位:Containerd 是云原生标准底层容器运行时,替代 Docker,适配 K8s 生产环境,轻量、稳定、高性能。
  2. 架构:插件化 C/S 架构,OCI 标准兼容,runC 负责容器运行,自身专注镜像、生命周期、存储网络管理。
  3. 核心能力:镜像管理、容器生命周期、CNI 网络、数据持久化、命名空间隔离、私有仓库对接。
  4. 生态兼容:支持 Docker 集成、K8s 原生适配、主流镜像加速器与私有仓库,是目前企业生产环境首选容器运行时。
 3

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2