Documentation

9. 执行环境

通过 Tower,您可以使用 ansible playbook 直接在集群成员或预置备的隔离节点上执行作业。在 Ansible Tower 3.6 中,您可以在每个 playbook 中根据需要执行容器组中的作业。如需更多信息,请参阅本节末尾的 容器组 部分。

9.1. 实例组

实例可以被分为一个或多个不同的实例组。实例组可以分配给下面列出的一个或多个资源。

  • 机构(Organization)

  • 清单(Inventory)

  • 作业模板(Job Template)

当与其中一个资源关联的作业执行时,它将被分配给与该资源关联的实例组。在执行过程中,会先检查与作业模板关联的实例组,然后检查与清单关联的实例组。类似地,先检查与清单关联的实例组,然后检查与机构关联的实例组。因此,三种资源的实例组分配形成一个层级结构:作业模板 > 清单 > 机构。

在处理实例组时需要考虑以下几个问题:

  • 您可以选择在这些组中定义其他的组和组实例。这些组应当带有前缀 instance_group_。实例不需要与其它 instance_group_ 组一起位于 tower 组中,但有一个实例**必须**存在于 tower 组中。从技术方面来说,tower 是像任何其他 instance_group_ 组一样的组,但它必须始终存在,如果某个特定组没有与特定资源关联,则作业执行始终会返回 tower 组。tower 实例组始终存在(无法删除或重命名)。

  • 请勿创建名为 instance_group_tower 的组。

  • 请勿将任何实例命名为与组名相同。

9.1.1. 使用 API 配置实例组

做为一个系统管理员,可以通过向 /api/v2/instance_groups 发送 POST 来创建示实例组。

创建后,就可以把实例与实例组进行关联:

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

添加到实例组中的实例将自动重新配置自身,以侦听组的工作队列。如需更多详情,请参阅以下部分 实例组策略

9.1.2. 实例组策略

您可以通过定义 policy,将 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 均设置最小分配。其中会为组分配更多实例的设置将生效。例如,policy_instance_percentage 为 50%,policy_instance_minimum 的设置为 2,如果您启动了 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 系统的工作容量。如果这些实例也被放入实例组中,则它们也会扩展该组的容量。如果某个实例正在执行工作,且它是多个组的成员,则它的容量就会从它所属的所有组中减少。取消置备实例将从实例分配到的集群中删除容量。如需更多详情,请参阅:ref:ag_cluster_deprovision

注解

不是所有实例都需要置备相同的容量。

9.1.6. 控制作业运行位置

如果任何作业模板、清单或机构都有与其关联的实例组,则从该作业模板运行的作业将无法满足默认行为的要求。这意味着,如果与这 3 个资源关联的实例组中的所有实例都容量用尽,则该作业将保持待处理状态,直到有可用容量为止。

决定哪个实例组提交该作业的优先顺序如下:

  1. 作业模板

  2. 清单

  3. 机构(通过项目)

如果实例组与作业模板关联,并且所有这些实例组都满负荷,则该作业将提交到清单上指定的实例组,然后提交到组织。在资源可用时,作业应当在这些组中按优先顺序执行。

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

例如,通过将 group_a 与作业模板关联并将 tower 组与其清单关联,您可以在 group_a 用尽容量时将 tower 组用作回退 (fallback)。

另外,可以不将实例组与一个资源关联,而是将另一个资源指定为回退。例如,不将实例组与作业模板关联,并把它回退到清单和/或机构的实例组。

这里提供了两个其他的经典用例:

  1. 将实例组与清单关联(忽略将作业模板分配给实例组)可确保针对一个特定清单运行的 playbook 只在与其关联的组上运行。这对于只有实例组中的实例才可以与受管节点直接连接的情况来说很有用。

  2. 管理员可为机构分配实例组。这样,管理员就可以有效地对整个基础架构进行分段,从而确保每个机构都具备运行作业的容量,而不会影响到其它机构运行作业的能力。

同样,管理员也可以根据需要为每个机构分配多个组,如以下情境中所示:

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

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

  • 然后,机构管理员可以自由地为他们想要的组分配清单或作业模板(或者只是允许它们从机构继承默认顺序)。

Instance Group example

以这种方式安排资源非常灵活。另外,您还可以创建只有一个实例的实例组,从而允许您将工作直接指向 Tower 集群中的特定主机。

9.1.7. 取消置备实例组

重新运行设置 (setup) 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>

从清单文件中的实例组删除实例的成员资格不能确保,在重新运行设置 (setup) playbook 时实例不会被添加回组中。要实现这一点,请通过 API 将不需要的实例删除,同时也从清单文件中将其删除。或者,您可以完全停止定义清单文件中的实例组。您还可以通过 Ansible Tower 用户界面来管理实例组拓扑。如需有关在 UI 中管理实例组的更多信息,请参阅 Ansible Tower User Guide 中的 Instance Groups

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

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

当把一个作业调度为在“隔离”实例上运行时:

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

  • 当元数据与隔离主机同步后,“controller”实例会在“隔离”实例上启动一个进程,该进程消耗了元数据并开始运行 ansible/ansible-playbook。当 playbook 运行时,作业工件(如 stdout 和作业事件)会在“隔离”实例上被写入磁盘。

  • 虽然作业在“隔离”实例上运行,但“controller”实例会定期从“隔离”实例中复制作业工件(stdout 和作业事件)。它会一直消耗元数据,直到作业在“隔离”实例上完成运行。

注解

如果 Controller 节点在隔离运行的中途下线,则会失败。如果 Tower 节点在 playbook 运行时重启或分发程序停止,则该节点上运行的作业会失败,并在分发程序上线时不会重启。

