1. docker和k8s的爱恨情仇

1.1 PaaS的普及和难点

2013年,伴随着 PaaS 概念的逐步普及,以 Cloud Foundry 为代表的经典 PaaS 项目,开始进入基础设施领域的视野,平台化和 PaaS 化成了这个生态中的一个最为重要的进化趋势。

就在对开源 PaaS 项目落地的不断尝试中,这个领域的从业者们发现了 PaaS 中最为棘手也最亟待解决的一个问题:究竟如何给应用打包?

遗憾的是,无论是 Cloud Foundry、OpenShift,还是 Clodify,面对这个问题都没能给出一个完美的答案,反而在竞争中走向了碎片化的歧途。

1.2 docker的崛起

而就在这时,一个并不引人瞩目的 PaaS 创业公司 dotCloud,却选择了开源自家的一个容器项目 Docker。更出人意料的是,就是这样一个普通到不能再普通的技术,却开启了一个名为“Docker”的全新时代。

Docker 项目给 PaaS 世界带来的“降维打击”,其实是提供了一种非常便利的打包机制。这种机制直接打包了应用运行所需要的整个操作系统,从而保证了本地环境和云端环境的高度一致,避免了用户通过“试错”来匹配两种不同运行环境之间差异的痛苦过程。

伴随着 Docker 公司一手打造出来的容器技术生态在云计算市场中站稳了脚跟,围绕着 Docker 项目进行的各个层次的集成与创新产品,也如雨后春笋般出现在这个新兴市场当中。而 Docker 公司,不失时机地发布了 Docker Compose、Swarm 和 Machine“三件套”,在重新定义 PaaS 的方向上走出了最关键的一步。

1.3 其他玩家的狙击–OCI的诞生

而令大多数人不满意的是,Docker 公司在 Docker 开源项目的发展上,始终保持着绝对的权威和发言权,并在多个场合用实际行动挑战到了其他玩家(比如,CoreOS、RedHat,甚至谷歌和微软)的切身利益。

于是,2015 年 6 月 22 日,由 Docker 公司牵头,CoreOS、Google、RedHat 等公司共同宣布,Docker 公司将 Libcontainer 捐出,并改名为 RunC 项目,交由一个完全中立的基金会管理,然后以 RunC 为依据,大家共同制定一套容器和镜像的标准和规范。

这套标准和规范,就是 OCI( Open Container Initiative )。OCI 的提出,意在将容器运行时和镜像的实现从 Docker 项目中完全剥离出来。这样做,一方面可以改善 Docker 公司在容器技术上一家独大的现状,另一方面也为其他玩家不依赖于 Docker 项目构建各自的平台层能力提供了可能。

不过,不难看出,OCI 的成立更多的是这些容器玩家出于自身利益进行干涉的一个妥协结果。所以,尽管 Docker 是 OCI 的发起者和创始成员,它却很少在 OCI 的技术推进和标准制定等事务上扮演关键角色,也没有动力去积极地推进这些所谓的标准。

1.4 CNCF基金会和K8S的崛起

Docker 之所以不担心 OCI 的威胁,原因就在于它的 Docker 项目是容器生态的事实标准,而它所维护的 Docker 社区也足够庞大。

可是,一旦这场斗争被转移到容器之上的平台层,或者说 PaaS 层,Docker 公司的竞争优势便立刻捉襟见肘了。在这个领域里,像 Google 和 RedHat 这样的成熟公司,都拥有着深厚的技术积累;而像 CoreOS 这样的创业公司,也拥有像 Etcd 这样被广泛使用的开源基础设施项目。可是 Docker 公司呢?它却只有一个 Swarm。

所以这次,Google、RedHat 等开源基础设施领域玩家们,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金会。这个基金会的目的其实很容易理解:它希望,以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker 公司为核心的容器商业生态。

Kubernetes 项目让人耳目一新的设计理念和号召力,很快就构建出了一个与众不同的容器编排与管理的生态。就这样,Kubernetes 项目在 GitHub 上的各项指标开始一骑绝尘,将 Swarm 项目远远地甩在了身后。

1.5 K8S生态发展

从 API 到容器运行时的每一层,Kubernetes 项目都为开发者暴露出了可以扩展的插件机制,鼓励用户通过代码的方式介入 Kubernetes 项目的每一个阶段。Kubernetes 项目的这个变革的效果立竿见影,很快在整个容器社区中催生出了大量的、基于 Kubernetes API 和扩展接口的二次创新工作,比如:

  • 目前热度极高的微服务治理项目 Istio;
  • 被广泛采用的有状态应用部署框架 Operator;
  • 还有像 Rook 这样的开源创业项目,它通过 Kubernetes 的可扩展接口,把 Ceph 这样的重量级产品封装成了简单易用的容器存储插件。

