Containerd指南:从Docker到K8s的容器运行时
操作类别Docker命令Containerd命令关键差异镜像拉取必须完整镜像地址镜像列表ctr i ls输出格式更详细镜像导出需指定完整名称镜像导入语法更简单创建容器需指定镜像完整地址启动容器通过task子命令进入容器需指定exec-id查看进程输出格式不同停止容器命令名称不同删除容器语法类似Containerd作为云原生时代的容器运行时标准,代表了从Docker垄断到开放生态
引言
随着云原生技术的快速发展,容器运行时技术栈正在经历深刻变革。从Docker一家独大到Kubernetes生态下的多元化选择,Containerd作为新一代容器运行时标准,正在成为企业级容器平台的核心基石。本文将带你深入了解Containerd的技术演进、架构设计和实战应用。
一、Kubernetes与Docker的世纪变革
1. 从共生到分离:K8s放弃Docker的背后



关键对比:
|
运行时 |
CRI支持 |
适配层 |
通信开销 |
推荐程度 |
|---|---|---|---|---|
|
Docker |
不支持 |
Dockershim |
高 |
❌ 不推荐 |
|
Containerd |
原生支持 |
无 |
低 |
✅ 推荐 |
|
CRI-O |
原生支持 |
无 |
低 |
✅ 推荐 |
迁移策略:1.24版本后的Docker使用
对于仍需使用Docker的场景,可以通过cri-dockerd实现兼容:
# 安装cri-dockerd适配器
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.1/cri-dockerd-0.3.1.amd64.tgz
tar -xzf cri-dockerd-0.3.1.amd64.tgz
sudo mv cri-dockerd /usr/local/bin/
# 创建systemd服务
cat <<EOF | sudo tee /etc/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd://
Restart=always
RestartSec=2s
[Install]
WantedBy=multi-user.target
EOF
# 配置kubelet使用cri-dockerd
cat <<EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS="--container-runtime=remote \
--container-runtime-endpoint=unix:///var/run/cri-dockerd.sock \
--image-service-endpoint=unix:///var/run/cri-dockerd.sock"
EOF
二、Containerd深度解析与安装部署
1. Containerd架构设计
Containerd最初是Docker的核心组件,2016年捐赠给CNCF基金会后独立发展,成为云原生生态的基础设施。
2. 生产环境安装指南
2.1 系统准备与依赖安装
#!/bin/bash
# install-containerd.sh
# 1. 系统环境检查
echo " 检查系统环境..."
if [[ $(id -u) -ne 0 ]]; then
echo " 请使用root权限执行此脚本"
exit 1
fi
# 检查操作系统
OS_ID=$(grep "^ID=" /etc/os-release | cut -d= -f2 | tr -d '"')
OS_VERSION_ID=$(grep "^VERSION_ID=" /etc/os-release | cut -d= -f2 | tr -d '"')
echo "系统: $OS_ID $OS_VERSION_ID"
# 2. 安装依赖
echo " 安装依赖包..."
case $OS_ID in
"centos"|"rhel"|"rocky"|"almalinux")
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
;;
"ubuntu"|"debian")
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
;;
*)
echo " 不支持的操作系统: $OS_ID"
exit 1
;;
esac
# 3. 安装Containerd
echo " 安装Containerd..."
if command -v apt-get &> /dev/null; then
apt-get install -y containerd.io
elif command -v yum &> /dev/null; then
yum install -y containerd.io
fi
# 4. 查看可用版本
echo " 查看可用版本:"
yum list --showduplicates containerd.io 2>/dev/null || apt-cache madison containerd.io 2>/dev/null
# 5. 配置Containerd
echo " 生成默认配置..."
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 修改配置以使用systemd cgroup
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 6. 启动服务
echo " 启动Containerd服务..."
systemctl daemon-reload
systemctl enable --now containerd
systemctl status containerd --no-pager
# 7. 验证安装
echo "验证安装..."
containerd --version
ctr version
echo " Containerd安装完成!"
三、Containerd核心命令实战
1. 镜像管理:从Docker到Containerd的思维转变

