哈喽大家好,我是咸鱼
咸鱼在《一文带你了解容器技术的前世今生》有介绍过容器技术的由来以及Docker项目的发展
我们知道,Docker 及其他容器技术能够极大地简化应用程序的部署,做到了”开箱即用“
俗话说:”凡是具有两面性“。容器技术给我们带来便利的同时,一些问题也随之出现了
随着企业规模或者说业务规模的不断扩大,应用程序越来越多、而每个应用程序往往又由多个容器组成
例如想要实现一个简单的数据库 web 界面也可能需要为数据库服务器和应用程序运行单独的容器
于是容器的管理便成为了一个棘手的难题。工程师们为了解决这个问题,开发了一系列的容器编排器(container orchestrator),其中最有名的当属 kubernetes
容器编排器可以将一组容器作为一个基本单元去进行管理(例如 K8s 里的 pod),而且容器编排器可以在集群之间自动分配容器工作负载
那么今天,咸鱼将以自我介绍的形式来带大家了解三个容器编排器——Docker Compose、Swarm、Kubernetes
Docker Compose
大家好,我叫 Docker Compose 。我的爸爸是一个名叫 Docker 的公司
我的前身是一个叫 Fig 的项目,Fig 项目可是大有来头——因为它第一次提出了容器编排的概念
你只需要执行一条命令 fig up
就能够依次创建一系列容器,并且容器之间的关系及依赖性,都会自动帮你解决
当时它在 Github 上的热度可是比肩 Docker 的,后来我的爸爸秉承”打不过就加入“的理念,把 Fig 项目收购了
收购之后将名字改成了 Compose,于是我诞生了
我是根据一个 yaml 格式的配置文件来工作的,通常命名为 Docker-compose.yml
:
- 首先我会去读取这个文件,然后通过 Docker API 创建这个文件声明的资源
- 我还会为这些资源打上标签,方便我创建之后将它们分组管理
实际上我并不能够称得上是一个容器编排器,因为我实际上是通过 Docker 命令行接口(Docker command-line interface )去操作一组组容器的
举个例子,比如说在配置文件里有这三种类型的资源:
- service:包含了要启动的容器的声明。里面的每一个条目都相当于一个
Docker run
命令 - networks:包含了可以访问到容器的网络。里面的每个条目都相当于一个
Docker network create
命令 - volumes:包含了可以访问到容器内部的容器卷(容器卷即能够挂载到容器内部的持久存储)。里面的每一个条目都相当于一个
Docker vloume create
命令
尽管如此,我依旧能够较好地管理容器之间的依赖关系,我还能够为容器创建一个共享网络和卷,使它们可以相互通信和共享数据
但是我不能够实现容器的高可用性,如果容器出现故障,需要手动进行恢复
Swarm
哈喽大家好,我叫 Swarm
Docker Compose 虽然为大家提供了一种方便的方式去管理容器,但他在一开始的时候只能在单台主机上工作
也就是说他创建的所有容器都在同一台机器上面运行,抛开性能不谈,如果所有应用都在一台服务器上,要是这台服务器宕了,后果可是不堪设想的
为了解决这个问题,早在 2014 年我的哥哥 Classic Swarm (https://github.com/Docker-archive/classicswarm)就已经开始提供跨主机运行容器的解决方案了,但不久之后我的爸爸就不管他了,在社区上不再维护
时间来到 2016 年,我诞生了
与我的哥哥 Classic Swarm 相比,我是直接被内置到了 Docker 当中
不但如此,我能够提供更强大的功能和更好的性能,支持服务发现、负载均衡、滚动更新等特性
创建集群的时候,我只需要在初始节点上执行 Docker swarm init
命令,然后在每个要添加进集群的其他节点上面执行 Docker swarm join
命令就可以了
怎么样,是不是非常方便
小伙伴们可能对我怎么管理集群比较关心,首先我会将集群中的节点分成两类:
- 管理节点(Manager nodes)
管理节点提供了一个 API ,可以通过这个 API 来启动容器
而且管理节点之间使用基于 Raft 共识算法的协议相互通信,便于同步集群的状态,实现了高可用性和数据一致性
- 工作节点(Worker nodes)
工作节点,顾名思义就是就负责干活的节点啦。它们负责执行实际的容器工作
而且我的爸爸跟我说管理节点最多只能设置七个,但工作节点数量不限制
别看我这么能干,其实我也有一些缺点,毕竟器无完器嘛
缺点一:集群里面不能够实现跨节点共享存储
虽然我支持集群里面跨节点网络通信(使用桥接方法),但是我不能够支持跨节点的共享存储。我必须依赖第三方的卷插件才能实现
缺点二:stack file 和 compose file 难以区分
自从我被集成到 Docker Engine 后,我发现我能够通过 compose 文件来部署服务了(部署 services、volumes等资源)
而你们也知道的,compose 文件一开始是给 Docker Compose 用的
我们来看下对比,可以看到用法是很相似的
Docker-compose -f Docker-compose upDocker stack deploy -c Docker-compose.yml somestackname
但实际上我是通过 stack file 来进行集群部署的,stack file 也是 YML 格式的文件,它跟 compose file 极其相似
这样就会导致一些初学者在学习的时候不知道该用 stack file 还是 compose file ,可以看下下面这个 issue
https://stackoverflow.com/questions/43099408/whats-the-difference-between-a-stack-file-and-a-compose-file
PS:一般来讲,Stack file 和Compose file 的语法和功能非常相似,都可以用来定义和部署多个服务或容器
但是,Stack file 更加适合用来管理生产环境中的服务,而Compose file 更加适合用来管理开发和测试环境中的容器
此外,Stack file 还支持一些 Compose file 不支持的功能,如服务发现、负载均衡、滚动更新等
我的器生并非一帆风顺,我曾经可是 Docker Cloud 的支柱,但是 Docker Cloud 在 2018 年的时候就被关闭了
不但如此,随着对手 Kubernetes 的发展,我的地位不断地受到威胁。直到 2019 年,我的爸爸宣布停止对我的开发和维护,将重心转向 Kubernetes
可谓是:”跻攀分寸不可上,失势一落千丈强“
Kubernetes
哈喽大家好,我叫 Kubernetes。为了方便,你们可以叫我 K8s
想必大家都听说过我,作为迄今为止最受欢迎的容器编排器,我能够在多达数千个节点的集群上管理和分配资源
请允许我骄傲一下,我在容器编排器中地位相当于谷歌在搜素引擎中的地位,可以说是我主导了容器编排
但我能有今天,一方面归功于我的爸爸是谷歌,另一方面我得到了云原生计算基金会(Cloud Native Computing Foundation,CNCF)的支持
在 2014~2015 年间,整个容器社区可谓热闹非凡。但是热闹非凡的景象背后则是许多人的担忧和不满
那时候 Docker 项目已经成为 Docker 公司一个商业产品,当时我的爸爸找到了 Docker 公司,希望能够跟 Docker 合作,但是强硬的 Docker 觉得这会消弱自己的地位,拒绝掉了这个请求
而且 Docker 公司在 Docker 开源项目的发展上,始终保持着绝对的权威和发言权,并在多个场合用实际行动挑战到了其他玩家(比如,CoreOS、RedHat,甚至我爸爸和微软)的切身利益
于是这些开源基础设施领域巨头们联合我爸爸发起了一个名为CNCF(Cloud Native Computing Foundation)的基金会
这个基金会的目的就是希望以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker 公司为核心的容器商业生态
于是在那个时候,我诞生了。我的前身是 Borg (一个谷歌内部工具)
如果你看过 Kubernetes 项目早期的 GitHub Issue 和 Feature 的话,就会发现它们大多来自于 Borg 和 Omega 系统的内部特性,这些特性落到 Kubernetes 项目上,就是 Pod、Sidecar 等功能和设计模式
我刚出生那会,因为操作太过复杂被很多人抱怨
如果你们想要配置集群,除了我本身,你们还需要选择和配置一些第三方组件。这就跟 Linux 内核需要跟 GNU 相结合才能构成一个完整的操作系统一样,我只是一个编排器,我需要跟其他软件结合才能构成一个完整的集群
还记得上面说过的 CNCF 基金会不,RedHat 也在里面,它把它的那一套玩法搬到了我的身上
跟 Linux 发行版本一样,我跟安装程序和其他精心挑选的第三方组件捆绑在一起,摇身一变就成了 K8s 发行版
有了 K8s 发行版,你们对我的抱怨就少了很多
不但如此,我的爸爸开始在 K8s 社区上大力推行”民主化“变革,即从 API 到容器运行时的每一层,Kubernetes 项目都为开发者暴露出了可以扩展的插件机制,鼓励用户通过代码的方式介入 Kubernetes 项目的每一个阶段
这个民主化变革带来的效果是巨大的,很快在整个容器社区中催生出了大量的、基于 Kubernetes API 和扩展接口的二次创新工作
随着我不断崛起不断扩大,Docker 公司也不得不面对自己即将失败的现实,从 2017 年开始,Docker 公司先是将 Docker 项目的容器运行时部分 Containerd 捐赠给 CNCF 社区
接着 10 月份的时候,Docker 公司出人意料地宣布,将我内置到它们的主打产品 Docker 企业版中,这标志着这场轰轰烈烈的”编排器之争“至此落下帷幕
如果当初 Docker 公司选择了跟我爸爸合作,那么如今的容器生态又会是一番怎样的景象呢?
本文参考链接:https://lwn.net/Articles/905164/#t