介绍
CoreOS为跨多服务器环境管理Docker容器提供了一个良好的环境。 一个用于使该集群管理简单的最重要组成部分的是一个称为船队服务。
Fleet允许用户将Docker容器作为整个集群的服务来管理。 它通过充当每个集群成员的systemd init系统上的接口和抽象级别来工作。 用户可以设置影响服务运行条件的约束。 这允许管理员通过指定某些应用程序根据提供的条件在相同或不同的主机上运行来定义他们希望其基础结构的外观。
在本指南中,我们将探讨Fleet和fleetctl
工具,它允许您控制守护进程。
先决条件
要遵循本指南,您应该有一个CoreOS集群可用。
我们使用本指南中的集群可以按照我们的指导创建如何创建一个DigitalOcean集群CoreOS 。 我们假设您具有该指南中描述的集群配置。
已配置的集群有三个节点。 它们被配置为使用专用网络接口在彼此之间进行通信。 公共接口在每个这些节点上可用于运行公共服务。 节点名称为:
- coreos-1
- coreos-2
- coreos-3
当您的集群准备就绪后,继续了解有关fleet的更多信息。
使用服务单元文件
在我们进入了fleetctl
工具,我们应该谈谈服务单位的文件了一下。
单位文件用于由systemd
初始化系统来描述每个可用的服务,定义管理它所需的命令,并设置相关性信息,以确保系统处于一个可行的状态,当每个服务启动。 该fleet
守护进程是建立在之上systemd
,以在集群范围内的级别上管理服务。 正因为如此,它采用略作修改的标准版本的systemd
单元文件。
为了得到一个深入了解的fleet
单元文件,按照我们的深潜主体。 对于本指南,我们将简要概述这些文件的格式。 我们还将提供您可以用它来了解一个例子单元文件fleetctl
。
Fleet单位文件部分
大多数单元文件的基本部分是:
- 单元 :这部分是用来提供关于不依赖于所述单元的“类型”的单元的一般信息。 这将包括元数据信息和依赖性信息。 这主要用于
fleet
提供的说明和连接到其它服务单位指定该单位的地方。 - 单位类型栏目在
fleet
守护程序可以采取不同的类型,包括单位:- 服务
- 插座
- 设备
- 安装
- 自动挂载
- 定时器
- 路径
如果类型具有特定选项,则允许关联类型的一部分。 该Service
款型是目前最常见的。 此部分用于定义特定于类型的属性。 对于Service
单位,这通常包括定义的启动和停止,可能执行相关行动的命令,以及前置和后置启动或停止命令。
- 的XFleet :这部分是用来提供特定车队的配置选项。 这主要意味着您可以根据机器ID,当前运行的服务,元数据信息等条件指定服务必须或不必以某种方式计划。
单元文件的一般格式为:
[Unit]
Generic_option_1
Generic_option_2
[Service]
Service_specific_option_1
Service_specific_option_2
[X-Fleet]
Fleet_option_1
Fleet_option_2
示例服务单元文件
要开始使用本教程,我们将给你一个单元文件使用。 这是从所拍摄的CoreOS快速启动页面 ,例如, 在您的一台CoreOS机器上,键入:
vim hello.service
在里面,输入我们的示例服务文件:
[Unit]
Description=My Service
After=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill hello
ExecStartPre=-/usr/bin/docker rm hello
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker stop hello
让我们快速了解这是什么。
在[Unit]
部分,描述信息和我们告诉systemd
认为在此之后服务只能运行docker.service
单位已经开始。 这是因为我们的单元依靠Docker来工作。
在[Service]
部分,我们禁用开始超时,然后我们设置了一些行动,以启动该服务前运行。 该ExecStartPre
在主前执行ExecStart
行动。 如果这些被称为与=-
这意味着该动作可能失败并且不影响服务的完成。 这是必要的,因为我们的预启动操作基本上会删除任何先前正在运行的服务。 这将失败,如果没有找到,我们不希望停止我们的服务,从开始,因为这只是一个清理过程。
最后一个预启动操作拉下了用于运行我们的命令的基本busybox映像。 由于这是必要的,我们不使用=-
语法。 然后我们开始一个容器,这个图像有一个无限循环,每秒打印一次“Hello World”。 停止动作简单地停止此容器。
这将只是足够让你开始运行。 如果您想了解如何开发Fleet的文件,签出更多的信息, 我们的导游船队单元文件 。
基本机器管理命令
我们会做的第一件事是向你介绍fleetctl
工具。 作为集群管理员,此工具将是您管理机器群组的主要接口。 多的语法已从结转systemctl
,systemd的管理工具。
要开始,我们可以通过键入以下内容获取所有集群成员的列表:
fleetctl list-machines
MACHINE IP METADATA
14ffe4c3... 10.132.249.212 -
1af37f7c... 10.132.249.206 -
9e389e93... 10.132.248.177 -
如您所见,您的每台机器在此列为可用。 当每个成员使用cloud-config文件引导自身时,它会生成唯一的机器ID,用于标识每个节点。 这是写在文件/etc/machine-id
。
默认情况下,fleet将使用机器的公共IPv4地址与其他成员通信。 但是,在我们的cloud-config文件中,我们告诉fleet使用我们的私有接口进行通信。 这些是上面输出中显示的IP地址。
在上面的示例中,“METADATA”列当前为空。 不过,我们可以下任意添加键-值对metadata
在云配置Fleet属性。 这可能如下所示:
#cloud-config
. . .
coreos:
fleet:
public-ip: $private_ipv4
metadata: region=europe,public_ip=$public_ipv4
如果你在你的cloud-config中设置引导所有的机器,你的输出看起来更像这样:
MACHINE IP METADATA
14ffe4c3... 10.132.249.212 public_ip=104.131.36.200,region=europe
1af37f7c... 10.132.249.206 public_ip=104.131.15.192,region=europe
9e389e93... 10.132.248.177 public_ip=104.131.15.192,region=europe
此额外数据对于从管理角度快速获取节点的信息很有用,但也可用于服务定义中以定位特定主机。
在集群内连接到特定的机器,你可以使用fleetctl ssh
命令。 这将允许您根据其机器ID或与所提供的设备名称相关联的机器来识别要连接的机器。
举例来说,如果你有一个机组运行叫nginx.service
,您可以连接到任何主机通过键入运行服务:
fleetctl ssh nginx
您将被放入相关主机上的shell会话。 您也可以在远程主机上运行一个命令,就像你可以与正常运行时, ssh
可执行文件。 例如,要得到的值COREOS_PRIVATE_IPV4
和COREOS_PUBLIC_IPV4
的CoreOS套在一个名为变量/etc/environment
(基于云的配置,并提供网络接口的参数),您可以键入:
fleetctl ssh nginx cat /etc/environment
COREOS_PRIVATE_IPV4=10.132.249.212
COREOS_PUBLIC_IPV4=104.131.29.80
服务管理
大部分可通过其他命令fleetctl
都基于服务管理。
启动服务
启动服务涉及相当多的步骤。 服务文件必须上传到fleet
,以便它知道该单元。 然后必须将其调度到集群中的特定机器上。 然后可以启动。 有对每个这些用命令fleetctl
,与负责的后期也进行前如果必要的命令。
您可以使用submit
命令提交你的单元文件到fleet
。 这将会使得fleet
读取文件内容到内存,使其可用于进一步的行动。
fleetctl submit hello.service
您hello.service
现在文件是众所周知的fleet
。 要查看已提交的单元文件,您可以键入:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 inactive inactive -
如您所见,单元文件存在,但尚未在任何主机上预定或启动。
要查看单元文件,该文件的内容fleet
知道,您可以键入:
fleetctl cat hello.service
[Unit]
Description=My Service
After=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill hello
ExecStartPre=-/usr/bin/docker rm hello
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker stop hello
这将允许您查看当前文件fleet
知道。
注 :提交命令是幂等的,这意味着fleet
将不会更新内存单元文件,如果你重新提交。 如果需要更新单元文件,则必须完全将其删除,然后重新提交。 我们将在后面介绍如何做到这一点。
一旦您的单元提交,下一步是在机器上安排它。 调度的单位涉及fleet
引擎寻找本机的最佳机上决定集群中的单元传递给。 这将在内部的条件为前提[X-Fleet]
单位的部分,以及集群中的每一台机器的目前的工作量。 当该单元已经被调度,已经传递给特定的机器和装载到本地systemd
实例。
使用load
命令加载并安排单位:
fleetctl load hello.service
Unit hello.service loaded on 14ffe4c3.../10.132.249.212
如果您以前没有手动加载单元,它将作为此过程的一部分自动加载,方法是在当前目录中搜索适当的文件名。
现在,如果我们检查我们的单元文件,我们可以看到它已经加载。 我们甚至可以看到它安排在哪个机器上:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 loaded loaded 14ffe4c3.../10.132.249.212
这也是我们第一次检查出的机会list-units
命令。 此命令用于显示任何正在运行或计划的单元及其状态:
fleetctl list-units
UNIT MACHINE ACTIVE SUB
hello.service 14ffe4c3.../10.132.249.212 inactive dead
要真正启动的单位,则可以使用start
命令。 这将通过执行在单元文件中定义的启动命令在已加载单元的机器上启动该单元:
fleetctl start hello.service
Unit hello.service launched on 14ffe4c3.../10.132.249.212
再次,我们应检查list-unit-files
:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 launched launched 14ffe4c3.../10.132.249.212
在上面的输出中,我们可以看到服务已经启动。 该DSTATE
列指示“理想状态”和STATE
指示的实际状态。 如果这两个匹配,这通常意味着操作成功。
我们还应该看看list-units
再次:
fleetctl list-units
UNIT MACHINE ACTIVE SUB
hello.service 14ffe4c3.../10.132.249.212 active running
这给了我们有关的信息systemd
状态。 它直接从本地守护程序收集,因此这是更好地了解本地系统如何看到服务状态。 在ACTIVE
列是单位的普遍状态,而SUB
是一个比较低层次的描述。
停止服务
上面的每个命令都有一个可以反转状态的伴随命令。
例如,要停止运行服务,使用stop
指令。 这将导致本地机器的systemd
实例来执行在单元中定义的停止命令:
fleetctl stop hello.service
Unit hello.service loaded on 14ffe4c3.../10.132.249.212
正如你所看到的,该服务已恢复到了loaded
状态。 这意味着,它仍装在机器的systemd
,但当前未运行。 我们可以在这里确认:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 loaded loaded 14ffe4c3.../10.132.249.212
从该机器的systemd除去单元,但保持在现有fleet
,你可以unload
单位。 如果单元当前处于活动状态,则在卸载之前将被停止:
fleetctl unload hello.service
如果我们检查状态,我们可以看到它现在被标记为非活动。 它也没有列出的目标机器:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 inactive inactive -
如果我们要从中删除该单元fleet
完全,我们可以使用destroy
命令。 这将停止并在必要时卸载装置,然后从删除单元fleet
:
fleetctl destroy hello.service
如果修改单元文件,你必须销毁当前单元fleet
递交/重新开始之前。
获取设备状态
您已经看到了一些获取单元状态信息的方法。
举例来说,我们已经讨论了如何list-units
将列出所有当前已预定了机器上的单位:
fleetctl list-units
UNIT MACHINE ACTIVE SUB
hello.service 14ffe4c3.../10.132.249.212 active running
该list-unit-files
规定, 各单位的名单fleet
知道。 它还提供有关所需和实际状态的信息:
fleetctl list-unit-files
UNIT HASH DSTATE STATE TMACHINE
hello.service 0d1c468 launched launched 14ffe4c3.../10.132.249.212
有关已启动的单元的更多特定信息,还有一些其他命令。 该status
的命令传回systemctl status
为运行单位的主机上的服务结果:
fleetctl status hello.service
● hello.service - My Service
Loaded: loaded (/run/fleet/units/hello.service; linked-runtime)
Active: active (running) since Mon 2014-09-08 21:51:22 UTC; 3min 57s ago
Process: 7630 ExecStartPre=/usr/bin/docker pull busybox (code=exited, status=0/SUCCESS)
Process: 7618 ExecStartPre=/usr/bin/docker rm hello (code=exited, status=0/SUCCESS)
Process: 7609 ExecStartPre=/usr/bin/docker kill hello (code=exited, status=0/SUCCESS)
Main PID: 7638 (docker)
CGroup: /system.slice/hello.service
└─7638 /usr/bin/docker run --name hello busybox /bin/sh -c while true; do echo Hello World; sleep 1; done
Sep 08 21:55:11 coreos-3 docker[7638]: Hello World
Sep 08 21:55:12 coreos-3 docker[7638]: Hello World
Sep 08 21:55:13 coreos-3 docker[7638]: Hello World
Sep 08 21:55:14 coreos-3 docker[7638]: Hello World
Sep 08 21:55:15 coreos-3 docker[7638]: Hello World
Sep 08 21:55:16 coreos-3 docker[7638]: Hello World
Sep 08 21:55:17 coreos-3 docker[7638]: Hello World
Sep 08 21:55:18 coreos-3 docker[7638]: Hello World
Sep 08 21:55:19 coreos-3 docker[7638]: Hello World
Sep 08 21:55:20 coreos-3 docker[7638]: Hello World
正如你可以看到的,我们终于得到验证我们的单元的输出正在产生。
同样,如果您希望看到该服务的日记帐分录可在相关的机器上,你可以使用journal
命令:
fleetctl journal hello.service
-- Logs begin at Mon 2014-09-08 14:22:14 UTC, end at Mon 2014-09-08 21:55:47 UTC. --
Sep 08 21:55:38 coreos-3 docker[7638]: Hello World
Sep 08 21:55:39 coreos-3 docker[7638]: Hello World
Sep 08 21:55:40 coreos-3 docker[7638]: Hello World
Sep 08 21:55:41 coreos-3 docker[7638]: Hello World
Sep 08 21:55:42 coreos-3 docker[7638]: Hello World
Sep 08 21:55:43 coreos-3 docker[7638]: Hello World
Sep 08 21:55:44 coreos-3 docker[7638]: Hello World
Sep 08 21:55:45 coreos-3 docker[7638]: Hello World
Sep 08 21:55:46 coreos-3 docker[7638]: Hello World
Sep 08 21:55:47 coreos-3 docker[7638]: Hello World
默认情况下,这将显示最后10行。 您可以通过添加一个调整这个--lines
参数,如下所示:
fleetctl journal --lines 20 hello.service
您也可以使用-f
参数,它表示“跟随”。 这表现在以类似的方式tail -f
,它会不断地传回最新的日志条目:
fleetctl journal -f hello.service
结论
通过学习如何使用fleet
和fleetctl
有效,你可以轻松地控制你的CoreOS集群。 您的服务和容器可以移动到不同的机器,没有什么问题。
在后面的指南中,我们将讨论更深入如何建立Fleet单元文件 。 这将允许您创建利用CoreOS体系结构的灵活和强大的服务。