2024之际探讨一下k8s弃用docker的原因;

        目前正在学习k8s和docker,但是得知早在2020年k8s官方就已经发布了弃用docker的消息,且在k8s的1.24版本以后便不再维护dockershim,直接使用containerd作为容器运行时;如今,我很好奇这样做的原因,接下来咋们就详细的来探讨一下吧;


一、什么是容器运行时?

        为了深刻了解原因,首先需要知道容器运行时的概念:

         容器运行时(Container Runtime)是一种负责在操作系统层面创建和管理容器的软件工具或组件,主要任务包括创建和启动容器、管理容器文件系统、管理和限制资源、协助配置容器网络、保证容器与宿主机间相互隔离;

          docker和containerd都是比较常用的容器运行时,而containerd究竟是什么,他与docker之间的关系又是什么?

二、什么是containerd?

        在2016年12月14日,Docker公司宣布将containerddocker 中分离,并由开源社区独立发展、运营;containerd是docker的基础组件之一相较于docker来说更为纯粹,它更专注于镜像管理和容器执行,具有更小的资源占用,更快的启动时间,以及更好的性能表现;

主要任务包括:       

        • 管理容器的生命周期(从创建容器到销毁容器)
        • 拉取/推送容器镜像
        • 存储管理(管理镜像及容器数据的存储)
        • 调用 runC 运行容器(与 runC 等容器运行时交互)
        • 管理容器网络接口及网络ctr:containerd 的命令行客户端。
        
        既然docker和containerd都曾作为k8s的容器运行时,那我们就详细了解一下k8s运行的原理;
三、k8s是如何管理容器?

        k8s会调用容器运行时接口(CRI)去操作容器运行时,容器运行时遵循 OCI 规范,并通过 runc 来实现与操作系统内核的交互,以此完成容器的创建、运行、销毁等工作;

        CRI:k8s提供的插件接口,是k8s和容器运行时之间通讯的主要协议;其运行时会从k8s获取gRPC请求,再根据OCI规范来创建json配置;

        OCI:全称为Open Container Initiative,是一个轻量级,开放的治理结构,在 Linux 基金会的支持下成立,致力于围绕容器格式和运行时创建开放的行业标准。

        k8s提出CRI时候,docker刚拆出containerd,此时CPI与docker的调用完全不兼容;为了兼容当时已经很成熟的docker,k8s提出了一个折中的方案,称为docker shim

四、什么是docker shim?

        docker shim是k8s与docker两者间的适配器,也成为“垫片”;

        k8s会通过CRI接口调用docker shim,docker shim作为Server接受来自于CRI的请求,docker shim接受到请求后,再发给docker的dockerd去调用containerd ;

        此时在容器退出状态被 docker收集之前,shim 会一直存在,也会一直占用资源;

五、为什么弃用docker而选择contained;

        所以很明显,使用docker作为k8s的容器运行时的话,k8s的调用链为:

                k8s-->CRI-->docker shim-->dockerd-->containerd

        而如果直接使用containerd作为容器运行时的话,那调用链可以简化为:

                k8s-->CRI-->containerd

        可以看到,两个调用链的最终效果是完全一致的,但是第二条调用链因为去除了docker shimdockerd,不仅性能提高,而且因为链路变短,资源占用也会变小,同时也会更为稳定;

        从2018年k8s 1.10与containerd1.1集成的相关测试数据中可以看出,对比于docker,containerd1.1作为容器启动时,延迟降低了20%左右,CPU 使用率降低了 68%,内存使用率降低了 12%,这是一个很可观的数据;

        再者,k8s使用的只有docker的部分功能,多余的功能比如说网络或者存储卷这些很有可能会带来更多的安全隐患,所以弃用contained而选择docker是一个很明智的选择;


        我是chililopp,正在学习k8s,之后如果有新的总结或者体验也会发出来,如果有说的不对的地方,还请指点,十分感谢阅读!

### Kubernetes Docker原因 Kubernetes 决定Docker 作为其默认容器运行时的主要原因可以归结为技术演进与生态发展的需求。以下是对这一决策背后原因的详细分析: - **维护成本上升**:Kubernetes 在早期依赖于 Docker 的 `dockershim` 模块来实现对 Docker 的支持。然而,随着时间推移,这种耦合关系导致了额外的维护负担[^4]。由于 Docker 的架构设计并非完全符合 Kubernetes 对容器运行时的需求,因此需要通过中间层(如 `dockershim`)进行适配,这增加了复杂性和潜在的性能开销。 - **CRI 标准的引入**:为了降低对特定容器运行时的依赖,Kubernetes 社区在 2016 年推出了容器运行时接口(CRI)。CRI 提供了一种标准化的方式,允许 Kubernetes 与多种容器运行时进行交互。Docker 的架构未能直接满足 CRI 的要求,因此需要额外的适配层[^2]。 - **社区和技术发展**:随着容器生态系统的成熟,出现了更轻量级、更高效的容器运行时(如 `containerd` 和 `cri-o`),它们更加专注于实现 CRI 标准。这些运行时相比 Docker 更加模块化和高效,能够更好地满足 Kubernetes 的需求[^3]。 --- ### Kubernetes 替代 Docker 的方案 Kubernetes Docker 后,用户可以选择以下替代方案来作为容器运行时: - **containerd**:这是 Docker 自身的一部分,负责容器的生命周期管理。`containerd` 是一个独立的项目,完全支持 CRI,并且比 Docker 更加轻量化和高效。它可以直接与 Kubernetes 集成,无需额外的适配层。 - **cri-o**:这是一个专门为 Kubernetes 设计的轻量级容器运行时。`cri-o` 直接实现了 CRI 标准,专注于提供 Kubernetes 所需的功能,而不会引入额外的复杂性。它的设计目标是减少资源消耗并提高安全性[^4]。 - **其他兼容 CRI 的运行时**:除了上述两种主流选择外,还有其他一些符合 CRI 标准的容器运行时可供选择,例如 `frakti` 和 `kata-containers`。这些运行时可以根据具体需求提供不同的功能特性。 --- ### 示例代码:配置 Kubernetes 使用 containerd 以下是将 Kubernetes 配置为使用 `containerd` 的示例步骤: ```bash # 安装 containerd sudo apt-get update && sudo apt-get install -y containerd # 配置 containerd sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml # 重启 containerd 服务 sudo systemctl restart containerd # 确保 kubelet 使用 containerd cat <<EOF | sudo tee /etc/default/kubelet KUBELET_EXTRA_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock" EOF # 重启 kubelet sudo systemctl daemon-reload sudo systemctl restart kubelet ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值