文档

9. 执行环境

Tower 允许您通过 ansible 剧本运行直接在集群成员上或在预先配置的隔离节点上执行作业。在 Ansible Tower 3.8 中,您只能根据需要针对每个剧本在容器组中执行作业。有关更多信息,请参阅本节结尾处的 容器组

9.1. 实例组

实例可以分组到一个或多个实例组中。实例组可以分配给下面列出的一个或多个资源。

  • 组织

  • 清单

  • 作业模板

当与某个资源关联的作业执行时,它将被分配给与该资源关联的实例组。在执行过程中,与作业模板关联的实例组将在与清单关联的实例组之前进行检查。同样,与清单关联的实例组将在与组织关联的实例组之前进行检查。因此,这三个资源的实例组分配形成一个层次结构:作业模板 > 清单 > 组织。

以下是一些在使用实例组时需要考虑的事项

  • 您可以选择定义其他组并在这些组中分组实例。这些组应该以 instance_group_ 为前缀。实例不必位于与其他 instance_group_ 组并列的 tower 组中,但必须在 tower 组中存在一个实例。从技术上讲,tower 与任何其他 instance_group_ 组一样,是一个组,但它必须始终存在,如果特定组未与特定资源相关联,那么作业执行将始终回退到 tower 组。 tower 实例组始终存在(它无法删除或重命名)。

  • 不要创建名为 instance_group_tower 的组。

  • 不要将任何实例命名为与组名相同。

9.1.1. 通过 API 配置实例组

系统管理员可以通过 POST 到 /api/v2/instance_groups 来创建实例组。

创建后,可以使用以下方法将实例与实例组关联

