【问题标题】:Delegation a set of tasks to another host that relies on conditional将一组任务委托给另一个依赖条件的主机
【发布时间】: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_tasksdelegate_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'])。

标签: ansible ansible-inventory


【解决方案1】:

结合include 和包含我需要委派任务的节点的主机名的任意变量解决了这种情况(include_task 不支持任意变量)。 所以语法是:

    - name: Checking if node is kubernetes master
      stat:
        path: "{{kubeconf}}"
      register: master_conf

    - name: Including tasks to perform if we are on the master node
      include: set-of-tasks.yml
      when: master_conf.stat.exists

    - name: Including tasks to perform if we are on the slave node
      include: set-of-tasks.yml
      delegate_host: "{{item}}"
      with_items: "{{groups.k8s_master}}"
      when: master_conf.stat.exists == false

然后在 set-of-tasks.yml 中添加 delegate_to 到委派任务: delegate_to: "{{delegate_host}}"

由于某种原因,default(omit) 对我不起作用(Ansible 尝试解析原始节点主机名并失败,尽管它可以与指定 IP 的清单文件中的该名称一起正常工作)。所以我在 set-of-tasks.yml 的开头添加了类似的内容:

    - name: Setting target kubernetes master node
      set_fact:
        delegate_host: "{{ansible_hostname}}"
      when: delegate_host is undefined

【讨论】:

  • include 即将被弃用,您可能需要使用import_tasks
猜你喜欢
  • 1970-01-01
  • 2019-08-23
  • 2019-06-22
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
相关资源
最近更新 更多