Documentation

7. 集群

集群是冗余的替代方法,替换通过主动-被动节点配置并涉及主 (primary) 实例和从 (secondary) 实例的冗余解决方案。对于 3.1 以前的版本,请参阅 Ansible Tower Administration Guide 的本章的旧版本。

集群在主机间共享负载。每个实例都应当能够作为 UI 和 API 访问的入口点。这可以让 Tower 管理员在尽可能多的实例中使用负载均衡器,并保持良好的数据可见性。

注解

负载均衡是可选的,可以完全根据需要在一个或多个实例上设有入口。

每个实例都应当能够加入 Tower 集群并扩展其执行作业的能力。这是一个简单的系统,作业可以并将会在任何位置运行,而不是定向在哪里运行。另外,集群实例可以被分组成不同的池/队列,称为 实例组

Tower 支持使用 OpenShift 或 Kubernetes 的基于容器的集群,这意味着可在这些平台上安装新的 Tower 实例,无需更改或转变功能。但是,有某些 OpenShift 部署和配置 差别必须进行考虑。在 Ansible Tower 版本 3.6 中,您可以创建实例组来指向 Kubernetes 容器。更多详情,请参阅 执行环境 部分。

支持的操作系统

支持以下操作系统来建立集群环境:

  • Red Hat Enterprise Linux 7 或更高版本(推荐使用 RHEL8,可以是 RHEL 7 或 centos 7 实例)

注解

在 OpenShift 中运行 Ansible Tower 不支持隔离的实例。

7.1. 设置注意事项

本节仅涵盖集群的初始设置。要升级现有集群,请参阅 Ansible Tower Upgrade and Migration GuideUpgrade Planning

新集群环境中需要注意的事项:

  • PostgreSQL 仍然是一个独立的实例,没有集群。Tower 不管理副本配置或数据库故障转移(如果配置了待机备份系统)。

  • 当集群升级时,数据库节点应当是独立服务器,而 PostgreSQL 则不应安装到 Tower 的一个节点上。

  • 集群中的实例数量应始终是一个奇数,且**强烈推荐**集群中至少有三个 Tower 实例,支持的最大值为 20。当达到这么高时,对奇数节点的要求会变得不太重要。

  • 所有实例都应能够从其他所有实例访问,并应能够访问数据库。另外,主机也必须拥有一个稳定的地址和/或主机名(取决于 Tower 主机的配置方式)。

  • 所有实例都必须进行地理上的分配,实例间有可靠的低延迟连接。

  • RabbitMQ 是 Tower 的集群系统的基础。许多配置要求和行为都是由它的需要决定。因此,超出 Tower 的设置 (setup) playbook 的自定义是有限的。每个 Tower 实例都部署了 RabbitMQ,它将与其他实例的 RabbitMQ 实例进行集群。

  • 为了升级到集群环境,您的主实例必须是清单中的 tower 组的一部分。*并且*它需要是 tower 组中列出的第一个主机。

  • 用户必须手动将手动项目同步到所有实例,同时对所有实例进行更新。

  • 在新的 Tower 系统中没有主 (primary)/从 (secondary) 系统的概念。所有系统都是主系统。

  • 设置 (Setup) playbook 进行更改以配置 RabbitMQ,并提供主机所在网络的类型。

  • 用于 Tower 部署的 inventory 文件应当被保存且有持久性。如果要置备新实例,则必须为安装程序提供密码和配置选项以及主机名。

7.2. 安装和配置

置备新实例涉及更新 inventory 文件并重新运行设置 (setup) playbook。务必确保 inventory 文件包含在安装集群时使用的所有密码和信息,或者其他实例可以重新配置。对于 3.1 或更高版本的部署,当前的独立实例配置不会改变。inventory 文件在某些重要方面发生了变化:

  • 因为没有主 (primary)/从 (secondary) 配置,这些清单组已过时,并被替换为单个清单组 tower

注解

所有实例都会负责各种与任务调度相关的托管任务,比如确定要启动的作业和处理 playbook 事件,以及定期清理。

[tower]
hostA
hostB
hostC

[instance_group_east]
hostB
hostC

[instance_group_west]
hostC
hostD

注解

如果没有为资源选择任何组,则使用 tower 组,但如果选择了组,则不会使用 tower 组。

database 组为指定外部 PostgreSQL 而保留。如果单独置备数据库主机,则该组应为空:

[tower]
hostA
hostB
hostC

[database]
hostDB

在外部置备 Tower 实例比较常见,但最好通过内部寻址来引用实例。这对于在外部接口上服务不可用的 RabbitMQ 集群来说最为重要。为此,需要为 RabbitMQ 链接分配内部地址,如:

[tower]
hostA rabbitmq_host=10.1.0.2
hostB rabbitmq_host=10.1.0.3
hostC rabbitmq_host=10.1.0.4

注解

集群中的实例数量应始终是一个奇数,且**强烈推荐**集群中至少有三个 Tower 实例,支持的最大值为 20。当达到这么高时,对奇数节点的要求会变得不太重要。

  • redis_password 字段已从 [all:vars] 中删除

  • RabbitMQ 的字段如下:

    • rabbitmq_port=5672:每次安装时均安装 RabbitMQ,不是可选项,也不能将其外部化。此设置配置了它监听的端口。

    • rabbitmq_vhost=tower:控制 Tower 配置 RabbitMQ 虚拟主机来隔离其自身的设置。

    • rabbitmq_username=towerrabbitmq_password=tower:每个实例和每个实例的 Tower 实例都用这些值进行配置。这与 Tower 的其他用户名/密码使用类似。

    • rabbitmq_cookie=<somevalue>:此值在独立部署中不使用,但对集群式部署来说至关重要。它可作为 secret 密钥,允许 RabbitMQ 集群成员相互识别。

    • rabbitmq_enable_manager:将此项设置为 true,以在每个实例上公开 RabbitMQ 管理 Web 控制台。

