Fleet 跨节点服务调度

在 Systemd 的许多工具中,例如 systemctl 命令,都有一个 “–host”参数,它提供了一种可以跨主机操作另一个节点上服务的方法。然而,这种方式仍然具有比较大的局限性。

  • 节点间必须相互添加 SSH Key 信任,因为 Systemd 的远程操作是通过 SSH 连接进行的。
  • 操作时每次都必须指明目的节点的用户名和主机地址(IP 地址)。
  • 只能够远程控制已有的服务,但不能远程创建服务。
  • 仅限简单的服务操作,对于同时牵连多个节点的情况无能为力。例如,将服务迁移到另一个节点上运行。

为了更方便地在集群中部署和管理服务,CoreOS 基于 Systemd 的接口设计了服务调度工具 FLeet,它继承并扩展了 Unit 文件格式,使之更加适用于集群环境的服务配置。

Fleet的基本操作

Fleet 服务实际上是由运行在每一个节点上的后台服务进程 fleetd 组成的。此外,Fleet 还提供了一个用于交互控制的工具:fleetctl。

  • fleetctl list-machines 查看整个集群的基本信息
  • fleetctl list-units 查看整个集群的所有服务
  • fleetctl ssh ID 跳转到指定节点(需要添加公钥)
  • fleetctl ssh ID CMD 跨节点执行命令

通过 Unit 文件运行跨节点调度的服务

Fleet 的 Unit 文件

在服务管理方面,Fleet 使用和 Systemd 相似的 Unit 文件进行配置。不同的地方在于,Fleet 额外支持一个 X-Fleet 配置段,用于指定服务可以在哪些节点上运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=Hello World
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker kill busybox1
[X-Fleet]
X-Conflicts=hello*.service

最后的 X-Fleet 配置段的 X-Conflicts 属性指定了这个 Hello 服务不能运行在“任意已经分配了任何名字以 hello 开头的服务”的节点上。

在集群上运行服务

由于 Fleet 需要在集群层面上对服务进行管理,因此它的服务管理流程与 Systemd 略有不同。最明显的区别是,Fleet 没有指定 Unit 文件必须放置在哪些目录下 ,而是直接通过参数的方式告诉 fleetctl 命令。

$ fleetctl start ${HOME}/hello.service

Fleet 的 X-Fleet 段

  • MachineID: 直接了当地告诉 Fleet 这个服务只能运行在特定节点上。注意,这里的值必须是完整的节点 ID,这个 ID 可以通过 “fleetctl list-machines -l”命令获得。
  • MachineOf: 值是另一个“.service”文件,表示当前服务必须与指定的这个服务运行在同一个节点上。
  • MachineMetadata: 值是一个节点的 Metadata 内容,例如“region=us-east-1”,这些 Metadata 是在启动节点时通过 Cloudinit 写进去的。这个参数可以使用多次,或者通过空格将多个值同时传进去。
  • Conflicts: 值是一个 .service 文件名或用于匹配文件名的通配字符串,Conflicts 参数也可以使用多次,并且其值可以使用通配符,例如 apache* 表示所有以“apache”开头的服务。
  • Global: 如果值为 true,则这个服务会被部署到集群中符合 MachineMetadata 限定条件的每一个节点上。注意,当 Global 值为 true 时,除了 MachineMetadata 以外的所有其它约束条件都会被忽略。

模版参数

Fleet 的 Unit 模版文件与 Systemd 的模版文件基本一致,同样在文件名的末尾有一个特征式的@符号。

虽然 Fleet 没有特定的 Unit 文件存放目录,但是只要在通过“fleetctl start”或“fleetctl submit”命令指定 Unit 文件路径时加上后缀参数,Fleet 同样会自动匹配去掉后缀参数的模版文件。例如 “fleetctl submit ${HOME}/apache@8080.service”,就会匹配到 ${HOME} 目录下面的 apache@.service 模版文件。

几乎所有的 Unit 模版文件都会使用到“%i”参数,因为它代表的是运行具体服务时,写在@符号后面部分的内容,这个值对于区分各个服务实例具有十分重要的意义。

集群中的服务生命周期

  • fleetctl submit ${PWD}/xxx.service 提交服务,将指定的 Unit 文件添加到 Fleet 的记录缓存中。
  • fleetctl cat xxx.service 打印已经缓存了的 Unit 文件内容
  • fleetctl load xxx.service 就绪
  • fleetctl start xxx.service 启动服务,并设置自动启动
  • fleetctl stop xxx.service 停止服务
  • fleetctl status xxx.service 查看服务状态
  • fleetctl journal xxx.service 查看服务日志
  • fleetctl journal –lines 20 xx.service 最新20行日志
  • fleetctl journal –follow xxx.service 跟随日志输出

服务热迁移

除了自动选择部署的节点外,Fleet的另一个重要功能便是在节点出现故障时,自动将故障节点上运行的服务迁移到另一个健康节点上。