【问题标题】:Reload Ansible's dynamic inventory重新加载 Ansible 的动态清单
【发布时间】:2015-05-14 05:37:30
【问题描述】:

我正在使用 Ansible 设置 EC2 实例并部署应用程序。有一个主机脚本收集标签相关的服务器和组信息。我想将这些动作作为一个单独的剧本来运行,所以

  1. 根据需要创建新实例
  2. 主机脚本加载清单(包括服务器的事实)
  3. 部署手册有效

但是,库存会提前加载,因此如果在游戏期间创建/更新服务器,则没有服务器/组数据。我可以 1) 单独提供和部署 playbook 2) 使用 add_host 技巧在服务器更新时模拟动态清单,但这些方法存在缺陷。

我可以强制 Ansible 重新加载库存吗?我的测试文件是: hosts脚本:

#!/bin/sh
echo `date` >> log.log
echo "{\"standalone\":[\"localhost\"]}"

示例playbook.yml:

---
- hosts: all
  tasks:
    - name: show inventory_hostname
      command: echo {{ inventory_hostname }}

我运行它ansible-playbook -i hosts playbook.yml -v 并看到 两个 运行:

$> cat log.log
Thu Mar 12 09:43:16 SAMT 2015
Thu Mar 12 09:43:16 SAMT 2015

但我还没有找到加倍它的命令。

【问题讨论】:

  • 您认为add_host 模块有什么缺点?
  • @Mxx 这是一个逻辑重复,不是吗?我不想考虑所有服务器都是全新的或部分更改的情况(我的分发模型包括多个服务器)。此外,hosts 脚本会生成一些本地事实,我是否也应该复制它?
  • 我同意弗拉基米尔@Mxx。在这里使用add_host 是重复的。我正在基于列表配置多个主机,但这打破了 ansible ec2 配置示例中常见的“注册:ec2”模式,因为结果是返回值列表。理想情况下,ansible 将允许我在同一个 playbook 中运行一个两阶段的配置过程:1)创建一堆实例,然后 2)按组寻址它们并进行一些基本配置(如设置 DNS 等)。
  • 可以确认:add_host 至少可以说是次优的。

标签: ansible ansible-inventory


【解决方案1】:

请注意,meta: refresh_inventory 在 Ansible Tower (AWX) 中不起作用。

https://docs.ansible.com/ansible-tower/3.3.1/html/userguide/best_practices.html

Playbook 不应使用 meta: refresh_inventory Ansible 功能,因为它与 Tower 处理库存的方式不兼容,如果 playbook 确实刷新了库存,它将刷新到作业开始时的库存开始。相反,请使用具有单独库存刷新步骤的工作流程。

我还没有足够的代表发表评论,否则我会的。

