网站首页 > 教程文章 正文
从Docker到Containerd:Kubernetes容器运行时升级全解析
一、背景:Kubernetes容器运行时演进史
自2020年Kubernetes 1.20版本宣布弃用Docker作为默认容器运行时以来,容器技术生态经历了重大变革。作为CNCF毕业项目,Containerd凭借其轻量化架构、原生CRI支持和卓越性能表现,逐渐成为云原生时代的首选运行时。截至2025年,超过80%的生产级K8s集群已完成运行时升级,这场技术迁移浪潮背后的驱动力值得深入探究。
二、Containerd核心优势解析
1. 架构精简度对比
指标 | Docker | Containerd |
守护进程数量 | 3 (Docker,containerd,runC) | 1 (containerd) |
内存占用 | 100MB+ | 30-50MB |
CRI调用链路 | 需Docker-shim转换 | 原生支持 |
冷启动时间 | 1.2s | 0.8s |
(数据来源:CNCF 2024容器运行时基准测试报告)
2. 关键技术优势
- 原生CRI集成:消除Docker-shim带来的性能损耗
- 资源占用优化:减少30%的节点内存开销
- 安全增强:最小化攻击面,符合NSA/CISA容器安全基线
- 镜像管理革新:支持Stargz懒加载,加速大规模镜像分发
三、生产环境迁移流程
说明:我们公司使用rancher来管理和搭建集群,rancher本身是不支持指定节点来滚动升级的,我们二开了rancher,增加了指定节点来升级节点kubelet、kube-proxy等组件
###下面打标签都是在rancher的local集群进行,标签对master节点不生效
### 下面所有的nodes资源指的是 rancher的 crd nodes.management.cattle.io
# 跳过升级节点,会阻塞整个集群的升级状态,当集群升级时根据需求要逐渐删除该label。所有nodes没有这个label时,集群更新成功,状态为正常
qihoo.net/upgrade=false
# nodes资源加上该标签,会忽略带标签的节点,该label不回阻塞升级过程,其他节点更新完成功后,集群状态会正常
qihoo.net/upgrade=ignore
1. 迁移前准备
# 集群状态备份: 通过rancher页面,备份集群数据(集群状态,etcd数据等)
# 环境兼容性检测
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
# 输出预期结果应包含"Docker"标识
#安装命令行工具crictl nerdctl
wget http://xxxx.qihoo.net/kubernetes/crictl
chmod +x crictl
mv crictl /usr/bin/
cat <<EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
wget http://xxx.qihoo.net/kubernetes/nerdctl
chmod +x nerdctl
mv nerdctl /usr/bin/
# 集群需要升级containerd节点暂时先全部打上label
#获取nodes
kubectl get nodes.management.cattle.io -n c-9vk5r
#集群所有需要升级nodes节点打上暂停升级标签
kubectl label nodes.management.cattle.io -n c-xxxx m-xxxxxxxx qihoo.net/upgrade=false
#集群中不需要升级的集群打上忽略标签
kubectl label nodes.management.cattle.io -n c-zv6zb m-xxxxxxx qihoo.net/upgrade=ignore
2. 升级master节点
# 把集群master节点的pod驱逐;确认相关系统组件的pod调度到其它机器并正常运行;
kubectl drain xxxxxx.qihoo.net --ignore-daemonsets --delete-local-data --grace-period=0
#更改containerd的/etc/containerd/config.toml配置文件并重启containerd、docker等
systemctl daemon-reload
systemctl restart containerd
systemctl restart docker
docker restart etcd service-sidekick kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy
# 重建master节点上的daemonset的pod
HOSTNAME=$(hostname)
for i in $(kubectl get pod -A -owide |grep ${HOSTNAME}|awk '{print $1"@"$2}')
do
ns=$(echo $i|awk -F'@' '{print $1}')
po=$(echo $i|awk -F'@' '{print $2}')
kubectl delete po -n${ns} ${po} --force
done
更改rancher中集群配置使用containerd
修改完成后,集群会升级master节点,等待master节点升级完成,原有的master上的ds的 pods 默认会重新创建;在重建过程中,对于一些 其他pod,可能需要人工干预去重建,然后在清理docker运行时下的残留进程。
检查master节点升级成功,确保上面的pod正常。
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
3. 按照滚动比例升级node节点
1、需要升级的节点先驱逐,然后删除对应rancher nodes 资源的label,就开始升级
#驱逐节点
kubectl drain xxxxxx.qihoo.net --ignore-daemonsets --delete-emptydir-data --grace-period=0 --force
# 参考第(1)步骤中的 更改containerd配置,并重启containerd docker 等
systemctl daemon-reload
systemctl restart containerd
systemctl restart docker
docker restart kubelet kube-proxy nginx-proxy
# 删除对应机器label,机器开始升级;注意更换 -n c-zv6zb m-3ba9e952bcfb
kubectl label nodes.management.cattle.io -n c-zv6zb m-3ba9e952bcfb qihoo.net/upgrade-
# 等机器更新完成后,删除机器上的daemonset的pod
HOSTNAME=$(hostname)
for i in $(kubectl get po -A -owide |grep ${HOSTNAME}|awk '{print $1"@"$2}')
do
ns=$(echo $i|awk -F'@' '{print $1}')
po=$(echo $i|awk -F'@' '{print $2}')
kubectl delete po -n${ns} ${po} --force
done
# 查看 node 运行时为 containerd
四、企业级实践案例
案例:公司迁移成效
指标 | 迁移前(Docker) | 迁移后(Containerd) | 提升幅度 |
Pod启动延迟 | 2.3s | 1.1s | 52% |
节点内存占用 | 1.8GB | 1.2GB | 33% |
CVE漏洞数量 | 12个/季度 | 3个/季度 | 75% |
CI/CD流水线耗时 | 14分钟 | 9分钟 | 36% |
五、常见问题解决方案
Q1: 如何兼容遗留Docker命令?
# 安装nerdctl增强工具
sudo containerd-rootless-setuptool.sh install
alias docker=nerdctl
Q2: 镜像存储如何迁移?
# 导出Docker镜像
docker save myapp:v1 > myapp.tar
# 导入Containerd
nerdctl load -i myapp.tar
Q3: 监控体系如何适配?
推荐部署方案:
- Prometheus + cAdvisor 2.8+(支持Containerd指标)
- Grafana仪表盘ID 13105(Containerd专项监控模板)
六、未来演进方向
随着2025年Kubernetes 1.30版本发布,容器运行时生态将迎来新变革:
- WasmEdge集成:支持WebAssembly工作负载
- 硬件加速支持:NVIDIA Container Toolkit 3.0深度优化
- 统一镜像规范:OCI Artifact全面普及
结语
容器运行时的升级不仅是技术组件的简单替换,更是云原生架构持续进化的必经之路。选择Containerd不仅意味着获得性能提升,更是拥抱开放标准的战略决策。建议结合自身技术栈,制定渐进式迁移计划,充分利用CNCF生态工具链实现平滑过渡。
猜你喜欢
- 2025-07-07 网络安全干货知识 | 手把手搭建 k8s docker 漏洞环境
- 2025-07-07 docker+k8s 报错(k8s docker login)
- 2025-07-07 轻松掌握k8s安装(使用docker)知识点
- 2025-07-07 什么是 k8s(Kubernetes)?Docker 与 Kubernetes选择哪一个?
- 2025-07-07 从 Docker 到 K8s:初学者常见的误区盘点
- 2025-07-07 Docker容器是什么?K8s和它有什么关系呢?
- 2025-07-07 Docker 是什么? 它与K8S之间是什么关系?
- 2025-07-07 Docker是什么?K8s是什么?如何从0到1实现Docker与K8s全流程部署
- 2025-07-07 K8S与Docker的区别(k8s与docker的区别是啥)
- 2025-07-07 想学K8s,必须得先学会Docker吗?(k8s自学难吗)
- 最近发表
-
- 网络安全干货知识 | 手把手搭建 k8s docker 漏洞环境
- docker+k8s 报错(k8s docker login)
- K8s 集群运行时:从 Docker 升级到 Containerd
- 轻松掌握k8s安装(使用docker)知识点
- 什么是 k8s(Kubernetes)?Docker 与 Kubernetes选择哪一个?
- 从 Docker 到 K8s:初学者常见的误区盘点
- Docker容器是什么?K8s和它有什么关系呢?
- Docker 是什么? 它与K8S之间是什么关系?
- Docker是什么?K8s是什么?如何从0到1实现Docker与K8s全流程部署
- K8S与Docker的区别(k8s与docker的区别是啥)
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)