转载

调度器1 —— 单体调度器

调度是一种向处理资源分配工作载荷的方式。在分布式环境中,调度器格外为大家需要,尤其是那些提供扩展性,资源意识以及高效能特性的调度器。

单体调度器是单个进程实体,进行调度决策并完成需要被调度的任务的部署。这些任务可以是长期运行的服务器程序,短期存在的批处理命令,MapReduce查询,等等。

为了调度任务的决策,单体调度器需要:观察集群中资源的可用性(例如,CPU,内存等),锁住资源,调度任务并更新可用资源。

对于单体调度器而言,它很难一次处理一个以上的任务,因为每个调度实体中只有一个资源管理器实体。相反,避免并发能够使得系统更易设计,更易于理解。

对于单体调度器,这里有一些样本:

  • fleet : CoreOS 的一个本地调度器(无资源意识)
  • Swarm : Docker容器的一个调度后端
  • Kubernetes : 一个 Pods 单体调度器的高级版本

本文将涵盖2个基础单体调度器。

首先,让我们来看看fleet,一个面向 systemd 单元的调度器。systemd是一个高级init子系统,负责配置和启动Linux用户空间。每个单元都是一个独立的systemd配置文件,描述了你希望运行的进程。下文中,我们也会看到Swarm,Docker容器的一个调度后端。

fleet

从本质上说,fleet即集群的systemd。

fleet利用了systemd和 etcd 的优点,其中后者是CoreOS所使用的一个分布式key-value存储,用来创建分布式init系统。在调度一个systemd单元之前,fleet会判断哪个节点目前运行的单元文件最少,然后将下一个单元文件调向该节点。

不过,fleet不是一个具有资源意识的调度器。在进行systemd单元调度时,fleet并不将诸如CPU和内存等可用的系统资源纳入考虑范围。它只使用上述简单算法来进行调度。

我们可以在单元文件中规定一些约束。例如,我们可以声明一个单元文件应该运行在每个主机上。

如下是Fleet单元文件的一个范例,用以部署 Deis储存管理器 :

[Unit]
Description=deis-store-admin

[Service]
EnvironmentFile=/etc/environment
TimeoutStartSec=20m
ExecStartPre=/bin/sh -c "IMAGE=`/run/deis/bin/get_image /deis/store-admin` /
&& docker history $IMAGE >/dev/null 2>&1 || docker pull $IMAGE"
ExecStartPre=/bin/sh -c "docker inspect deis-store-admin >/dev/null 2>&1 /
&& docker rm -f deis-store-admin >/dev/null 2>&1 || true"
ExecStart=/bin/sh -c "IMAGE=`/run/deis/bin/get_image /deis/store-admin` /
&& docker run --name deis-store-admin --rm /
--volumes-from=deis-store-daemon-data /
--volumes-from=deis-store-monitor-data /
-e HOST=$COREOS_PRIVATE_IPV4 $IMAGE"
ExecStopPost=-/usr/bin/docker rm -f deis-store-admin
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

[X-Fleet]
Global=true

约束通过 X-Fleet 部分指定。这里有些指令是提供给fleet本身的,而剩余部分则是提供给systemd。比如,在上述例子中, X-FleetGlobal=true 部分告诉fleet,要在集群中的每个机器上调度(如,部署)该单元。

可以参照 单元文件与调度 来获取关于定制fleet单元文件的更多选项。

通常,你可以使用 fleetctl 命令来提交一个fleet单元。如果你正在使用 Deis ,你可以使用 deisctl 命令。

用户可以通过为fleetctl的 FLEETCTL_TUNNEL (或deisctl的 DEISCTL_TUNNEL )设置集群中任意CoreOS的IP,来指定自己需要通讯的fleet守护进程所在的主机。

如下命令将会在集群中安装一个fleet单元:

deisctl install <unit name>

如下命令将会运行单元:

deisctl start <unit name>

Swarm

Swarm是Docker容器在集群中的一个调度后端。

由于Swarm通过Docker API工作,因此我们可以通过Docker client或者其它和 Docker Engine 通讯的工具,来调度集群中的容器。

Swarm是对 libswarm 项目的扩展。Swarm有一个swarm管理器,它能够和集群中每个节点上的swarm节点通讯。Swarm的优点是支持 过滤器 和描述如何优化一个容器在集群的调度方式的策略。

让我们看一个示例命令:

docker run -d --name bar -e affinity:container==foo bar:v1

在这里,我们通过设定 affinity:container==foo ,告诉Swarm将容器 bar 部署到容器 foo 所在的节点。

用户也可以选择指定软关联,只需使用 ,例如 affinity:container==~foo 。如果foo容器当前不再任何节点中,Swarm将会取消关联,并根据调度策略调度容器。当前,Swarm支持的调度策略有: spead , bin packing 和 random 。

缺省情况下, Deis 使用fleet后端。不过现版本的Deis亦支持Swarm。

想要安装Swarm,只需运行:

deisctl install swarm && deisctl start swarm

切换调度后端:

deisctl config controller set schedulerModule=swarm

总结

单体调度器的设计限制了性能和吞吐量。

由于资源管理器和调度器位于同一进程,单体调度器对于集群中的资源动态变化并不敏感。且调度是紧耦合的,这也就限制了扩展性。比如,fleet只能够调度systemd单元,Swarm只能够调度docker容器。

fleet是相对底层的调度器,并且没有资源意识。因此并不建议在超过100个节点的集群中使用fleet。幸运的是,Deis V2将能够和Kubernetes协同工作,后者是一个更加高级的调度器。Swarm也有其自身的缺点,比如,在0.2版本中,Swarm不支持节点的故障切换。因此,当一个节点变得不可用时,Swarm不会为故障节点上的容器重新调度。

在下一篇文章中,我们将会介绍高级调度器,例如Kubernetes,Apache Mesos,Omega和Sparrow。同时,我们也会讨论这些工具,相较诸如Swarm和fleet之类的基础单体调度器所做的改进。

原文链接: Schedulers, Part 1: Basic Monolithic (翻译:孙科)

原文  http://dockone.io/article/1229
正文到此结束
Loading...