Kubernetes生产环境Containerd迁移全指南:从Docker到高性能容器运行时

1. 为什么选择Containerd作为Kubernetes运行时?

在Kubernetes 1.24版本发布后,社区正式移除了对Docker作为容器运行时的默认支持。这一变化并非突然,而是经过多年技术演进的必然结果。Containerd作为CNCF毕业项目,已经成为云原生生态中容器运行时的标准实现。

性能对比数据

指标 Docker (with dockerd) Containerd
容器启动延迟 1.2s 0.8s
内存占用 350MB 120MB
CPU利用率 5-7% 2-3%
API响应时间 200ms 80ms

从架构上看,Containerd去掉了Docker中非必要的组件(如Docker API、Swarm等),使得调用链路更加简洁:

Docker运行时:kubelet → dockershim → dockerd → containerd
Containerd运行时:kubelet → CRI plugin → containerd

这种精简的架构带来了显著的性能提升,特别是在大规模集群中。某电商平台在迁移后报告:

  • 节点资源利用率提升15%
  • Pod启动时间减少40%
  • 运行时相关故障减少60%

2. 迁移前的准备工作

2.1 环境检查与兼容性验证

在开始迁移前,需要全面评估现有环境:

# 检查当前运行时
kubectl get nodes -o wide
kubectl describe node <node-name> | grep ContainerRuntime

# 验证Kubernetes版本
kubectl version --short

# 检查容器依赖
kubectl get pods --all-namespaces -o json | jq '.items[].spec.containers[].image' | sort -u

注意:确保所有工作负载都使用标准OCI镜像格式,避免依赖Docker特有功能

2.2 关键数据备份策略

迁移前必须建立完善的备份机制:

  1. 镜像备份

    # 使用skopeo工具批量备份镜像
    skopeo list-tags docker://<registry>/<image> | \
    jq -r '.Tags[]' | \
    xargs -I {} skopeo copy docker://<registry>/<image>:{} dir:./backup/{}
    
  2. 容器状态备份

    # 导出关键容器配置
    docker inspect <container-id> > container_backup.json
    
  3. Kubernetes资源备份

    kubectl get all --all-namespaces -o yaml > cluster_backup.yaml
    

3. 分步迁移实施指南

3.1 节点排空与运行时安装

采用滚动更新的方式逐节点迁移:

# 标记节点不可调度
kubectl cordon <node-name>

# 排空节点
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# 安装Containerd
apt-get install -y containerd.io

# 配置Containerd
containerd config default > /etc/containerd/config.toml
systemctl restart containerd

3.2 镜像迁移与命名空间管理

Containerd使用命名空间隔离不同环境的镜像,Kubernetes专用镜像需存入k8s.io命名空间:

# 导出Docker镜像
docker save nginx:latest > nginx.tar

# 导入到Containerd
ctr -n=k8s.io images import nginx.tar

# 验证镜像
ctr -n=k8s.io images ls

常见镜像操作对照表

操作 Docker命令 Containerd命令
列出镜像 docker images ctr -n k8s.io images ls
拉取镜像 docker pull ctr -n k8s.io images pull
推送镜像 docker push ctr -n k8s.io images push
删除镜像 docker rmi ctr -n k8s.io images rm
查看镜像详情 docker inspect crictl inspecti

3.3 容器操作命令转换

对于日常运维,推荐使用crictl工具(兼容CRI接口):

# 安装crictl
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.24.0/crictl-v1.24.0-linux-amd64.tar.gz
tar zxvf crictl-*.tar.gz -C /usr/local/bin

常用容器操作对照

操作 Docker命令 crictl命令
列出容器 docker ps crictl ps
创建容器 docker create crictl create
启动容器 docker start crictl start
停止容器 docker stop crictl stop
查看容器日志 docker logs crictl logs
执行命令 docker exec crictl exec

4. 生产环境验证与优化

4.1 迁移后验证清单

  1. 基础功能验证

    # 运行测试Pod
    kubectl run -it --rm --restart=Never test-pod --image=busybox -- sh
    
    # 检查存储挂载
    kubectl exec test-pod -- mount | grep volumes
    
    # 网络连通性测试
    kubectl exec test-pod -- ping -c 3 kubernetes.default
    
  2. 性能基准测试

    # 使用kube-bench进行安全检查
    docker run --rm --pid=host -v /etc:/etc:ro -v /var:/var:ro aquasec/kube-bench:latest node
    
    # 使用clusterloader2进行压力测试
    ./clusterloader --kubeconfig=/root/.kube/config \
      --nodes=1000 \
      --testconfig=testing/density/config.yaml
    

4.2 常见问题排查指南

问题1:镜像拉取失败

解决方案:

# 检查镜像拉取密钥
kubectl get secret --all-namespaces

# 查看Pull事件
kubectl get events --field-selector involvedObject.kind=Pod

问题2:容器启动超时

检查点:

  1. 查看containerd日志: journalctl -u containerd -n 100
  2. 验证CRI插件状态: ctr plugin ls | grep cri
  3. 检查cgroup驱动一致性:
    docker info | grep Cgroup
    kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.containerRuntimeVersion}{"\n"}{end}'
    

5. 混合环境下的CI/CD适配

虽然生产环境使用Containerd,但开发构建环节可能仍需Docker:

# 在Kubernetes中部署DinD(Docker in Docker)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dind
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dind
  template:
    metadata:
      labels:
        app: dind
    spec:
      containers:
      - name: dind
        image: docker:dind
        securityContext:
          privileged: true
        ports:
        - containerPort: 2375

配置CI系统使用远程Docker:

export DOCKER_HOST=tcp://<dind-service>:2375
docker build -t my-app .
docker push my-registry/my-app

构建与运行分离架构

[CI系统] → [DinD服务] → 推送镜像到仓库 → [K8s集群 with Containerd]拉取运行

6. 高级配置与性能调优

6.1 存储驱动优化

Containerd支持多种存储驱动,推荐配置:

[plugins."io.containerd.grpc.v1.cri".containerd]
  snapshotter = "overlayfs"
  disable_snapshot_annotations = true

性能对比:

  • overlayfs:兼容性好,适合大多数场景
  • btrfs:高性能但需要特定文件系统支持
  • zfs:适合需要高级存储功能的场景

6.2 镜像拉取加速

配置镜像仓库mirror:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://registry-1.docker.io", "https://mirror.gcr.io"]

6.3 资源限制配置

调整Containerd资源使用:

[plugins."io.containerd.runtime.v1.linux"]
  runtime = "io.containerd.runc.v2"
  [plugins."io.containerd.runtime.v1.linux".options]
    SystemdCgroup = true
    NoPivotRoot = false
    NoNewKeyring = false

7. 监控与日志管理新范式

7.1 运行时指标采集

配置Prometheus监控Containerd:

scrape_configs:
  - job_name: 'containerd'
    static_configs:
      - targets: ['localhost:1338']
    metrics_path: '/metrics'

关键监控指标:

  • container_cpu_usage_seconds_total
  • container_memory_working_set_bytes
  • container_fs_usage_bytes

7.2 日志收集调整

由于不再使用Docker,日志路径发生变化:

/var/log/pods/<namespace>_<pod-name>_<pod-uid>/<container-name>/<restart-count>.log

推荐Fluent Bit配置:

[INPUT]
    Name              tail
    Tag               kube.*
    Path              /var/log/pods/*/*/*.log
    Parser            docker
    DB                /var/log/flb_kube.db
    Mem_Buf_Limit     5MB
    Skip_Long_Lines   On

更多推荐