面对 Kubernetes 社区的崛起和壮大,Docker 公司也不得不面对自己豪赌失败的现实。但在早前拒绝了微软的天价收购之后,Docker 公司实际上已经没有什么回旋余地,只能选择逐步放弃开源社区而专注于自己的商业化转型。

所以,从 2017 年开始,Docker 公司先是将 Docker 项目的容器运行时部分 Containerd 捐赠给 CNCF 社区,标志着 Docker 项目已经全面升级成为一个 PaaS 平台;紧接着,Docker 公司宣布将 Docker 项目改名为 Moby,然后交给社区自行维护,而 Docker 公司的商业产品将占有 Docker 这个注册商标。

2017 年 10 月,Docker 公司出人意料地宣布,将在自己的主打产品 Docker 企业版中内置 Kubernetes 项目,这标志着持续了近两年之久的“编排之争”至此落下帷幕。

2. 相关技术概念诞生的时间线

2015–Docker发布OCI

2015 年 OCI (Open Container Initiative, 开放容器倡议)由 Docker 和其他容器行业领导者共同成立(它也是 Linux 基金会旗下项目)

OCI 主要包含两个规范:

  • 运行时规范(runtime-spec):容器运行时,如何运行指定的 文件系统上的包
  • 容器镜像规范(image-spec):如何创建一个 OCI 运行时可运行的文件系统上的包

Docker 把它自己的容器镜像格式和 runtime ( 现在的 runc ) 都捐给了 OCI 作为初始工作。

2016–k8s发布CRI,Docker发布Docker Swarm

2016 年 6 月,Docker v1.12 发布,带来了 Docker 在多主机多容器的编排解决方案,Docker Swarm 。

2016 年 12 月, Kubernetes 发布 CRI (Container Runtime Interface, 容器运行时接口) ,这当中一部分原因是由于 Kubernetes 尝试支持另一个由 CoreOS 领导的容器运行时项目 rkt ,但是需要写很多兼容的代码之类的,为了避免后续兼容其他运行时带来的维护工作,所以发布了统一的 CRI 接口,凡是支持 CRI 的运行时,皆可直接作为 Kubernetes 的底层运行时;

当然, Kubernetes 也是在 2016 年逐步取得那场容器编排战争的胜利的。

CRI中定义了容器和镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务:

  • RuntimeService:容器和Sandbox运行时管理。
  • ImageService:提供了从镜像仓库拉取、查看、和移除镜像的RPC。

CRI接口使用Protocol Buffer,Container Runtime实现了CRI gRPC Server,包括RuntimeService和ImageService。该gRPC Server需要监听本地的Unix socket,而kubelet则作为gRPC Client运行。

2017-- docker捐献containerd,支持CNI

containerd

2017 年, Docker 将自身从 v1.11 起开始引入的容器运行时 containerd 捐给了 CNCF
2017 年,Docker 的网络组件 libnetwork 增加了 CNI 的支持;CNI(Container Network Interface, 容器网络接口),由一组用于配置 Linux 容器的网络接口的规范和库。CNI 仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。

2017年11月,K8s支持Containerd
k8s+containerd

2018-- k8s集成containerd

2018 年, Kubernetes 的 containerd 集成,正式 GA
在这里插入图片描述

2019–rkt终止使命,Docker企业服务被收购

2019 年,上文中提到的另一个容器运行时项目 rkt 被 CNCF 归档,终止使命了;
2019 年 Mirantis 收购 Docker 的企业服务。

2020 K8s 宣布开始进入废弃 dockershim 支持的倒计时

别慌: Kubernetes 和 Docker

Mirantis 公司宣布将维护 dockershim

Docker引擎是Kubernetes支持的第一个(也是最初唯一的)容器运行时,但这绝不是Kubernetes社区的长期计划。

从长远来看,社区希望能够运行许多不同类型的容器,因此,创建了容器运行时接口(CRI),这是容器引擎与Kubernetes进行通信的标准方式。如果容器引擎符合CRI,则可以轻松地在Kubernetes中运行。

对于大多数人来说,弃用dockershim并不是一个问题,因为他们实际上并没有真正使用Docker。他们使用的是符合CRI要求的容器。对于这些人来说,什么都不会改变。

3. 最后–k8s/docker/containerd/runc的关系

containerd

参考

https://opencontainers.org/
深入剖析Kubernetes_容器_K8s-极客时间
K8S 弃用 Docker 了?Docker 不能用了?别逗了!
终于可以像使用 Docker 一样丝滑地使用 Containerd 了!

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