GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

Kubernetes 决定弃用 Docker,到底会影响到谁?

2020 年 12 月 10 日

Kubernetes决定弃用Docker,到底会影响到谁?

导读:Kubernetes 在其最新的 Changelog 中宣布,自 Kubernetes 1.20 之后将弃用 Docker 作为容器运行时。那么这到底是怎么回事?开发者和企业会受到什么样到影响?


近几年,Kubernetes 已经成为自有机房、云上广泛使用的容器编排方案,最广泛的使用方式是 Kubernetes+Docker。从 DevOps 人员的角度,一面用 kubctl 命令、k8s API 来操作集群,一面在单机用 Docker 命令来管理镜像、运行镜像。


单独用 Docker 的情况,在一些公司的场景里面也是有的。一种场景是“只分不合”,把一台机器用 Docker 做资源隔离,但是不需要将多容器“编排”。单独用 Kubernetes,下层不是 Docker 的情况,并不算很多。


Kubernetes 和 Docker 的关系,简单来说,有互补,也有竞争。在一般的认知中,Kubernetes 和 Docker 是互补关系:


  • Dockers 属于下层——容器引擎;

  • Kubernetes 属于上层——编排调度层。


Docker 源于 Linux Container,可以将一台机器的资源分成 N 份容器,做到资源的隔离,并将可运行的程序定义为标准的 docker image;Kubernetes 则可以把不同机器的每份容器进行编排、调度,组成分布式系统。


Kubernetes 和 Docker 并不完全是“泾渭分明”的互补关系,它之间有重叠部分,也可以说成是竞争,主要在于几个点:


  • 系统三大移植资源是计算、存储、网络,从 Kubernetes 角度 Docker 属于“Runtime(运行时)”,也就是计算资源;但是 Docker 技术体系里面,本身也包括存储层、网络层。上下层职责的重叠,也可以看作竞争。

  • Docker 原本有个原生的调度引擎——Swarm,几年前在调度编排领域,还是 Kubernetes、Mesos、Swarm 三者并存,Kubernetes 最终胜出,但 Docker 仍有“继续向上做一层的意愿”。



Kubernetes 在如何使用 Docker 方面,存在争议和变数。kubernetes 1.20 ChangeLog 中所谓要废弃 Docker 的传言,也是无风不起浪。换句话说,即便 Kubernetes 一直用 Docker,也不是用 Docker 的全部,多少是不一样的。



而且,“弃用 Docker”这个词本身有多重的含义,Docker 并非一个单层软件,Kubernetes 1.20 启用 dockershim 并不代表弃用了 Docker 的全部,仍有 containerd 可以对接 docker。

Kubernetes 有 CRI、OCI 两个容器标准


在目前广泛使用 kubernetes 与 Runtime 的桥接方案,CRI(Container Runtime Interface)与 OCI(Open Container Initiative)是“套娃“关系。Kubernetes 的 kubelet 调用 CRI,OCI 的实现者然后再调用 OCI。


下图也说明了 CRI 与 OCI 的关系:



从 Kubernetes 的角度,CRI 是与 CNI(网络)、CSI(存储)相同层级的接口。


OCI 是个自下而上的标准,也就是从实现抽象出接口,它是 Linux Foundation 主导的。Docker 实现的核心 RunC,也就是 OCI 的典型实现、标准实现。


CRI 是个自上而下的标准,源于 Kubernetes 对移植层(运行时)的要求。


容器引擎层自下而上定义 OCI,容器编排层自上而下定义 CRI,这也让它们出现了“套娃“运行情况。


在 Kubernetes 的 dockershim、cri-containerd、cri-o 三种实现中,RedHat 推崇的 cri-o 已经比较主流,它虽然仍是“套娃“,但已经比较精简。



下面是从 kubernetes 集群运行的全景图看 cri-o 的位置:



Docker 本源于 Linux Container


