2.1 开源容器集群方案
2.1.1 容器社区的“四朵金花”
技术社区从来不缺乏各种各样的轮子,容器的圈子里也一度百花齐放地诞生过许多辅助规模化容器运维的工具和平台。且不说企业自研和未开源的项目,单是在GitHub上就能轻松找到数百种工具,功能从简单的批量部署脚本到设计精良的全功能平台,让人目不暇接。纵观这些开源项目,核心解决的问题都是如何高效地进行容器集群的资源调度和任务编排,其中SwarmKit、Kubernetes、Mesos和Rancher是目前在这个领域中最知名且使用者数量最庞大的四种全功能解决方案。
接下来将用连续的四个章节(包括本章)依次讨论这四种主流容器的部署、使用和适用场景。值得一提的是,虽然这些容器集群管理项目能够独立提供十分相似的功能,但它们之间并非是完全互斥而毫无交集的。例如,Mesos社区曾多次尝试将Swarm或Kubernetes作为其管辖的数据中心中的一种扩展任务调度框架,Rancher则能够快速构建和管理Swarm、Kubernetes和Mesos集群环境,并通过Web UI统一监控在这些节点上运行的容器资源。
对初识容器集群应用的用户来说,SwarmKit是很好的起点。一方面它与Docker深度集成,能够充分运用许多用户已经熟悉的Docker概念和周边设施,学习曲线相对平缓。另一方面,它的部署结构简单紧凑,内置配置存储、服务域名路由、跨容器网络等集群基础能力,因此几乎不会因操作复杂而让人感到信心受挫。
2.1.2 经典Swarm、SwarmKit和Swarm Mode
SwarmKit并不是Docker公司在集群方式运用方面的第一次尝试。早在2014年年底,Docker公司就着手设计一组容器集群的组合方案:Machine、Swarm和Compose。在这个方案中,Machine是一款用于各种主流虚拟机和云平台快速创建Docker运行环境的工具,它支持在创建出来的节点上自动部署Swarm。当时的Swarm是一款整合跨节点网络的集群式容器运维管理服务,它利用Docker守护进程的API,将多节点的计算资源进行汇总,并提供完全兼容Docker的运行API,使用者只需在执行Docker命令工具时,用--host参数将目标设置为Swarm服务的IP和端口,即可像操作单个节点的Docker服务一样操作整个容器集群。但这种方式具有先天的局限性,比如在单节点Docker中并没有为服务高可用而设计的副本集和负载均衡等概念,也不存在服务网络管理和跨节点数据存储的问题。此外,集群中的服务间关系和启动顺序编排也远比单节点时复杂,这些功能过去是由Compose组件完成的,而它所支持的定义项对于集群的场景也一度显得捉襟见肘,直到其v2版本API推出之后才逐渐完善。
在一年多后的2016年2月,Docker公司低调地开始了SwarmKit项目。这个项目的作用与Swarm相似,但也许是意识到了Docker的API和服务模型与集群化场景的不匹配,SwarmKit从一开始就重新设计了独立的一套API和模型体系,并且采用了独立的客户端命令行工具:swarmctl。在SwarmKit里,集群的节点管理被设计成了API中十分自然的一部分,而不再是像Machine这样的单独组件。同时,SwarmKit将过去Swarm所依赖的外部集群一致性存储组件Etcd的核心部分内置到了软件中,这样虽然让使用者失去了选择存储组件的自由,却大大地简化了集群的部署过程。本书在第7章中会单独介绍Etcd这个项目。
真正让SwarmKit项目为众人所知的事件是Docker 1.12版本开始提供了一个一键创建容器集群的新命令:docker swarm。事实上,在这个后来被称为Swarm Mode的功能背后,正是SwarmKit的功劳。Docker将SwarmKit的核心模块内嵌在了Docker后台服务中。Swarm Mode并非一种特别的运行“模式”,而是Docker中的一组与集群相关功能的统称,因此并不存在像“模式切换”这样的概念,Docker通过不同的命令允许使用者同时以“当前节点”和“整个集群”两种视角来操作容器。
在Docker Daemon服务默认启动时,使用者只能用与过去的Docker命令相同的操作在当前节点上启动和管理容器,与集群相关的命令处于禁用的状态。直到使用者通过docker swarm命令从当前节点创建出新的集群,或是将当前节点加入到一个已经存在的集群里,就解封了Swarm Mode带来的一系列全新的命令集,包括docker service、docker stack、docker node、docker config和docker secret等,本章稍后会详细地介绍它们。
图2-1表示了Swarm、SwarmKit和Swarm Mode以及其他相关项目之间的关系。图中重叠的部分表示相应的项目之间存在代码层面的相互引用或组件形式的依赖。
图2-1 SwarmKit和相关项目的关系
Swarm Mode所创建的集群,本质上就是SwarmKit的集群,二者在代码实现层面上其实是同样的事物。但相比于Swarm Mode这个名称,SwarmKit一词更具有识别性,因此社区里有时会用“SwarmKit集群”来指代Swarm Mode所创建的集群,以便与过去的经典Swarm集群划清界限,本章的标题“SwarmKit集群解决方案”就采用了这样的表述方式。本章的内容会严格区分“Swarm Mode”和“SwarmKit”的名称使用,以避免产生混淆。