在本教程中,我们将了解容器编排系统的基本需求。
我们将评估这种系统的期望特性。在此基础上,我们将尝试比较目前使用的两个最流行的容器编排系统Apache Mesos和Kubernetes。
在我们开始比较Mesos和Kubernetes之前,让我们花点时间来理解什么是容器,以及为什么我们需要容器编排。
容器是一个标准化的软件单元,它将代码及其所有必需的依赖项打包。
因此,它提供了平台独立性和操作简单性。Docker是使用中最流行的容器平台之一。
Docker利用Linux内核特性,如cGroup和命名空间来提供不同进程的隔离。因此,多个容器可以独立且安全地运行。
创建docker映像非常简单,我们只需要一个Dockerfile:
FROM openjdk:8-jdk-alpine VOLUME /tmp COPY target/hello-world-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] EXPOSE 9001
因此,这几行代码足以使用Docker CLI创建Spring Boot应用程序的Docker映像:
docker build -t hello_world .
因此,我们已经了解了容器如何使应用程序部署可靠且可重复。但为什么我们需要容器编排?
现在,虽然我们有一些容器需要管理,但我们可以使用Docker CLI。我们也可以自动化一些简单的家务。但是当我们要管理数百个容器时会发生什么呢?
考虑到不同的可扩展性和微服务的可用性,例如所有的微服务。
因此,事情会很快失控,这就是容器编排系统的好处所在。容器编排系统将具有多容器应用程序的计算机集群视为单个部署实体。它提供了从初始部署、调度、更新到其他功能(如监视、扩展和故障转移)的自动化。
Apache Mesos是一个开源集群管理器,最初是在加州大学伯克利分校开发的。它为应用程序提供了跨集群的资源管理和调度API。Mesos为我们提供了以分布式方式运行容器化和非容器化工作负载的灵活性。
Mesos体系结构由Mesos Master、Mesos Agent和应用框架组成:
让我们来了解一下体系结构的组成部分:
正如我们刚才看到的,Mesos非常灵活,允许框架通过定义良好的api来调度和执行任务。然而,直接实现这些原语并不方便,尤其是当我们想调度定制应用程序时。例如,编排打包为容器的应用程序。
这就是像Marathon这样的框架可以帮助我们的地方。Marathon是一个运行在Mesos上的容器编排框架。在这方面,Marathon是中微子群的一个框架。Marathon提供了一些我们通常期望从编排平台获得的好处,如服务发现、负载平衡、度量和容器管理api。
Marathon将长时间运行的服务视为应用程序,将应用程序实例视为任务。一个典型的场景可以有多个应用程序,它们之间的依赖关系形成所谓的应用程序组。
那么,让我们看看如何使用Marathon来部署我们之前创建的简单Docker映像。请注意,安装一个Mesos集群可能很少涉及,因此我们可以使用一个更直接的解决方案,如Mesos Mini。Mesos-Mini使我们能够在Docker环境中旋转一个本地Mesos集群。它包括一个Mesos Master,一个Mesos代理,和Marathon。
一旦Mesos集群启动并运行了Marathon,我们就可以将容器部署为一个长期运行的应用程序服务。我们只需要一个小的JSON应用程序定义:
#hello-marathon.json { "id": "marathon-demo-application", "cpus": 1, "mem": 128, "disk": 0, "instances": 1, "container": { "type": "DOCKER", "docker": { "image": "hello_world:latest", "portMappings": [ { "containerPort": 9001, "hostPort": 0 } ] } }, "networks": [ { "mode": "host" } ] }
让我们了解一下这里到底发生了什么:
我们可以使用Marathon提供的REST API启动此应用程序:
curl -X POST \ http://localhost:8080/v2/apps \ -d @hello-marathon.json \ -H "Content-type: application/json"
Kubernetes是一个开源的容器编排系统,最初由Google开发。它现在是云计算基础(CNCF)的一部分。它提供了一个平台,用于跨主机集群自动化应用程序容器的部署、扩展和操作。
Kubernetes架构由Kubernetes主节点和Kubernetes节点组成
让我们来看看这个高级体系结构的主要部分:
在最后一节中,我们看到了几个Kubernetes对象,它们是Kubernetes系统中的持久实体。它们反映集群在任何时间点的状态。
让我们来讨论一些常用的Kubernetes对象:
还有其他几个Kubernetes对象,它们可以有效地以分布式方式运行容器。
所以,现在我们可以尝试将Docker容器启动到Kubernetes集群中。Kubernetes提供Minikube,一个在虚拟机上运行单节点Kubernetes集群的工具。我们还需要kubectl,Kubernetes命令行接口来与Kubernetes集群一起工作。
在安装了kubectl和Minikube之后,我们可以将容器部署到Minikube中的单节点Kubernetes集群上。我们需要在YAML文件中定义基本的Kubernetes对象:
这里不可能详细分析此定义文件,但让我们来看看其中的亮点:
最后,我们可以部署容器并通过kubectl创建所有定义的Kubernetes对象:
kubectl apply -f yaml/hello-kubernetes.yaml
现在,我们已经了解了足够的上下文,并且在Marathon和Kubernetes上执行了基本部署。我们可以试着去了解他们之间的对比。
不过,这只是一个警告,直接比较库伯涅茨和介观并不完全公平。我们寻求的大多数容器编排特性都是由一个Mesos框架提供的,比如Marathon。因此,为了保持正确的观点,我们将尝试将Kubernetes与Marathon进行比较,而不是直接比较Mesos。
我们将基于这样一个系统的一些期望属性来比较这些编排系统。
Mesos设计用于处理各种类型的工作负载,这些负载可以是容器化的,甚至可以是非容器化的。这取决于我们使用的框架。正如我们所看到的,使用Marathon这样的框架在Mesos中支持容器化工作负载非常容易。
另一方面,Kubernetes只处理容器化的工作负载。最广泛的是,我们将其用于Docker容器,但它支持其他容器运行时,如Rkt。将来,Kubernetes可能支持更多类型的工作负载。
Marathon支持通过应用程序定义或用户界面进行缩放。Marathon也支持自动缩放。我们还可以扩展应用程序组,它可以自动扩展所有依赖项。
如前所述,Pod是Kubernetes的基本执行单元。当由部署管理时,Pods可以扩展,这就是为什么Pods总是被定义为部署的原因。缩放可以手动或自动进行。
Marathon中的应用程序实例分布在Mesos代理之间,从而提供了高可用性。典型的介观团簇由多个代理组成。此外,ZooKeeper通过法定人数和领导人选举为Mesos集群提供高可用性。
类似地,Kubernetes中的pod跨多个节点进行复制,以提供高可用性。通常,Kubernetes集群由多个工作节点组成。此外,集群还可以有多个主节点。因此,Kubernetes集群能够为容器提供高可用性。
Mesos DNS可以为应用程序提供服务发现和基本的负载平衡。Mesos DNS为每个Mesos任务生成SRV记录,并将其转换为运行该任务的机器的IP地址和端口。对于Marathon应用程序,我们还可以使用Marathon-lb使用HAProxy提供基于端口的发现。
在Kubernetes部署可以动态地创建和销毁pod。因此,我们通常通过服务在Kubernetes中公开pod,服务提供服务发现。Kubernetes中的服务充当pods的调度器,因此也提供负载平衡。
在Marathon中对应用程序定义的更改作为部署处理。部署支持应用程序的启动、停止、升级或扩展。Marathon还支持滚动启动来部署新版本的应用程序。但是,回滚也是直接的,通常需要部署更新的定义。
Kubernetes中的部署支持升级和回滚。我们可以提供部署策略,同时将旧的pod与新的pod重新连接。典型的策略是重新创建或滚动更新。默认情况下,Kubernetes维护部署的部署历史,这使得回滚到以前的版本变得很简单。
Mesos有一个诊断工具,可以扫描所有集群组件,并提供与健康和其他指标相关的数据。可以通过可用的api查询和聚合数据。我们可以使用像普罗米修斯这样的外部工具来收集这些数据。
Kubernetes将与不同对象相关的详细信息发布为资源度量或完整度量管道。典型的做法是在Kubernetes集群上部署一个外部工具,比如ELK或Prometheus+Grafana。这样的工具可以吸收集群指标并以一种非常用户友好的方式呈现出来。
Mesos为有状态应用程序提供了持久的本地卷。我们只能从保留资源创建持久卷。它还可以支持外部存储,但有一些限制。Mesos对容器存储接口(CSI)有实验性的支持,CSI是存储供应商和容器编排平台之间的一组公共API。
Kubernetes为有状态容器提供了多种类型的持久卷。这包括iSCSI、NFS等存储。此外,它还支持外部存储。Kubernetes中的Volume对象支持这个概念,并且有多种类型,包括CSI。
Mesos中的容器运行时提供两种类型的网络支持,即每个容器的IP和网络端口映射。Mesos定义了一个公共接口来指定和检索容器的网络信息。Marathon应用程序可以在主机模式或网桥模式下定义网络。
Kubernetes的网络为每个pod分配一个唯一的IP。这就不需要将容器端口映射到主机端口。它进一步定义了这些pod如何在节点间相互通信。这是在Kubernetes中通过Cilium、Contiv等网络插件实现的。
最后,相比之下,我们通常期待一个明确的判决!然而,不管怎样,宣称一种技术优于另一种技术并不完全公平。正如我们所看到的,Kubernetes和Mesos都是强大的系统,并且提供了相当竞争的特性。
然而,性能是一个非常关键的方面。一个Kubernetes集群可以扩展到5000个节点,而Mesos集群上的Marathon支持多达10000个代理。在大多数实际情况下,我们不会处理这么大的集群。
最后,它归结为灵活性和工作负载的类型。如果我们重新开始,只计划使用容器化的工作负载,Kubernetes可以提供一个更快的解决方案。然而,如果我们现有的工作负载是容器和非容器的混合,那么Mesos和Marathon可能是一个更好的选择。
Kubernetes和ApacheMesos非常强大,但它们并不是这个领域中唯一的系统。我们有很多有前途的选择。虽然我们不会深入讨论它们的细节,但让我们快速列出其中一些:
总之,在本教程中,我们讨论了容器和容器编排系统。我们简要介绍了两个使用最广泛的容器编排系统,Kubernetes和apachemesos。我们还根据几个特点对这些系统进行了比较。最后,我们看到了这个领域的一些其他选择。