可以创建隔离组(节点),允许它们存在于 VPC 中,其安全规则只允许其控制器组中的实例访问它们;仅需要从“controller”实例到“隔离”实例的入口 SSH 流量。在置备隔离节点时,您的安装机器需要能够连接到隔离节点。如果无法直接访问隔离节点,但可以通过其他主机间接访问,您可以使用 SSH 配置中的 ProxyCommand 指定“跳过主机”,以指定跳过主机,然后运行安装程序。

Isolated nodes daisy chain example

Jump Host example

建议系统配置与隔离组如下所示:

  • 请勿创建名为 isolated_group_tower 的组。

  • 请勿将任何隔离实例放到 tower 组或者其它普通实例组中。

  • 将控制器变量定义为隔离组中所有实例上的组变量或主机变量。请勿允许同一组中的隔离实例具有这个变量的不同值——本例中的行为无法预测。

  • 请勿将隔离实例放在多个隔离的组中。

  • 请勿将实例放在普通组和隔离组中。

  • 可在 RHEL 7 及之后的版本上安装隔离实例。

  • 可在 Settings (settings) 菜单的 Jobs 选项卡中配置与隔离组关联的以下持续时间:

    • Isolated Status Check Interval:30 秒是为隔离实例上运行的作业在状态检查之间设置的休眠默认时间。

    • Isolated Launch Timeout:600 秒(10 分钟)在隔离实例上启动作业的默认超时时间。这包括将源控制文件 (playbook) 复制到隔离实例所需的时间。

    • Isolated Connection Timeout:10 秒是与隔离实例通信时的默认 Ansible SSH 连接超时。此值应显著大于预期的网络延迟。

在 Tower 用户界面的 Instance Groups 列表视图中会相应地标记隔离组。

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

9.2. 容器组

Ansible Tower 3.6 引入 Container Groups 的概念,可用于在 Tower 中执行作业,不管 Tower 作为单机安装、安装在虚拟环境中或安装在容器中均可。容器组作为虚拟环境中的资源池使用。您可以创建实例组来指向 OpenShift 或 Kubernetes 容器,这是按需置备为 Pod 的作业环境,Pod 仅在 playbook 运行期间存在。这称为瞬时执行模式,可确保每个运行的作业都有一个清洁的环境。

有些情况下,需要将执行环境设置为“始终开启(always-on)”,这通过创建实例来配置。

9.2.1. 创建容器组

ContainerGroup 就是一个 InstanceGroup,它具有一个可以连接到 OpenShift 或 Kubernetes 集群的关联凭证。要在 Kubernetes 或 OpenShift 上设置容器组,您必须首先有以下几项:

  • 一个可以在其中启动的命名空间(有一个 “default” 命名空间,但多数情况下会因客户而异)

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

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

  • 与集群关联的 CA 证书

要创建容器组:

  1. 使用 Tower 用户界面创建与容器组一起使用的 OpenShift 或 Kubernetes API 持有者令牌凭证,详情请参阅 Ansible Tower User Guide 中的 添加新凭证

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

  1. 点击 add 按钮并选择 Create Container Group

IG - create new CG

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

9.2.2. 自定义 Pod 规格

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

要自定义 Pod 规格,使用切换功能启用并扩展 Pod Spec Override 字段,在 Pod Spec Override 字段中指定命名空间,完成后点击 Save

IG - CG customize pod

如果需要,您可以提供额外的定制功能。请点击 Expand 查看整个定制窗口。

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

成功创建容器组后,新创建的容器组的 Details 选项卡将保留,它可用于审核和编辑容器组信息。如果从 Instance Group 链接点击 Edit (edit-button) 按钮,也打开此菜单。您也可以编辑 Instances 并查看与该实例组关联的 Jobs

IG - example CG successfully created

对容器组和实例组进行相应的标记。

注解

尽管客户有自定义的 Pod 规格,如果默认 pod_spec 更改,则升级可能会较为困难。大多数清单都可应用于任何命名空间,命名空间单独指定,很可能您只需要覆盖命名空间。类似地,将不同版本 Tower 的默认镜像固定到默认作业运行程序容器的不同版本较为复杂。如果默认镜像在 Pod 规格中指定,则升级不会选择针对默认 Pod 规格所做的新默认更改。

9.2.3. 验证容器组功能

验证容器的部署和终止:

  1. 通过在 Instance Group 字段中填充容器组的名称来创建 mock 清单,并将容器组与其关联。如需详情,请参阅 Ansible Tower User Guide 中的 添加新清单

Dummy inventory

  1. 使用变量在清单中创建“本地主机”主机:

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

Inventory with localhost

  1. 使用 ping 或者 setup 模块对本地主机启动一个临时作业。尽管需要 Machine Credential,为此简单测试选择哪个选项无关紧要。

Launch inventory with localhost

您可在作业详情视图中看到,已成功使用一个临时作业访问了该容器。

Inventory with localhost ping success

如果您有 OpenShift 或 Kubernetes UI,您可以看到在部署和终止 Pod 时它会出现和消失。另外,您可以使用 CLI 在命名空间上执行 get pod 操作,以观察实时发生的这些相同事件。

9.2.4. 查看容器组作业

当您运行与容器组关联的作业时,您可以在 Details 视图中看到该作业的详情,以及关联的实例组和执行节点。

IG - instances jobs

9.2.5. Kubernetes 故障状况

在运行容器组和 Kubernetes 时,如果出现超出资源配额的问题,则 Tower 会将作业保持为待处理状态。如果出现其他问题,Error Details 字段中的追溯信息会显示故障原因,类似于以下示例:

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

9.2.6. 容器容量限制

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

注解

容器组不使用常规节点所使用的容量算法。您需要在作业模板一级为实例明确设置 fork 的数量。如果在 Tower 中配置了 fork,则该设置会随同传递给容器。