【发布时间】:2019-06-19 05:14:45
【问题描述】:
我的问题有点复杂。我有一些使用 Ansible 编排的多节点集群基础架构。
并且可以有 Kubernetes 主节点或从节点。如果当前任务在从节点上播放,我需要将一组特定的任务委托给主节点。
例如,我有这样的库存结构:
[k8s_master]
hostname ansible_ssh_host= ... etc.
[k8s_slaves]
hostname ansible_ssh_host= ... etc.
[k8s_cluster:children]
k8s_master
k8s_slaves
我有一个任务是检查 k8s 节点是主节点还是从节点并注册一些值:
- name: Checking if node is kubernetes master
stat:
path: "{{kubeconf}}"
register: master_conf
我想根据 master_conf.stat.exists 值(true 或 false)在本地执行一些任务(如果节点是 k8s 主节点)或将其委托给主节点(如果节点是 k8s 从节点)。问题:
- 我需要委派一组任务或动态包含
剧本,但 delegate_to 不适用于
block:或include_tasks:。 - 我需要根据具体情况委派这组任务 在条件语句上或在本地播放。
- 我需要传递节点 这组任务的主机名,即使它们将在远程播放 节点。例如,我可以这样设置:
set_fact:
node_hostname: "{{ansible_hostname}}"
然后我需要变量 {{node_hostname}} 在任务中,即使它们是
委托。然后我需要在播放过程中注册一些变量
主节点并再次在从节点的任务中使用。
仍然找不到正确的解决方案。我尝试过类似的方法:
- name: Including tasks to perform if we are on the master node
include_tasks: set-of-tasks.yml
when: master_conf.stat.exists
- name: Including tasks to perform if we are on the slave node
include_tasks: set-of-tasks.yml
delegate_to: "{{item}}"
delegate_facts: true
with_items: "{{groups.k8s_master}}"
when: master_conf.stat.exists == false
但这不起作用。
【问题讨论】:
-
当你运行循环
with_items: "{{groups.k8s_master}}"这些主机是主人。对?为什么需要测试它?when: master_conf.stat.exists == false. -
@VladimirBotka 在检查当前节点是否为从节点后,我需要在剧本中运行此循环。所以有两个选择,我最近在帖子中更新了示例。如果原始节点是主节点,则任务集必须在同一节点上播放,但如果它是从节点,则任务集被委派。但这无论如何都行不通,因为 Ansible 无法将
include_tasks与delegate_to结合起来:FAILED! => {"reason": "'delegate_to' is not a valid attribute for a TaskInclude\n -
Ansible 也不支持循环块(如我所见),因此我也不能将这组任务委托为块。
FAILED! => {"reason": "'with_items' is not a valid attribute for a Block\n -
为什么要测试您是否在主/从上,因为此信息可从您的库存中获得(例如
inventory_hostname in groups['k8s_master'])? ansible 支持include_tasks的循环,并且可以接受您可以在包含的文件中重用的任意变量,包括在必要时使用default(omit)过滤器的delegate_to子句。对于它的价值,在我看来,您只需要在针对正确主机组的不同游戏中分开您的任务。 -
您可以将您的游戏定位到具有相应pattern 的两个组的交集,例如
hosts: sandbox_nodes:&k8s_slaves。如果您仍然需要为特定任务执行此操作,您只需检查当前节点是否在我之前建议的相应组中(例如when: inventory_hostname in groups['k8s_slaves'])。