【讨论】:

    【解决方案2】:

    我遇到过类似的情况,meta 没有帮助,但 setup 有帮助。所以,这适用于所有可能觉得这很有用的人......为了提供一点上下文,我所做的是将 linux 内核内存限制为一定数量的实际内存,然后更新一些基于文件的文件新价值观。

    例如,ansible 任务类似于:

    - name: Print real memory
      debug:
        msg: {{ ansible_memory_mb.real.total }}
    
    - name: Reset GRUB_CMDLINE_LINUX
      lineinfile:
        path: /etc/default/grub
        regexp: '^{{ item.key }}='
        line: '{{ item.key }}="{{ item.value }}"'
      with_items:
        - { key: 'GRUB_CMDLINE_LINUX', 
            value: '{{ ansible_memory_mb.real.total - reserved }}m'}
    
    - name: Update GRUB
      command: update-grub
    
    - name: Reboot the node to load the system's real memory settings
      reboot:
    
    - name: Print real memory
      debug:
        msg: {{ ansible_memory_mb.real.total }}
    

    两个调试日志的输出相同,因为在更改 linux 内核配置后,ansible_memory_mb 变量没有重新加载。

    解决方案?重启系统后向setup添加任务。

    - name: Refresh ansible facts (ansible_memory_mb) after updating grub
      setup:
    

    【讨论】:

      【解决方案3】:

      您也可以编辑 ec2.ini 文件并设置选项:

      cache_max_age = 0

      首先确保没有缓存任何内容,从而避免重新加载。

      【讨论】:

        【解决方案4】:

        使用 Ansible 2.0+,您可以通过运行 task 来刷新您的库存:

        - meta: refresh_inventory
        

        【讨论】:

        • 这真的很有帮助。我最终将它作为post_task 添加到我的剧本中,然后继续其他剧本。超级好用。关于这方面的文档不多,但是如果您查看 github repo for ansible,您会在那里看到它。实现此目的的另一种方法是使用 --refresh-cache 运行您的 ec2.py 文件。
        • refresh_inventory 真的有效吗?我在我的剧本中使用它并且没有暂停表明它正在刷新库存,更重要的是,它没有发现自初始库存收集以来创建的 ec2 实例。我已经测试过手动给它更多时间暂停,以防它是实例仍在初始化的问题,但是......这似乎没有帮助。
        • 对于其他任何人,我想我找到了我的问题。 Meta:刷新库存不像使用 ./ec2.py --refresh-cache 强制刷新缓存。我发现我必须降低(或更具体地说,完全禁用)库存缓存。您可以通过在 ec2.ini 中设置 cache_max_age = 0 来做到这一点。
        • 这即 meta: refresh_inventory 不适用于 vCenter 清单。关于如何刷新 VMware 动态清单的任何想法?
        • 这似乎与aws_ec2 inventory source 配合得很好,不需要旧的ec2.py 动态库存方法显然确实需要额外的--refresh-cache
        【解决方案5】:

        我发现meta: refresh_inventory 不够用。
        我必须首先添加对ec2.py --refresh-cache 的显式调用。

        - 名称:刷新库存 主机:本地主机 连接:本地 收集事实:错误 任务: - 名称:刷新 EC2 缓存 命令:/etc/ansible/ec2.py --refresh-cache - 名称:刷新内存中的 EC2 缓存 元:refresh_inventory

        【讨论】:

        • 这对我有用 rax.py 使用inventory/rax.py --list --refresh-cache
        • 为了让ec2.py的位置更加灵活(例如使用多个库存时),可以使用{{inventory_dir}}/ec2.py --refresh-cache
        • 感谢您发布此信息,我们仍然看到与此解决方案不一致的结果,第一次执行确实获得了正确的库存并在 Ansible 中输出,但内存中的刷新似乎没有正确的主机,只有几次。我的同事@eric-oliver 刚刚在github.com/ansible/ansible/issues/71169 上打开了一个问题,因为我们在 refresh_inventory 代码中发现了一些源代码,上面写着`# FIXME: flush inventory cache`。因此,请关注该问题以获取更多信息。
        【解决方案6】:

        看看add_host

        它确实将一个主机(或者一个组)添加到 ansible-playbook 内存清单

        【讨论】:

        • 正如我所说 - add_host 是我不喜欢的选项(详情请参阅上面的 cmets)
        【解决方案7】:

        Ansible 当前不支持此功能。如果您查看ansibleansible-playbook 命令的源代码,您会看到先加载库存,然后将库存对象传递给运行指定任务或剧本的ansible 命令。出于多种原因,移动库存处理以使其在任务/剧本处理程序中发生可能是一项非常重要的工作。

        当你做这样的事情时,最好的办法是简单地将你的剧本分成两部分,并将它们的调用包装在一个你只需要调用一次的 shell 脚本中。

        【讨论】:

        • 当无法重新加载或删除库存时,应修改此注释以告知它早于 ansible 2.0 版。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        • 1970-01-01
        • 2019-01-04
        • 2017-07-15
        相关资源
        最近更新 更多