Containerd指南:从Docker到K8s的容器运行时

引言

随着云原生技术的快速发展,容器运行时技术栈正在经历深刻变革。从Docker一家独大到Kubernetes生态下的多元化选择,Containerd作为新一代容器运行时标准,正在成为企业级容器平台的核心基石。本文将带你深入了解Containerd的技术演进、架构设计和实战应用。

一、Kubernetes与Docker的世纪变革

1. 从共生到分离:K8s放弃Docker的背后

关键对比

运行时 CRI支持 适配层 通信开销 推荐程度
Docker 不支持 Dockershim ❌ 不推荐
Containerd 原生支持 ✅ 推荐
CRI-O 原生支持 ✅ 推荐
迁移策略:1.24版本后的Docker使用

对于仍需使用Docker的场景,可以通过cri-dockerd实现兼容:

bash 复制代码
# 安装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 系统准备与依赖安装
bash 复制代码
#!/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 镜像拉取与管理对比
bash 复制代码
# 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 多平台镜像处理
bash 复制代码
# 查看镜像支持的平台
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 容器生命周期管理
bash 复制代码
#!/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插件配置网络
复制代码
bash 复制代码
#!/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是构建云原生技能栈的重要

相关推荐
后端小张2 小时前
【JAVA进阶】Docker 2025完全指南:从容器入门到企业级实践
java·运维·开发语言·spring·docker·容器·springboot
Hui Baby2 小时前
K8S蓝绿发布
java·容器·kubernetes
一周困⁸天.2 小时前
K8S-Helm
容器·kubernetes
DeepFlow 零侵扰全栈可观测2 小时前
金山办公基于 DeepFlow docker 模式的可观测性实践
运维·docker·容器
驾驭人生3 小时前
SSH 服务部署 + Docker(指定版本)完整安装 的一体化操作流程
运维·docker·ssh
珂玥c3 小时前
Rook部署——k8s集群中使用ceph
运维·ceph·kubernetes
一点晖光13 小时前
Docker 作图咒语生成器搭建指南
python·docker
qianshuaiblog.cn13 小时前
Kubernetes安装部署
云原生·容器·kubernetes
Empty_77716 小时前
K8S-中的优先级
云原生·容器·kubernetes