如何使用Fleet和Fleectl来管理你的CoreOS集群

来自菜鸟教程
跳转至:导航、​搜索

状态: 已弃用

原因: 2016年12月22日,CoreOS宣布不再维护fleet; 它将在 2017 年 2 月之前收到安全更新和错误修复,届时它将从 CoreOS 中删除。 该项目建议使用 Kubernetes 来满足所有集群需求。

请参阅: 有关在没有队列的情况下在 CoreOS 上使用 Kubernetes 的指导,请参阅 CoreOS 上的 Kubernetes 文档


介绍

CoreOS 为跨多服务器环境管理 Docker 容器提供了极好的环境。 使这种集群管理变得简单的最重要的组件之一是名为 fleet 的服务。

Fleet 允许用户将 Docker 容器作为其整个集群的服务进行管理。 它通过充当每个集群成员的 systemd init 系统的接口和抽象级别来工作。 用户可以设置影响服务运行条件的约束。 这使管理员可以通过根据提供的标准告诉某些应用程序在相同或不同的主机上运行来定义他们希望其基础架构的外观。

在本指南中,我们将探索舰队和 fleetctl 实用程序,可让您控制守护程序。

先决条件

要遵循本指南,您应该有一个可用的 CoreOS 集群。

我们在本指南中使用的集群可以按照我们关于 如何在 DigitalOcean 上创建 CoreOS 集群的指南来创建。 我们将假设您具有该指南中描述的集群配置。

已经配置好的集群有3个节点。 它们被配置为使用专用网络接口在彼此之间进行通信。 公共接口在这些节点中的每一个上都可用于运行公共服务。 节点名称为:

  • coreos-1
  • coreos-2
  • coreos-3

准备好集群后,请继续了解有关车队的更多信息。

使用服务单元文件

在我们进入 fleetctl 工具之前,我们应该先谈谈服务单元文件。

systemd init 系统使用单元文件来描述每个可用的服务,定义管理它所需的命令,并设置依赖信息以确保每个服务启动时系统处于可工作状态。 fleet 守护进程建立在 systemd 之上,以便在集群范围内管理服务。 因此,它使用标准 systemd 单元文件的略微修改版本。

要深入了解 fleet 单元文件,请关注我们关于该主题的 深度潜水 。 对于本指南,我们将粗略概述这些文件的格式。 我们还将提供一个示例单元文件,您可以使用它来了解 fleetctl

舰队单位文件部分

大多数单元文件将具有的基本部分是:

  • Unit:此部分用于提供有关不依赖于单元“类型”的单元的通用信息。 这将包括元数据信息和依赖信息。 这主要用于 fleet 提供描述并指定此单元与其他服务单元连接的位置。
  • Unit Type Sectionfleet daemon 可以采用不同类型的单元,包括:


如果该类型具有特定选项,则允许关联类型的一部分。 Service 部分类型是迄今为止最常见的。 本节用于定义特定于类型的属性。 对于 Service 单元,这通常涉及定义启动和停止命令,以及可能执行相关操作的前后启动或停止命令。

  • X-Fleet:此部分用于提供特定于车队的配置选项。 这主要意味着您可以根据机器 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”。 stop 动作只是停止这个容器。

这足以让您启动并运行。 如果您想了解有关如何开发车队文件的更多信息,请查看我们的车队单元文件指南

基本机器管理命令

我们要做的第一件事是向您介绍 fleetctl 实用程序。 作为集群管理员,此工具将成为您管理机器群的主要界面。 大部分语法都继承自 systemd 的管理工具 systemctl

首先,我们可以通过键入以下内容获取所有集群成员的列表:

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”列当前是空白的。 但是,我们可以在 cloud-config 中的 metadata 属性下添加任意键值对。 这可能看起来像这样:

#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 在名为 /etc/environment 的文件中设置的 COREOS_PRIVATE_IPV4COREOS_PUBLIC_IPV4 变量的值(基于 cloud-config 和网络接口的参数)可用),您可以键入:

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 知道的 all 单位列表。 它还提供了有关所需状态和实际状态的信息:

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

结论

通过学习如何有效地使用 fleetfleetctl,您可以轻松控制您的 CoreOS 集群。 您的服务和容器可以毫无问题地移动到不同的机器上。

在后面的指南中,我们将更深入地讨论 如何创建舰队单元文件 。 这将允许您创建利用 CoreOS 架构的灵活而强大的服务。