CoreOS 折腾笔记(二)Fleet 进阶

如果要说什么样子的分布式集群对用户是最友好的,那无疑是对客户来说,像本地执行命令一样方便的执行集群命令肯定是最舒服的了。这个我们在上一节 集群部署 里面就提到了一个叫做 “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 的介绍中说一下,敬请期待。

Built with Hugo
主题 StackJimmy 设计