引言

随着云原生技术的快速发展,容器运行时技术栈正在经历深刻变革。从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命令

关键差异

镜像拉取

docker pull nginx:1.20

ctr i pull docker.io/library/nginx:1.20

必须完整镜像地址

镜像列表

docker images

ctr i ls

输出格式更详细

镜像导出

docker save -o nginx.tar nginx:1.20

ctr i export nginx.tar docker.io/library/nginx:1.20

需指定完整名称

镜像导入

docker load -i nginx.tar

ctr i import nginx.tar

语法更简单

创建容器

docker create --name my-nginx nginx:1.20

ctr c create docker.io/library/nginx:1.20 my-nginx

需指定镜像完整地址

启动容器

docker start my-nginx

ctr t start -d my-nginx

通过task子命令

进入容器

docker exec -it my-nginx sh

ctr t exec -t --exec-id demo1 my-nginx sh

需指定exec-id

查看进程

docker top my-nginx

ctr t ps my-nginx

输出格式不同

停止容器

docker stop my-nginx

ctr t kill my-nginx

命令名称不同

删除容器

docker rm my-nginx

ctr c rm my-nginx

语法类似

Containerd作为云原生时代的容器运行时标准,代表了从Docker垄断到开放生态的重要转变。通过本文的学习,你应该已经掌握了:

 技术演进背景:理解K8s放弃Docker的历史必然性

 核心架构设计:掌握Containerd的模块化设计思想

 实战操作技能:熟练使用ctr命令进行日常管理

 生产环境部署:具备企业级部署和调优能力

 迁移规划能力:能够制定和执行从Docker到Containerd的迁移方案

记住,技术选型没有绝对的对错,只有适合与否。对于不同场景:

  • 个人开发/学习:Docker仍然是最佳选择

  • 中小规模生产:可以考虑Docker + cri-dockerd

  • 大规模Kubernetes集群:Containerd是官方推荐方案

  • OpenShift/RHEL生态:CRI-O是更好的选

容器技术的未来是多元化的,掌握Containerd是构建云原生技能栈的重要

Logo

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

更多推荐