1概述
在本教程中,我们将了解容器编排系统的基本需求。
我们将评估这种系统的期望特性。在此基础上,我们将尝试比较目前使用的两个最流行的容器编排系统Apache Mesos和Kubernetes。
2容器业务流程
在我们开始比较Mesos和Kubernetes之前,让我们花点时间来理解什么是容器,以及为什么我们需要容器编排。
2.1.容器
容器是一个标准化的软件单元,它将代码及其所有必需的依赖项打包。
因此,它提供了平台独立性和操作简单性。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 .
2.2. 容器编排
因此,我们已经了解了容器如何使应用程序部署可靠且可重复。但为什么我们需要容器编排?
现在,虽然我们有一些容器需要管理,但我们可以使用Docker CLI。我们也可以自动化一些简单的家务。但是当我们要管理数百个容器时会发生什么呢?
考虑到不同的可扩展性和微服务的可用性,例如所有的微服务。
因此,事情会很快失控,这就是容器编排系统的好处所在。容器编排系统将具有多容器应用程序的计算机集群视为单个部署实体。它提供了从初始部署、调度、更新到其他功能(如监视、扩展和故障转移)的自动化。
三. Memos 简介
Apache Mesos是一个开源集群管理器,最初是在加州大学伯克利分校开发的。它为应用程序提供了跨集群的资源管理和调度API。Mesos为我们提供了以分布式方式运行容器化和非容器化工作负载的灵活性。
3.1. 架构
Mesos体系结构由Mesos Master、Mesos Agent和应用框架组成:
让我们来了解一下体系结构的组成部分:
- 框架:这些是需要分布式执行任务或工作负载的实际应用程序。典型的例子是Hadoop或Storm。Mesos框架由两个主要部分组成:调度程序:它负责向主节点注册,以便主节点可以开始提供资源Executor:这是在代理节点上启动以运行框架任务的过程
- Mesos代理:它们负责实际运行任务。每个代理将其可用资源(如CPU和内存)发布到主服务器。从主节点接收任务时,它们将所需的资源分配给框架的执行器。
- Mesos Master:它负责调度从框架接收到的任务到其中一个可用的代理节点。Master向框架提供资源。框架的调度器可以选择在这些可用资源上运行任务。
3.2. Marathon
正如我们刚才看到的,Mesos非常灵活,允许框架通过定义良好的api来调度和执行任务。然而,直接实现这些原语并不方便,尤其是当我们想调度定制应用程序时。例如,编排打包为容器的应用程序。
这就是像Marathon这样的框架可以帮助我们的地方。Marathon是一个运行在Mesos上的容器编排框架。在这方面,Marathon是中微子群的一个框架。Marathon提供了一些我们通常期望从编排平台获得的好处,如服务发现、负载平衡、度量和容器管理api。
Marathon将长时间运行的服务视为应用程序,将应用程序实例视为任务。一个典型的场景可以有多个应用程序,它们之间的依赖关系形成所谓的应用程序组。
3.3. 例子
那么,让我们看看如何使用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"
}
]
}
让我们了解一下这里到底发生了什么:
- 我们已经为我们的申请提供了一个id
- 然后,我们定义了应用程序的资源需求
- 我们还定义了要运行多少个实例
- 然后,我们提供了容器的详细信息来启动应用程序
- 最后,我们定义了能够访问应用程序的网络模式
我们可以使用Marathon提供的REST API启动此应用程序:
curl -X POST \
http://localhost:8080/v2/apps \
-d @hello-marathon.json \
-H "Content-type: application/json"
4.Kubernets简介
Kubernetes是一个开源的容器编排系统,最初由Google开发。它现在是云计算基础(CNCF)的一部分。它提供了一个平台,用于跨主机集群自动化应用程序容器的部署、扩展和操作。
4.1 架构
Kubernetes架构由Kubernetes主节点和Kubernetes节点组成
让我们来看看这个高级体系结构的主要部分:
- Kubernetes Master:Master负责维护集群的期望状态。它管理集群中的所有节点。我们可以看到,master是三个过程的集合:kubeapiserver:这是管理整个集群的服务,包括处理REST操作、验证和更新Kubernetes对象、执行身份验证和授权kube控制器管理器:这是一个守护进程,它嵌入了Kubernetes附带的核心控制循环,进行必要的更改以使当前状态与集群的期望状态相匹配kube调度器:该服务监视未调度的pod,并根据请求的资源和其他约束将它们绑定到节点
- Kubernetes节点:Kubernetes集群中的节点是运行容器的机器。每个节点都包含运行容器所需的服务:kubelet:这是主节点代理,它确保kubeapiserver提供的podspec中描述的容器运行正常kube代理:这是在每个节点上运行的网络代理,在一组后端上执行简单的TCP、UDP、SCTP流转发或循环转发容器运行时:这是运行pods内部容器的运行时,Kubernetes有几种可能的容器运行时,包括使用最广泛的Docker运行时
4.2 Kubernetes对象
在最后一节中,我们看到了几个Kubernetes对象,它们是Kubernetes系统中的持久实体。它们反映集群在任何时间点的状态。
让我们来讨论一些常用的Kubernetes对象:
- Pods:Pod是Kubernetes中的基本执行单元,可以由一个或多个容器组成,Pod中的容器部署在同一个主机上
- 部署:部署是在Kubernetes中部署pods的推荐方法,它提供了一些特性,比如不断地将pods的当前状态与所需的状态进行协调
- 服务:Kubernetes中的服务提供了一种公开一组pod的抽象方法,其中分组基于针对pod标签的选择器
还有其他几个Kubernetes对象,它们可以有效地以分布式方式运行容器。
4.3. 例子
所以,现在我们可以尝试将Docker容器启动到Kubernetes集群中。Kubernetes提供Minikube,一个在虚拟机上运行单节点Kubernetes集群的工具。我们还需要kubectl,Kubernetes命令行接口来与Kubernetes集群一起工作。
在安装了kubectl和Minikube之后,我们可以将容器部署到Minikube中的单节点Kubernetes集群上。我们需要在YAML文件中定义基本的Kubernetes对象:
- # hello-kubernetes.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: hello-world
- spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: hello-world
- spec:
- containers:
- - name: hello-world
- image: hello-world:latest
- ports:
- - containerPort: 9001
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: hello-world-service
- spec:
- selector:
- app: hello-world
- type: LoadBalancer
- ports:
- - port: 9001
- targetPort: 9001
这里不可能详细分析此定义文件,但让我们来看看其中的亮点:
- 我们在选择器中定义了一个带有标签的部署
- 我们定义了此部署所需的副本数量
- 此外,我们还提供了容器映像详细信息作为部署的模板
- 我们还定义了一个带有适当选择器的服务
- 我们已经将服务的性质定义为LoadBalancer
最后,我们可以部署容器并通过kubectl创建所有定义的Kubernetes对象:
kubectl apply -f yaml/hello-kubernetes.yaml
5. Mesos vs. Kubernets
现在,我们已经了解了足够的上下文,并且在Marathon和Kubernetes上执行了基本部署。我们可以试着去了解他们之间的对比。
不过,这只是一个警告,直接比较库伯涅茨和介观并不完全公平。我们寻求的大多数容器编排特性都是由一个Mesos框架提供的,比如Marathon。因此,为了保持正确的观点,我们将尝试将Kubernetes与Marathon进行比较,而不是直接比较Mesos。
我们将基于这样一个系统的一些期望属性来比较这些编排系统。
5.1 支持的工作负载
Mesos设计用于处理各种类型的工作负载,这些负载可以是容器化的,甚至可以是非容器化的。这取决于我们使用的框架。正如我们所看到的,使用Marathon这样的框架在Mesos中支持容器化工作负载非常容易。
另一方面,Kubernetes只处理容器化的工作负载。最广泛的是,我们将其用于Docker容器,但它支持其他容器运行时,如Rkt。将来,Kubernetes可能支持更多类型的工作负载。
5.2 支持可扩展性
Marathon支持通过应用程序定义或用户界面进行缩放。Marathon也支持自动缩放。我们还可以扩展应用程序组,它可以自动扩展所有依赖项。
如前所述,Pod是Kubernetes的基本执行单元。当由部署管理时,Pods可以扩展,这就是为什么Pods总是被定义为部署的原因。缩放可以手动或自动进行。
5.3 处理高可用性
Marathon中的应用程序实例分布在Mesos代理之间,从而提供了高可用性。典型的介观团簇由多个代理组成。此外,ZooKeeper通过法定人数和领导人选举为Mesos集群提供高可用性。
类似地,Kubernetes中的pod跨多个节点进行复制,以提供高可用性。通常,Kubernetes集群由多个工作节点组成。此外,集群还可以有多个主节点。因此,Kubernetes集群能够为容器提供高可用性。
5.4 服务发现和负载平衡
Mesos DNS可以为应用程序提供服务发现和基本的负载平衡。Mesos DNS为每个Mesos任务生成SRV记录,并将其转换为运行该任务的机器的IP地址和端口。对于Marathon应用程序,我们还可以使用Marathon-lb使用HAProxy提供基于端口的发现。
在Kubernetes部署可以动态地创建和销毁pod。因此,我们通常通过服务在Kubernetes中公开pod,服务提供服务发现。Kubernetes中的服务充当pods的调度器,因此也提供负载平衡。
5.5 执行升级和回滚
在Marathon中对应用程序定义的更改作为部署处理。部署支持应用程序的启动、停止、升级或扩展。Marathon还支持滚动启动来部署新版本的应用程序。但是,回滚也是直接的,通常需要部署更新的定义。
Kubernetes中的部署支持升级和回滚。我们可以提供部署策略,同时将旧的pod与新的pod重新连接。典型的策略是重新创建或滚动更新。默认情况下,Kubernetes维护部署的部署历史,这使得回滚到以前的版本变得很简单。
5.6 记录和监控
Mesos有一个诊断工具,可以扫描所有集群组件,并提供与健康和其他指标相关的数据。可以通过可用的api查询和聚合数据。我们可以使用像普罗米修斯这样的外部工具来收集这些数据。
Kubernetes将与不同对象相关的详细信息发布为资源度量或完整度量管道。典型的做法是在Kubernetes集群上部署一个外部工具,比如ELK或Prometheus+Grafana。这样的工具可以吸收集群指标并以一种非常用户友好的方式呈现出来。
5.7 存储
Mesos为有状态应用程序提供了持久的本地卷。我们只能从保留资源创建持久卷。它还可以支持外部存储,但有一些限制。Mesos对容器存储接口(CSI)有实验性的支持,CSI是存储供应商和容器编排平台之间的一组公共API。
Kubernetes为有状态容器提供了多种类型的持久卷。这包括iSCSI、NFS等存储。此外,它还支持外部存储。Kubernetes中的Volume对象支持这个概念,并且有多种类型,包括CSI。
5.8 网络
Mesos中的容器运行时提供两种类型的网络支持,即每个容器的IP和网络端口映射。Mesos定义了一个公共接口来指定和检索容器的网络信息。Marathon应用程序可以在主机模式或网桥模式下定义网络。
Kubernetes的网络为每个pod分配一个唯一的IP。这就不需要将容器端口映射到主机端口。它进一步定义了这些pod如何在节点间相互通信。这是在Kubernetes中通过Cilium、Contiv等网络插件实现的。
6. 什么时候用什么?
最后,相比之下,我们通常期待一个明确的判决!然而,不管怎样,宣称一种技术优于另一种技术并不完全公平。正如我们所看到的,Kubernetes和Mesos都是强大的系统,并且提供了相当竞争的特性。
然而,性能是一个非常关键的方面。一个Kubernetes集群可以扩展到5000个节点,而Mesos集群上的Marathon支持多达10000个代理。在大多数实际情况下,我们不会处理这么大的集群。
最后,它归结为灵活性和工作负载的类型。如果我们重新开始,只计划使用容器化的工作负载,Kubernetes可以提供一个更快的解决方案。然而,如果我们现有的工作负载是容器和非容器的混合,那么Mesos和Marathon可能是一个更好的选择。
7.其他替代方案
Kubernetes和ApacheMesos非常强大,但它们并不是这个领域中唯一的系统。我们有很多有前途的选择。虽然我们不会深入讨论它们的细节,但让我们快速列出其中一些:
- Docker Swarm:Docker Swarm是一个开源的Docker容器集群和调度工具。它附带了一个命令行实用程序来管理Docker主机集群。它只限于Docker容器,不像Kubernetes和Mesos。
- Nomad:Nomad是HashiCorp的一个灵活的工作负载协调器,用于管理任何容器化或非容器化应用程序。Nomad将声明性基础设施作为部署Docker容器等应用程序的代码。
- OpenShift:OpenShift是一个来自redhat的容器平台,在底层由Kubernetes编排和管理。OpenShift在Kubernetes提供的基础上提供了许多特性,比如集成映像注册表、源代码到映像构建、本地网络解决方案等等。
8.结论
总之,在本教程中,我们讨论了容器和容器编排系统。我们简要介绍了两个使用最广泛的容器编排系统,Kubernetes和apachemesos。我们还根据几个特点对这些系统进行了比较。最后,我们看到了这个领域的一些其他选择。