Docker 作为容器引擎,其实现的基础是 Linux Container——从内核到用户空间的机制。


Linux Container 可以分成两个部分,内核里面的 cgroup,用户空间的 lxc。Docker 最初实现的时候,也是完全基于 Linux Container 的,基于 lxc 做更上层的东西。


这张很多人认为“与事实不符“的图,其实代表了过去:



在 Docker 的发展过程中,最终启用了 C 语言写成 lxc,换成了 go 语言写成的 libcontainer。


下面的图也不是很新,但它更能表示 Docker 后续典型的架构,这里面已经没有了 lxc。



然而,万变不离其宗,Docker 实现的本源,还是 Linux Container。即便不用 lxc,当仍要用内核的 cgroup,并且模式也是类似的。

Kubernetes 最终如何桥接容器


从纯技术的角度,与其讨 Kubernetes 与 Docker 关系,不如讨论 Kubernetes 与最终容器实现层的关系。因为 Docker 这个名词,在不同的时候,有着不同的内涵、外延。


下面是 Docker 的简图:



从软件模块的角度,图中的 docker Engine、cri-containd、containd-shim、runC 都属于 Docker 体系的软件。


下图中的紫、橙、红三种颜色,代表了 dockershim、cri-containerd、cri-o 三种 CRI 的典型方式——流程在逐渐缩短,这也是 CRI 实现的一个演进过程。



如果是 kubelet 的 dockershim 模式(紫色),流程是这样的:


  1. kubelet 从 CRI 的 gRPC 调用 dockershim,二者在同一个进程

  2. dockershim 调用 docker 守护进程

  3. docker 守护进程调用 containerd;containerd 调用 containerd-shim(有时名为 docker-containerd-shim 守护进程)完成创建容器等操作

  4. containerd-shim 访问 OCI 的实现 runC(命令行可执行程序)


如果是 kubelet 的 cri-containerd 模式(橙色),流程是这样的:


  1. kubelet 从 CRI 的 gRPC 调用 cri-containerd;

  2. cri-containerd 调用 containerd;containerd 调用 containerd-shim(同上)

  3. containerd-shim 调用 RucnC (同上);


在很多人的印象中,如果不用 docker 守护进程,就相当于“弃用 docker“,这其实也就是从 dockershim 到 containerd 的变化。从另一个角度来说,containerd 这个守护进程,也是 docker 组织做的。


如果是 kubelet 的 cri-o 模式(红色),则更加简练:


  1. kubelet 从 CRI 的 gRPC 调用 cri-o;

  2. cri-o 调用 OCI 的实现 runC


如果以 kubelet 调用 CRI 为起点,OCI 的 runC 调用为终点,三种模式经历的可执行程序分别是:


  • dockershim 模式:dockershim(*)->dockd->containerd->containerd-shim

  • cri-containerd 模式:cri-containerd(*)-> containerd->containerd-shim

  • cri-o 模式:cri-o


dockershim 模式有 3 个可执行程序,dockershim 一般与 kubelet 同进程;cri-containerd 模式有 2-3 个可执行程序,cri-containerd 可与 containerd 同进程;cri-o 模式只有 1 个可执行程序。


显然在这种 Red Hat 推崇的 cri-o 模式下,Docker 体系的 containerd 也用不着了,只剩 runC 这个命令行的程序。runC 也是用 go 写成的,里面有调用 libcontainer。


当 Docker 萎缩到这个地步,其实也只剩 Linux 内核里面 cgroup、namespace 功能的封装了。


总结来说,由于老技术实现的惯性,在生产环境大量使用的经典 Kubernetes+ Docker 方案依然运行,且运维已经成熟,不会很快升级。对于开发人员、企业,对于 K8S API 的使用频率、变数,远远大于 Docker API,至于 Kubernetes 和 Docker 的桥接,更不用关心。因此,即便“彻底弃用 Docker”,对开发者与企业的影响也非常有限。


作者介绍:


