【编者的话】此篇文章是《Using Docker》一书的作者 Adrian Mouat 编写,详细对比分析了Swarm、Fleet、K8s以及Mesos的区别。
大部分软件系统是随时间演进的,添加新的修改旧的功能,不断变化的用户需求意味着一个高效的系统必须能够迅速扩展或收缩资源。为了达到接近零宕机的需求,通常在一个单独的数据中心或区域需要自动地将故障转移到预设的备份系统。
在此之上,一些大型企业经常会运行多个这样的系统或是偶尔需要运行一些独立于主系统的任务比如数据挖掘,但又需要现存系统内更多资源或通讯交互。
当使用多个资源时,重要的是确保他们得到有效地使用而不被闲置,但是还可以应对需求高峰。成本效益与迅速扩展的规模之前的权衡是困难的任务,但是可以用各种方式加以处理。
所有这一切都意味着一个非凡系统的运行充满了各种管理任务、挑战以及不应低估的复杂性。很快在个体层面一个接一个地修补和更新某个机器将变为不可能,他们必须同等对待。当一台机器发生问题时,它应该被摧毁并更换,而不是调养修复后再上线。
当前有各种工具和解决方案能够帮助解决这些挑战,这里主要集中讲解几个编排工具,这些工具能帮助我们以集群方式在主机上启动容器,并能够彼此连接,同时也考虑到了扩展性和自动故障转移的重要特性。
Swarm
Swarm是Docker的原生集群工具,Swarm使用标准的Docker API,这意味着容器能够使用docker run命令启动,Swarm会选择合适的主机来运行容器,这也意味着其他使用Docker API的工具比如Compose和bespoke脚本也能使用Swarm,从而利用集群而不是在单个主机上运行。
Swarm的基本架构很简单:每个主机运行一个Swarm代理,一个主机运行Swarm管理器(在测试的集群中,这个主机也可以运行代理),这个管理器负责主机上容器的编排和调度。Swarm能以高可用性模式(etcd、Consul 或ZooKeeper 中任何一个都可以用来将故障转移给后备管理器处理)运行。当有新主机加入到集群,有几种不同的方式来发现新加的主机,在Swarm中也就是discovery。默认情况下使用的是token,也就是在Docker Hub上会储存一个主机地址的列表。
Fleet
Fleet是一个来自CoreOS的集群管理工具,自诩为“底层的集群引擎”,也就意味着它有望形成一个“基础层”的更高级别的解决方案,如Kubernetes。
Fleet最显著的特点是基于systemd(systemd提供单个机器的系统和服务初始化)建立的,Fleet将其扩展到集群上,Fleet能够读取systemd单元文件,然后调度单个机器或集群。
每个机器运行一个引擎和一个代理,任何时候在集群中只激活一个引擎,但是所有代理会一直运行,Systemd单元文件被提交给引擎,然后在 least-loaded机器上调度任务,单元文件会简单运行一个容器,代理会启动单元和报告状态,Etcd用来激活机器间的通讯以及存储集群和单元的状态。
这个架构用来设计容错的,如果一个机器宕机了,这个机器上的所有单元会在新的主机上被重新启动。
Fleet支持各种调度提示与约束。在最基本的层面,单元的调度可以是全局的:一个实例将在所有机器上运行,或者作为一个单独的单元运行在一台机器上。全局调度对于如日志和监控容器任务非常实用。支持各种关联类型约束,因此,例如规定在应用服务器上运行健康检查的容器。元数据也可以连接到主机用于调度,所以你可以让你的容器在某一区域或某些硬件设备上运行。
由于Fleet是基于systemd的,它也支持socket activation概念;容器可以绑定到一个给定端口的连接响应上。这样做的主要优点是进程可以即时创建而不是闲置等待某些任务。有可能涉及到sockets管理的其他好处,如容器重启的消息不丢失。
Kubernetes
Kubernetes是一个由google基于他们上个世纪容器产品化的经验而推出的容器编排工具,Kubernetes有些固执己见对于容器如何组织和网络强制了一些概念,你需要了解的主要概念有:
Pods – Pods是容器一起部署与调度的群体。Pods与其他系统的单一容器相比,它组成了Kubernetes中调度的原子单元。Pod通常会包括1-5个一起提供服务的容器。除了这些用户容器,Kubernetes还会运行其他容器来提供日志和监控服务。在Kubernetes中Pods寿命短暂;随着系统的进化他们不断地构建和销毁。
Flat Networking Space – Kubernetes的网络是跟默认的Docker网络不同。在默认Docker网络中, 容器存在于一个私有子网络中,它需要赚翻主机上的端口或者使用代理才能与其他主机上的容器通讯。在Kubernetes,pod中的容器会分享一个IP地址,但是该地址空间跟所有的pods是“平”的,这意味着所有pods不用任何网络地址转换(NAT)就可以互相通讯。这就使得多主机群集更容易管理,不支持链接的代价使得建立单台主机(更准确地说是单个pod)网络更为棘手。由于在同一个pod中的容器共享一个IP,它们可以通过使用本地主机地址端口进行通信(这并不意味着你需要协调pod内的端口使用)。
Labels – Labels是附在Kubernetes对象(主要是pods)上用于描述对象的识别特征的键值对,例如版本:开发与层级:前端。通常Labels不是***的;它们用来识别容器组。Labels选择器可以用来识别对象或对象组,例如设置所有在前端层的pods与环境设置为production。使用Labels可以很容易地处理分组任务,例如分配pods到负载均衡组或者在组织之间移动pods。
Services – Services是通过名称来定位的稳定的节点。Services使用label选择器来连接pods,比如“缓存”Service可以连接到标识为 label选择器“type”为“redis”的某些“redis”pods。该service将在这些pods之间自动循环地请求。以这种方式,Services可用于连接一个系统各部件。使用Services会提供一个抽象层,这意味着应用程序并不需要知道他们调用的service的内部细节,例如pods内部运行的应用程序只需要知道调用的数据库service的名称和接口,它不必关心有多少pods组成了那个数据库,或者上次它调用了哪个pod。 Kubernetes会为集群建立一个DNS服务器,用于监视新的services并允许他们在应用程序代码和配置文件中按名称定位。
它也可以设置services不指向pods而是指向其他已经存在的services,比如外部API或数据库。
Replication Controllers - Replication controllers是Kubernetes实例化pods的正常方式(通常情况下,在Kubernetes中不使用Docker CLI)。它们为service来控制和监视运行的pods数量(称为replicas)。例如,一个replication controller可以负责维持5个Redis的pods的运行。如果一个失败,它会立即启动一个新的。如果replicas的数量减少,它会停止多余的pods。虽然使用Replication Controllers来实例化所有pods会增加一层额外的配置,但是它显著提高容错性和可靠性。
Mesos 和 Marathon
Apache Mesos是一个开源的集群管理器。它是为涉及数百或数千台主机的大规模集群而设计的。 Mesos支持在多租户间分发工作负载,一个用户的Docker容器运行紧接着另一个用户的Hadoop任务。
Apache Mesos始于加州大学伯克利分校的一个项目,用来驱动Twitter的底层基础架构,并且成为许多大公司如eBay和Airbnb的重要工具。后来 Mesosphere(共同创办人之一:Ben Hindman - Mesos原始开发人员 )做了很多持续性的Mesos开发和支持工具(如Marathon)。
Mesos的体系结构是围绕高可用性和弹性而设计的。在一个Mesos群集的主要组成部分是:
- Mesos Agent Nodes - 负责实际的运行任务。所有代理向Master提交其可用资源。通常会有数十到上千的节点。
- Mesos Master - 负责给Agents发送任务。它维护一个现有资源的列表并且将此“提供”给Frameworks。Master基于分配策略来决定提供多少资源。通常会有2个或4个备用Master来接替故障的Master。
- ZooKeeper - 用于选择和查找当前Master地址。通常情况下会运行3个或5个ZooKeeper实例以确保可用性和故障处理。
- Frameworks - 与Master协调调度任务到Agent节点。Frameworks由两部分组成:executor进程会运行代理并维护运行的任务以及那些已注册的寄存器,还可以选择使用那些基于来自主机提供的资源。Mesos集群为不同种类的任务可以运行多种Frameworks。用户希望与frameworks交互来提交任务而不是和Mesos交互。
上图中我们可以看到Mesos集群使用framework作为调度器。Marathon调度器使用ZooKeeper来定位当前要提交任务的Mesos master。无论是Marathon调度器还是Mesos master都有备用以便当前master不可用的时候使用。
通常情况下,ZooKeeper,作为Mesos master以及备用,它会运行在同一台主机上。在一个小的集群中,这些主机也可以运行代理,但是更大的集群做这些就不可行,因为它们需要与master通信。Marathon也可以运行在同一个主机上,或者运行在存在于网络边界的独立主机上,而且还可以为客户端形成接入点,从而保持客户端与Mesos集群分离。
Marathon(来自 Mesosphere)是为开启、监控以及扩展长期运行应用程序规模而设计的。Marathon启动应用程序的设计是灵活的,它甚至可以启动其他互补的 frameworks,如Chronos(数据中心的“cron”)。可以选择使用framework来运行Docker容器,Marathon直接支持这样做。就像我们见过的其他编排架构,Marathon支持各种亲和与约束规则。客户端通过REST API与Marathon交互。其他功能还包括支持健康检查以及可用于与负载平衡器或分析指标交互的事件流。
结论
编排、集群以及管理容器显然有多种选择。话虽如此,但这些选择一般都是高度分化的。在编排方面,我们可以说:
- Swarm具有使用标准Docker接口的优势(及劣势)。虽然这样使得它与现有的工作流程交互起来简单易用,但也可能对于支持更为复杂的定义在定制接口的调度变得更加困难。
- Fleet是底层级的而且相当简单的编排层,它被于运行更高级别的编排工具,例如Kubernetes或者自定义系统。
- Kubernetes是带有服务发现和复制的编排工具。它可能需要重新设计一些现有的应用程序,但是正确地使用可以提供一个可容错和可扩展的系统。
- Mesos 是一种底层级、久经沙场的调度器,对于容器的编排,它支持多种frameworks,包括Marathon、Kubernetes、和Swarm。在写这篇文章的时候,Kubernetes和Mesos比Swarm开发的更多以及更为稳定。在规模上,只有Mesos已经证明了支持成百上千个节点的大型系统。但是,对于小的集群比方说,还不到十几个节点的集群,用Mesos可能过于复杂。
原文链接:http://dockone.io/article/823?utm_source=tuicool&utm_medium=referral