HTTP POST /api/v2/instance_groups/x/instances/ {'id': y}`

添加到实例组的实例将自动重新配置自身以侦听该组的工作队列。有关更多详细信息,请参阅下一节 实例组策略

9.1.2. 实例组策略

您可以通过定义 策略来配置 Tower 实例,以便在它们上线时自动加入实例组。这些策略将针对每个新上线的实例进行评估。

实例组策略由 Instance Group 上的三个可选字段控制

  • policy_instance_percentage: 这是一个介于 0 - 100 之间的数字。它保证一定比例的活动 Tower 实例将被添加到此实例组中。当新实例上线时,如果此组中实例的数量相对于实例总数而言低于给定百分比,那么新的实例将被添加到此组中,直到满足百分比条件为止。

  • policy_instance_minimum: 此策略尝试在实例组中保留至少这么多个实例。如果可用实例的数量低于此最小值,那么所有实例都将被放置到此实例组中。

  • policy_instance_list: 这是一个始终包含在该实例组中的实例名称的固定列表。

Ansible Tower 用户界面中的实例组列表视图根据实例组策略提供了每个实例组的容量级别摘要

Instance Group policy example

9.1.3. 值得注意的策略注意事项

  • policy_instance_percentagepolicy_instance_minimum 都设置了最小分配。导致更多实例分配给组的规则将生效。例如,如果您有 50% 的 policy_instance_percentage 和 2 个 policy_instance_minimum,并且您启动了 6 个实例,那么其中 3 个将被分配到实例组。如果将集群中的总实例数减少到 2 个,那么它们中的两个都将被分配到实例组以满足 policy_instance_minimum。这样,您可以设置可用资源量的下限。

  • 策略不会主动阻止实例与多个实例组关联,但可以通过将百分比加起来达到 100 来有效地实现这一点。如果您有 4 个实例组,为每个实例组分配 25% 的百分比值,实例将分配到它们之间,不会重叠。

9.1.4. 手动将实例固定到特定组

如果您有一个特殊实例需要专用于特定的实例组,但又不想让它通过“百分比”或“最小”策略自动加入其他组

  1. 将实例添加到一个或多个实例组的 policy_instance_list

  2. 将实例的 managed_by_policy 属性更新为 False

这将阻止实例根据百分比和最小策略自动添加到其他组;它只属于您手动分配给它的组

HTTP PATCH /api/v2/instance_groups/N/
{
"policy_instance_list": ["special-instance"]
}

HTTP PATCH /api/v2/instances/X/
{
"managed_by_policy": False
}

9.1.5. 作业运行时行为

当您运行与实例组关联的作业时,一些值得注意的行为是

  • 如果集群被分成单独的实例组,那么行为类似于整个集群。如果两个实例分配给一个组,那么任何一个实例都与同一组中的任何其他实例一样有可能接收作业。

  • 当 Tower 实例上线时,它实际上扩展了 Tower 系统的工作能力。如果这些实例也被放置在实例组中,那么它们也会扩展该组的能力。如果一个实例正在执行工作并且它是多个组的成员,那么它的能力将从它所属的所有组中减少。取消配置一个实例将从集群中删除它被分配到的任何地方的能力。有关更多详细信息,请参阅取消配置实例部分。

注意

并非所有实例都需要以相同的容量进行配置。

9.1.6. 控制作业运行的位置

如果作业模板、清单或组织中的任何一个与实例组相关联,那么从该作业模板运行的作业将不符合默认行为。这意味着如果与这 3 个资源关联的实例组中的所有实例都已达到容量,那么作业将保持在挂起状态,直到容量变得可用。

确定向哪个实例组提交作业的优先级顺序如下

  1. 作业模板

  2. 清单

  3. 组织(通过项目)

如果实例组与作业模板相关联,并且所有这些都已达到容量,那么该作业将被提交到清单中指定的实例组,然后是组织。作业应在这些组中按优先级顺序执行,前提是资源可用。

全局 tower 组仍然可以与资源关联,就像 playbook 中定义的任何自定义实例组一样。这可用于在作业模板或清单上指定首选实例组,但仍允许将作业提交到任何实例,即使这些实例已达到容量。

例如,通过将 group_a 与作业模板关联,并将 tower 组与它的清单关联,您允许 tower 组用作备用,以防 group_a 达到容量。

此外,可以选择不将实例组与一个资源关联,而是指定另一个资源作为备用。例如,不将实例组与作业模板关联,并使其回退到清单和/或组织的实例组。

这提出了另外两个很好的用例

  1. 将实例组与清单关联(省略将作业模板分配给实例组)将允许用户确保针对特定清单运行的任何 playbook 仅在与它关联的组上运行。这在只有这些实例与受管节点有直接链接的情况下非常有用。

  2. 管理员可以将实例组分配给组织。这有效地允许管理员隔离整个基础架构并保证每个组织都有运行作业的能力,而不影响任何其他组织运行作业的能力。

同样,管理员可以根据需要将多个组分配给每个组织,如以下场景所示

  • 有三个实例组:A、B 和 C。有两个组织:Org1 和 Org2。

  • 管理员将组 A 分配给 Org1,将组 B 分配给 Org2,然后将组 C 分配给 Org1 和 Org2,作为可能需要的任何额外容量的溢出。

  • 然后,组织管理员可以自由地将清单或作业模板分配到他们想要的任何组(或只让他们从组织继承默认顺序)。

Instance Group example

以这种方式安排资源提供了很大的灵活性。此外,您可以创建只包含一个实例的实例组,从而允许您将工作直接定向到 Tower 集群中非常特定的主机。

9.1.7. 取消配置实例组

重新运行安装 playbook 不会自动取消配置实例,因为集群目前不区分有意脱机或由于故障而脱机的实例。相反,关闭 Tower 实例上的所有服务,然后从任何其他实例运行取消配置工具

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

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

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

同样,取消配置 Tower 中的实例组不会自动取消配置或删除实例组,即使重新配置通常会导致这些实例组未使用。它们可能仍然显示在 API 端点和统计信息监控中。可以使用以下命令删除这些组

示例:awx-manage unregister_queue --queuename=<name>

从清单文件中删除实例对实例组的成员资格并重新运行安装 playbook 无法确保实例不会被添加回组。要确保实例不会被添加回组,请通过 API 删除,并在清单文件中删除它,或者您可以完全停止在清单文件中定义实例组。您也可以通过 Ansible Tower 用户界面管理实例组拓扑。有关在 UI 中管理实例组的更多信息,请参阅实例组,该页面位于Ansible Tower 用户指南中。

9.1.8. 隔离的实例组

Tower 能够选择性地在安全受限的网络区域内定义隔离的组,用于运行作业和临时命令。这些组中的实例将不会安装完整的 Tower,但将拥有运行作业所需的一组最小的实用程序。必须在清单文件中指定隔离组,并以 isolated_group_ 为前缀。以下是一个隔离实例组清单文件的示例。

[tower]
towerA
towerB
towerC

[instance_group_security]
towerB
towerC

[isolated_group_govcloud]
isolatedA
isolatedB

[isolated_group_govcloud:vars]
controller=security

在隔离实例组模型中,“控制器”实例通过一系列 SSH 上的 Ansible playbook 与“隔离”实例交互。在安装时,默认情况下,会生成一个随机的 RSA 密钥,并将该密钥作为授权密钥分发给所有“隔离”实例。该密钥的私钥部分被加密并存储在 Tower 数据库中,用于在“控制器”实例运行作业时向“隔离”实例进行身份验证。

当一个作业被安排在“隔离”实例上运行时

  • “控制器”实例会编译运行作业所需的元数据,并将其复制到“隔离”实例。

  • 一旦元数据同步到隔离主机,"控制器" 实例就会在 "隔离" 实例上启动一个进程,该进程会消耗元数据并开始运行 ansible/ansible-playbook。当 playbook 运行时,作业工件(如 stdout 和作业事件)将写入 "隔离" 实例上的磁盘。

  • 当作业在“隔离”实例上运行时,“控制器”实例会定期从“隔离”实例复制作业工件(stdout 和作业事件)。它会一直消耗这些工件,直到作业在“隔离”实例上完成运行。

注意

如果控制器节点在隔离运行过程中脱机,则控制器节点会失败。如果 Tower 节点重新启动,或者调度程序在 playbook 运行期间停止,则在该节点上运行的作业会失败,并且在调度程序上线时不会重新启动。

可以创建隔离组(节点),以便它们可以存在于 VPC 中,该 VPC 的安全规则只允许其控制器组中的实例访问它们;只需要从 "控制器" 实例到 "隔离" 实例的入站 SSH 流量。在配置隔离节点时,您的安装机器需要能够连接到隔离节点。在隔离节点不可直接访问但可以通过其他主机间接访问的情况下,您可以通过在 SSH 配置中使用 ProxyCommand 指定跳转主机,然后运行安装程序。

Isolated nodes daisy chain example

Jump Host example

具有隔离组的推荐系统配置如下

  • 不要创建名为 isolated_group_tower 的组。

  • 不要将任何隔离实例放入 tower 组或其他普通实例组中。

  • 将控制器变量定义为所有隔离组中的实例的组变量或主机变量。不允许隔离组中的同一组中的隔离实例具有该变量的不同值 - 这种情况下行为不可预测。

  • 不要将一个孤立的实例放在多个孤立组中。

  • 不要将一个实例同时放在普通组和孤立组中。

  • 孤立实例可以安装在 RHEL 7 及更高版本上。

  • 与孤立组相关的以下持续时间可以在“设置” (settings) 菜单的“作业”选项卡中配置

    • **孤立状态检查间隔**: 30 秒是为在孤立实例上运行的作业设置的状态检查之间睡眠时间的默认值。

    • **孤立启动超时**: 600 秒 (10 分钟) 是在孤立实例上启动作业的默认超时时间。这包括将源代码控制文件(剧本)复制到孤立实例所需的时间。

    • **孤立连接超时**: 10 秒是与孤立实例通信时默认的 Ansible SSH 连接超时时间。此值应明显大于预期的网络延迟。

在 Tower 用户界面中,实例组列表视图中相应地标记了孤立组。

_images/instance-group-list-with-isolated-group.png

9.2. 容器组

注意

容器组功能处于技术预览阶段,可能会在将来的版本中发生更改。

Ansible Tower 支持 容器组,它允许您在 Tower 中执行作业,无论 Tower 是作为独立程序、虚拟环境还是容器安装。容器组充当虚拟环境中的资源池。您可以创建实例组以指向 OpenShift 容器,这些容器是在按需基础上作为 Pod 进行供应的作业环境,该 Pod 只存在于剧本运行的持续时间内。这被称为短暂执行模型,并确保每个作业运行的干净环境。

在某些情况下,需要执行环境“始终处于活动状态”,这可以通过创建实例来配置。

9.2.1. 创建容器组

要设置容器组,您必须首先拥有以下内容

  • 可以启动到的命名空间(存在一个“默认”命名空间,但大多数情况下会因客户而异)

  • 具有允许它在该命名空间中启动和管理 Pod 的角色的服务帐户

  • 与该服务帐户关联的令牌(OpenShift 或 Kubernetes Bearer 令牌)

  • 与集群关联的 CA 证书

以下是如何创建服务帐户并收集配置 Ansible Tower 所需的信息的示例

  1. 下载并使用此示例,containergroup sa,以获取上述凭据。

  2. 应用 containergroup-sa.yml 中的配置

    oc apply -f containergroup-sa.yml
    
  3. 获取与服务帐户关联的秘密名称

    export SA_SECRET=$(oc get sa containergroup-service-account -o json | jq '.secrets[0].name' | tr -d '"')
    
  4. 从秘密获取令牌

    oc get secret $(echo ${SA_SECRET}) -o json | jq '.data.token' | xargs | base64 --decode > containergroup-sa.token
    
  5. 获取 CA 证书

    oc get secret $SA_SECRET -o json | jq '.data["ca.crt"]' | xargs | base64 --decode > containergroup-ca.crt
    
  6. 使用 containergroup-sa.tokencontainergroup-ca.crt 的内容来提供 OpenShift 或 Kubernetes API Bearer 令牌 的信息,该令牌是容器组所需的。

要创建容器组

  1. 使用 Tower 用户界面创建 OpenShift 或 Kubernetes API Bearer 令牌 凭据,该凭据将与您的容器组一起使用。有关详细信息,请参阅Ansible Tower 用户指南中的 添加新凭据

  2. 通过导航到实例组配置窗口 instance group icon 来创建一个新的容器组。

  1. 单击 add 按钮并选择**创建容器组**。

IG - create new CG

  1. 输入新容器组的名称,并选择之前创建的凭据将其与容器组相关联。

9.2.2. 自定义 Pod 规范

Tower 提供了一个简单的默认 Pod 规范,但是,您可以提供一个自定义 YAML(或 JSON)文档,该文档将覆盖默认 Pod 规范。此字段使用可以“序列化”为有效 Pod JSON 或 YAML 的任何自定义字段(例如,imagenamespace)。可以在 OpenShift 文档 中找到所有选项的完整列表。

要自定义 Pod 规范,请使用切换按钮启用和展开**Pod 规范覆盖**字段,并在**Pod 规范覆盖**字段中指定命名空间,完成后单击**保存**。

IG - CG customize pod

如果需要,您可以提供额外的自定义。单击**展开**以查看整个自定义窗口。

_images/instance-group-customize-cg-pod-expanded.png

注意

默认容器组映像是从 registry.redhat.com 中提取的。这意味着应该在 Pod 规范中指定映像提取秘密 (imagePullSecrets)。有关如何创建映像提取秘密的更多信息,请参阅 Red Hat Container Registry 身份验证文章 中的允许 Pod 引用来自其他安全注册表的映像部分。

成功创建容器组后,将保留新创建的容器组的**详细信息**选项卡,允许您查看和编辑容器组信息。如果从**实例组**链接中单击编辑 (edit-button) 按钮,将打开相同的菜单。您还可以编辑**实例**并查看与该实例组关联的**作业**。

IG - example CG successfully created

容器组和实例组已相应标记。

注意

尽管客户拥有自定义 Pod 规范,但如果默认的 pod_spec 发生更改,升级可能会很困难。大多数任何清单都可以应用于任何命名空间,其中命名空间分别指定,您很可能只需要覆盖命名空间。类似地,将 Tower 的不同版本的默认映像固定到默认作业运行程序容器的不同版本很棘手。如果默认映像在 Pod 规范中指定,那么升级不会拾取对默认 Pod 规范进行的默认更改。

9.2.3. 验证容器组功能

要验证容器的部署和终止

  1. 创建一个模拟清单,并在**实例组**字段中填充容器组的名称,将其与该容器组相关联。有关详细信息,请参阅Ansible Tower 用户指南中的 添加新清单

Dummy inventory

  1. 在清单中创建“localhost”主机,并使用变量

{'ansible_host': '127.0.0.1', 'ansible_connection': 'local'}

Inventory with localhost

  1. 使用pingsetup模块,针对 localhost 启动临时作业。虽然**机器凭据**字段是必需的,但对于此简单测试,选择哪个凭据无关紧要。

Launch inventory with localhost

您可以在作业详细信息视图中看到,容器已使用其中一个临时作业成功访问。

Inventory with localhost ping success

如果您有 OpenShift UI,则可以查看 Pod 在部署和终止时出现和消失。或者,您可以使用 CLI 对您的命名空间执行 get pod 操作,以实时观察这些事件的发生。

9.2.4. 查看容器组作业

运行与容器组关联的作业时,您可以在**详细信息**视图中查看该作业的详细信息,以及其关联的实例组和启动的执行节点。

IG - instances jobs

9.2.5. Kubernetes API 故障条件

运行容器组时,如果 Kubernetes API 响应资源配额已超过,控制器会使作业保持挂起状态。其他故障会导致**错误详细信息**字段的回溯显示故障原因,类似于此处的示例

_images/instance-group-cg-job-details-error.png

9.2.6. 容器容量限制

容器的容量限制和配额是通过 Kubernetes API 中的对象定义的

  • 要对给定命名空间内的所有 Pod 设置限制,请使用 LimitRange 对象。有关 配额和限制范围 的信息,请参阅 OpenShift 文档。

  • 要直接对 Tower 启动的 Pod 定义设置限制,请参阅 自定义 Pod 规范 并参阅 OpenShift 文档以将选项设置为 计算资源

注意

容器组不使用普通节点使用的容量算法。您需要在作业模板级别显式设置分叉数,例如。如果在 Tower 中配置了分叉,则该设置将传递到容器。