3.1 镜像拉取与管理对比
# Docker方式(熟悉的操作)
docker pull nginx:1.20
docker images
docker tag nginx:1.20 my-nginx:v1
docker save nginx:1.20 -o nginx.tar
docker rmi nginx:1.20
# Containerd方式(需要适应的新语法)
# 必须使用完整镜像地址!
ctr images pull docker.io/library/nginx:1.20
ctr images ls
ctr tag docker.io/library/nginx:1.20 docker.io/library/my-nginx:v1
ctr images export nginx.tar docker.io/library/nginx:1.20
ctr images rm docker.io/library/nginx:1.20
3.2 多平台镜像处理
# 查看镜像支持的平台
ctr images ls --format json | jq -r '.[] | "\(.name) - \(.target.platform.os)/\(.target.platform.architecture)"'
# 拉取特定平台的镜像
ctr images pull --platform linux/amd64 docker.io/library/nginx:1.20
ctr images pull --platform linux/arm64 docker.io/library/nginx:1.20
# 拉取所有平台的镜像(用于导出/导入)
ctr images pull --all-platforms docker.io/library/nginx:1.20
# 导出多平台镜像
ctr images export --all-platforms nginx-multi.tar docker.io/library/nginx:1.20
# 导入多平台镜像
ctr images import nginx-multi.tar
2. 容器管理:创建、运行与监控
2.1 容器生命周期管理
#!/bin/bash
# containerd_container_demo.sh
echo " Containerd容器生命周期管理演示"
# 1. 创建容器(不启动)
echo "1. 创建nginx容器..."
ctr containers create \
--snapshotter overlayfs \
--net-host \
docker.io/library/nginx:1.20 \
nginx-demo
echo " 容器创建完成,查看容器列表:"
ctr containers ls
# 2. 启动容器任务
echo -e "\n2. 启动容器任务..."
ctr task start -d nginx-demo
echo " 任务启动完成,查看任务列表:"
ctr task ls
# 3. 查看容器进程
echo -e "\n3. 查看容器内进程:"
ctr task ps nginx-demo
# 4. 进入容器
echo -e "\n4. 进入容器执行命令:"
echo "当前时间:" && ctr task exec --exec-id demo1 nginx-demo date
echo "Nginx版本:" && ctr task exec --exec-id demo2 nginx-demo nginx -v
# 5. 暂停与恢复
echo -e "\n5. 暂停容器任务..."
ctr task pause nginx-demo
sleep 2
echo "任务状态:" && ctr task ls
echo -e "\n恢复容器任务..."
ctr task resume nginx-demo
echo "任务状态:" && ctr task ls
# 6. 停止容器
echo -e "\n6. 停止容器任务..."
ctr task kill nginx-demo
ctr task rm nginx-demo
# 7. 删除容器
echo -e "\n7. 删除容器..."
ctr containers rm nginx-demo
echo -e "\n 容器生命周期演示完成!"
echo "最终容器列表:"
ctr containers ls
3. 网络配置:从无网络到生产就绪
3.1 Containerd默认网络限制

3.2 使用CNI插件配置网络
#!/bin/bash
# setup-containerd-cni.sh
echo " 配置Containerd CNI网络"
# 1. 安装CNI插件
echo "1. 安装CNI插件..."
CNI_VERSION="v1.3.0"
mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" \
| tar -C /opt/cni/bin -xz
# 2. 创建网络配置
echo "2. 创建网络配置..."
mkdir -p /etc/cni/net.d
cat > /etc/cni/net.d/10-mynet.conf << EOF
{
"cniVersion": "0.4.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.22.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
EOF
# 3. 配置Containerd使用CNI
echo "3. 配置Containerd..."
cat >> /etc/containerd/config.toml << EOF
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
EOF
# 4. 重启Containerd
echo "4. 重启Containerd..."
systemctl restart containerd
# 5. 测试网络
echo "5. 测试网络配置..."
cat > /tmp/test-cni.json << EOF
{
"cniVersion": "0.4.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.22.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
EOF
# 创建测试容器
ctr run --runtime=io.containerd.runc.v2 --net-host \
docker.io/library/alpine:latest test-cni sh -c "ip addr show"
echo " CNI网络配置完成!"
五、总结
1. 技术选型决策矩阵

2. 核心命令对比速查表
|
操作类别 |
Docker命令 |
Containerd命令 |
关键差异 |
|---|---|---|---|
|
镜像拉取 |
|
|
必须完整镜像地址 |
|
镜像列表 |
|
|
输出格式更详细 |
|
镜像导出 |
|
|
需指定完整名称 |
|
镜像导入 |
|
|
语法更简单 |
|
创建容器 |
|
|
需指定镜像完整地址 |
|
启动容器 |
|
|
通过task子命令 |
|
进入容器 |
|
|
需指定exec-id |
|
查看进程 |
|
|
输出格式不同 |
|
停止容器 |
|
|
命令名称不同 |
|
删除容器 |
|
|
语法类似 |
Containerd作为云原生时代的容器运行时标准,代表了从Docker垄断到开放生态的重要转变。通过本文的学习,你应该已经掌握了:
技术演进背景:理解K8s放弃Docker的历史必然性
核心架构设计:掌握Containerd的模块化设计思想
实战操作技能:熟练使用ctr命令进行日常管理
生产环境部署:具备企业级部署和调优能力
迁移规划能力:能够制定和执行从Docker到Containerd的迁移方案
记住,技术选型没有绝对的对错,只有适合与否。对于不同场景:
-
个人开发/学习:Docker仍然是最佳选择
-
中小规模生产:可以考虑Docker + cri-dockerd
-
大规模Kubernetes集群:Containerd是官方推荐方案
-
OpenShift/RHEL生态:CRI-O是更好的选
容器技术的未来是多元化的,掌握Containerd是构建云原生技能栈的重要
更多推荐

所有评论(0)