杨明越,现从事分布式系统、云架构方面工作,具有全方位的技术,曾任新兴互联网公司(BAT)的主任架构师,世界顶级芯片公司的 OS 技术专家,前 Top2 通讯公司高级工程师。


2020 年 12 月 10 日 15:384592

评论 1 条评论

发布
用户头像
Open Container Initiative (OCI) , not Oracle Call Interface
2020 年 12 月 10 日 16:56
回复
没有更多了
发现更多内容

寻找音乐API接入正版音乐曲库?了解HIFIVE音乐开放平台!

HIFIVE嗨翻屋

音乐api 正版曲库 音乐sdk

阿里巴巴研究员叔同:云原生是企业数字创新的最短路径

阿里云原生团队

云计算 Serverless 容器 云原生 Faas

区块链农产品溯源--保护舌尖上的安全

13530558032

tensorflow实现两种图像风格融合 即神经风格迁移

AI_robot

tensorflow实现低分辨率灰度图像分类算法

AI_robot

NodeJs中Buffer与Stream理解

小风以北

stream 原理 Node buffer

最全Java架构师技能树:Java编程+网络+设计模式+数据库+分布式

钟奕礼

Java 编程 程序员 架构 面试

民国最出名的女作家,为什么是她?

了了Vita

tensorflow实现深度卷积生成对抗网络(DCGAN)生成手写数字图片

AI_robot

专访孙立坚:印度经济发展实力几何 ?

了了Vita

深入分析小程序运行环境框架原理

小风以北

小程序 编译原理 框架 工作原理

阿里天猫3面(Java研发):GC回收+Redis Hash算法+架构部署+秒杀等

钟奕礼

Java 编程 程序员 架构 面试

iOS开发:关于UILabel、UIButton、UITextField文字下划线的设置方法(涉及到富文本的知识)

花花

ios

keras深度学习框架

AI_robot

springboot+redis+rabbitmq实现模拟秒杀系统(附带docker安装mysql,rabbitmq,redis教程)

yk

redis Docker 高并发 RabbitMQ

如何在游戏中快速集成聊天功能

LeanCloud

游戏开发 即时通讯 聊天室 sdk

《月亮与六便士》:给你500万,你会用它买套房子还是周游世界?

了了Vita

iOS开发:git上传代码到开源中国的步骤,以及pod的更新方法

花花

ios

面对不可避免的故障,我们造了一个“上帝视角”的控制台

阿里巴巴云原生

容器 微服务 云原生 监控 应用服务中间件

最新阿里蚂蚁金服四面(已拿offer)Java技术面经总结

钟奕礼

Java 编程 程序员 架构 面试

iOS开发:过滤网络请求中,服务器返回空值null数据的处理(过滤null显示问题)

花花

ios

芯翌科技:技术理想主义的务实之旅

朋湖网

百度面试被算法血虐,闭关29天肝完445页算法神仙笔记成功入职字节跳动!

Java成神之路

Java 程序员 架构 面试 编程语言

Java面试过了京东五面之后,发现掌握了这些技术也没有那么难

钟奕礼

Java 编程 程序员 架构 面试

GitHub标星150K的神仙笔记,3个月肝完成功面进美团定级3-2

Java成神之路

Java 程序员 架构 面试 编程语言

区块链底层Baas平台搭建,区块链政务底层平台开发

13823153121

云图说|将源端MongoDB业务搬迁至华为云DDS的几种方式

华为云开发者社区

mongodb 数据迁移 华为云文档数据库服务 DDS 文档数据库

tensorflow实现像素级图像分割算法

AI_robot

tensorflow实现cifar10彩色图像多类别分类

AI_robot

深度学习keras像搭积木般构建神经网络模型

AI_robot

tensorflow实现CNN模型垃圾分类算法

AI_robot

DNSPod与开源应用专场

DNSPod与开源应用专场

Kubernetes决定弃用Docker,到底会影响到谁?-InfoQ