7.2.1. RabbitMQ 默认设置

以下配置显示了 RabbitMQ 的默认设置:

rabbitmq_port=5672
rabbitmq_vhost=tower
rabbitmq_username=tower
rabbitmq_password=''
rabbitmq_cookie=cookiemonster

注解

rabbitmq_cookie 这是一个敏感值,应当像 Tower 中的 secret key 一样对待。

7.2.2. Tower 使用的实例和端口

Tower 使用的端口和实例如下:

  • 80, 443(正常的 Tower 端口)

  • 22 (ssh)

  • 5432(数据库实例——如果数据库安装在外部实例上,则需要对 tower 实例打开)

集群/RabbitMQ 端口:

  • 4369, 25672(RabbitMQ 专门的用来维护集群的端口,需要在每个实例之间打开)

  • 15672(如果启用了 RabbitMQ Management Interface,则需要打开此端口(可选))

7.2.3. 可选 SSH 身份验证

对于希望通过 Tower 外的一些系统(比如外部管理的无密码 SSH 密钥)管理从“controller”节点到“isolated”节点的 SSH 身份验证的用户,可以通过取消设置两个 Tower API 设置值来禁用此行为:

HTTP PATCH /api/v2/settings/jobs/ {'AWX_ISOLATED_PRIVATE_KEY': '', 'AWX_ISOLATED_PUBLIC_KEY': ''}

7.3. 通过浏览器 API 报告状态和进行监控

Tower 自身通过 /api/v2/ping 处的可浏览 API 报告尽可能多的状态,以便提供集群健康状况验证,包括:

  • 为 HTTP 请求提供服务的实例

  • 集群中所有其他实例的最后一个心跳 (heartbeat) 的时间戳

  • 这些组中的实例组和实例成员资格

查看关于实例和实例组的更多详细信息,包括 /api/v2/instances//api/v2/instance_groups/ 处的正在运行的作业和成员资格信息。

7.4. 实例服务和故障行为

每个 Tower 实例由几个不同的服务组成,它们协调工作:

  • HTTP 服务 - 包括 Tower 应用本身以及外部 Web 服务。

  • 回调接收器 - 从正在运行的 Ansible 作业接收作业事件。

  • 分配程序 - 处理并运行所有作业的 worker 队列。

  • RabbitMQ - 此消息代理用作分配程序以及向应用传播的事件数据的一个信号机制。

  • Memcached - 所在实例的本地缓存服务。

Tower 配置为:如果任何这些服务或其组件故障,则所有服务将会重启。如果这些故障在较短的时间内频繁出现,则整个实例将自动变为离线,以便进行补救,避免造成意外行为。

要备份和恢复集群环境,请参考 集群环境的备份和恢复 部分。

7.5. 作业运行时行为

作业运行并报告给 Tower 的“常规”用户的方式不会改变。在系统端,需要注意一些差异:

  • 当从 API 接口提交作业时,作业会推送到 RabbitMQ 上的分配程序队列中。单个 RabbitMQ 实例负责单独队列的 master,但每个 Tower 实例都将使用特定的调度算法连接该队列并从队列接收作业。集群中的任何实例都可能接收工作并执行作业。如果实例在执行任务时失败,则该工作标记为永久失败。

Tower Cluster example

  • 项目更新在 Ansible Tower 3.6 中的表现不同。在以前的版本中,项目更新是在单个实例上运行的普通作业。现在,项目更新必须在可能运行作业的所有实例上成功运行。在运行作业前,项目立即与实例上的正确版本同步。如果需要的修订版本已经在本地签出,并且不需要 galaxy 或集合更新,则无法执行同步。

  • 当同步发生时,通过 launch_type = syncjob_type =  run 在数据库中将其记录为项目更新。项目同步不会更改项目的状态或版本;相反,它*仅*在其运行的实例上更新源树。

7.5.1. 作业运行

在默认情况下,当作业被提交到 tower 队列时,任何 worker 都可以选择它。但是,您可以控制某个特定作业的运行位置,例如限制在其上运行作业的实例。

为了支持暂时关闭某个实例的功能,在每个实例上定义了一个启用的属性。禁用这个属性时,不会为该实例分配任何作业。现有的作业将会完成,但不会分配新的工作。

7.6. 取消置备实例

重新运行设置 (setup) playbook 不会自动取消置备实例,因为集群目前不会区分有意关闭的实例与因故障而关闭的实例。而是,关闭 Tower 实例上的所有服务,然后从任何其他实例运行取消置备工具:

  1. 使用命令 ansible-tower-service stop 关闭实例或停止服务。

  2. 从另一个实例运行取消置备命令 $ awx-manage deprovision_instance --hostname=<name used in inventory file>,将其从 Tower 集群 registry 和 RabbitMQ 集群 registry 中删除。

    示例:awx-manage deprovision_instance --hostname=hostB

同样,在 Tower 中取消置备实例组不会自动取消置备或删除实例组。如需了解更多信息,请参阅 Deprovision Instance Groups 部分。