如果要说什么样子的分布式集群对用户是最友好的,那无疑是对客户来说,像本地执行命令一样方便的执行集群命令肯定是最舒服的了。这个我们在上一节 集群部署 里面就提到了一个叫做 “fleetctl” 的命令,这个命令是做什么用的呢?
fleet 是什么
工具 fleet
是一个在集群层面上的 systemd
管理工具。它的配置文件语法基于 systemd
的语法,另外添加了一些自有的属性。如果你希望在集群中运行你的服务,那么使用 fleet
管理 systemd
单元是再有必要不过的了。
在比较新的系统 (CentOS 7+、Ubuntu 16+、Debian 8+) 中均采用了 systemd
作为启动项管理工具。如果你对 systemd
有疑问的话,请到其 官方网站 查看具体的介绍,这里不做赘述。
之前使用的 fleetctl
就是 fleet
的管理工具,默认是在集群中的某台机器上进行管理。当然,fleetctl
同样也可以通过远程进行管理,可以通过如下命令连接远程集群。
FLEETCTL_ENDPOINT=http://<IP:[PORT]> fleetctl list-units
fleetctl 常见命令
比较常见的 fleetctl
命令有:
core@core-01 ~ $ fleetctl -h
...
COMMANDS:
cat 查看已经提交的单元文件内容
destroy 销毁集群中的一个或多个单元
fd-forward 将标准输入输出转向到一个 unix socket 中
journal 将集群中的某个 unit 的日志输出到当前
list-machines 查看集群中的已知机器
list-unit-files 查看集群中存在的单元
list-units 查看集群中的单元状态
load 将一个或多个单元加载到集群中,必要时会先执行 submit 功能
ssh 连接到集群中的某台机器
start 启动集群中一个或多个单元,必要时会先执行 submit 和 load 功能
status 输出集群中一个或多个单元的状态
stop 停止集群中一个或多个单元
submit 上传一个或多个单元到集群中,并不会加载执行
unload 卸载集群中的一个或多个单元
fleet 单元文件
以一个 Hello World
程序作为演示来讲解:
[Unit]
Description=Echo Hello World
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox
ExecStartPre=-/usr/bin/docker rm busybox
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox busybox /bin/sh -c "trap'exit 0'INT TERM; while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker stop busybox
看起来基本与 systemd
语法一致。保存成 helloworld.service
,然后执行命令:
core@core-01 ~ $ fleetctl start helloworld.service
Unit helloworld.service inactive
Unit helloworld.service launched on 6e1b9fae.../172.17.8.104
可以通过 fleetctl
查看状态:
core@core-01 ~ $ fleetctl list-units
UNIT MACHINE ACTIVE SUB
helloworld.service 6e1b9fae.../172.17.8.104 active running
core@core-01 ~ $ fleetctl list-unit-files
UNIT HASH DSTATE STATE TARGET
helloworld.service ce68bd4 launched launched 6e1b9fae.../172.17.8.104
同时,可以通过 fleetctl journal
查看程序是否正常运行了。
core@core-01 ~ $ fleetctl journal helloworld
The authenticity of host '172.17.8.104' can't be established.
ECDSA key fingerprint is 11:63:ee:93:e4:b9:5e:06:e9:c6:cd:63:e2:df:ef:9e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.8.104' (ECDSA) to the list of known hosts.
-- Logs begin at Sat 2016-05-28 08:45:39 UTC, end at Sat 2016-05-28 10:09:13 UTC. --
May 28 10:09:04 core-04 docker[1163]: Hello World
May 28 10:09:05 core-04 docker[1163]: Hello World
May 28 10:09:06 core-04 docker[1163]: Hello World
May 28 10:09:07 core-04 docker[1163]: Hello World
May 28 10:09:08 core-04 docker[1163]: Hello World
May 28 10:09:09 core-04 docker[1163]: Hello World
May 28 10:09:10 core-04 docker[1163]: Hello World
May 28 10:09:11 core-04 docker[1163]: Hello World
May 28 10:09:12 core-04 docker[1163]: Hello World
May 28 10:09:13 core-04 docker[1163]: Hello World
通过 fleet 单元文件实现高可用服务
实现高可用服务需要多个服务实例:当其中一个服务实例出现问题时,不会干扰其它服务实例的运行。这里我们还是使用上一节中提到的单元文件,但是需要做额外的修改让其支持多实例运行:
[Unit]
Description=Echo Hello World
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox
ExecStartPre=-/usr/bin/docker rm busybox
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox busybox /bin/sh -c "trap'exit 0'INT TERM; while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker stop busybox
[X-Fleet]
Conflicts=helloworld@*.service
最后新增的内容是 fleet 的专属语法,使用 Conflicts
可以限定每台机器上仅允许一个 helloworld
服务运行。
core@core-01 ~ $ fleetctl stop helloworld
Unit helloworld.service loaded on 6e1b9fae.../172.17.8.104
core@core-01 ~ $ fleetctl unload helloworld
Unit helloworld.service inactive
core@core-01 ~ $ mv helloworld.service helloworld@.service
core@core-01 ~ $ fleetctl start helloworld@1
Unit helloworld@1.service inactive
Unit helloworld@1.service launched on 6e1b9fae.../172.17.8.104
core@core-01 ~ $ fleetctl start helloworld@2
Unit helloworld@2.service inactive
Unit helloworld@2.service launched on 91060182.../172.17.8.103
core@core-01 ~ $ fleetctl start helloworld@3
Unit helloworld@3.service inactive
Unit helloworld@3.service launched on af1494a6.../172.17.8.102
core@core-01 ~ $ fleetctl start helloworld@4
Unit helloworld@4.service inactive
Unit helloworld@4.service launched on c99fef8a.../172.17.8.101
core@core-01 ~ $ fleetctl list-unit-files
UNIT HASH DSTATE STATE TARGET
helloworld.service ce68bd4 inactive inactive -
helloworld@1.service ce68bd4 launched launched 6e1b9fae.../172.17.8.104
helloworld@2.service ce68bd4 launched launched 91060182.../172.17.8.103
helloworld@3.service ce68bd4 launched launched af1494a6.../172.17.8.102
helloworld@4.service ce68bd4 launched launched c99fef8a.../172.17.8.101
卸载之前的 helloworld
,执行了新的 4 个实例,通过观察可以看到目前实例都是运行在了 4 台不同机器上。
fleet 的一些疑问
事实上,通过 fleet,可以将服务进行多副本部署,同时通过 fleet 守护程序的正常运行。但是在实际使用中你会发现有一个实际问题,在微服务化场景中,每个服务部署的机器是无法控制的,那么我们怎么知道服务究竟在哪呢?
如何控制流量流向,或者说服务发现问题,这个我会在下一个 Etcd
的介绍中说一下,敬请期待。