【问题标题】:Ansible docker connection with identical container names on more than one hostAnsible docker 连接在多个主机上具有相同的容器名称
【发布时间】:2019-10-31 11:30:06
【问题描述】:

我正在尝试针对使用相同名称运行容器的多个主机运行 ansible playbook。有 3 台主机,每台主机都运行一个名为“web”的容器。我正在尝试使用 docker 连接。

我正在使用 hosts 文件的典型模式,该模式适用于在主机上运行 ansible 模块。

- name: Ping
  ping:

- name: Add web container to inventory
  add_host:
    name: web
    ansible_connection: docker
    ansible_docker_extra_args: "-H=tcp://{{ ansible_host }}:2375"
    ansible_user: root
  changed_when: false

- name: Remove old logging directory
  delegate_to: web
  file:
    state: absent
    path: /var/log/old_logs

它仅适用于hosts 文件中的第一个主机

PLAY [all]

TASK [Gathering Facts]
ok: [web1]
ok: [web2]
ok: [web3]


TASK [web-playbook : Ping]
ok: [web1]
ok: [web2]
ok: [web3]

TASK [web-playbook : Add sensor container to inventory] 
ok: [web1]

PLAY RECAP 
web1  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web3  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

我尝试将name 设置为web_{{ ansible_host }} 以使其在主机之间唯一,但随后它会尝试连接到web_web1。我一直在使用sudo docker exec web rm -rf /var/log/old_logs 运行命令,这当然可以,但我希望能够直接在 docker 容器中使用 ansible 模块。

【问题讨论】:

    标签: ansible


    【解决方案1】:

    你得到的结果绝对是意料之中的。引用add_host documentation

    此模块绕过播放主机循环,并且只对播放中的所有主机运行一次,如果您需要它进行迭代,请使用 with-loop 构造。

    add_host 不能依赖主机循环,需要自己创建循环。

    此外,您肯定需要为动态创建的主机使用不同的名称(即inventory_hostname),但由于所有 docker 容器都具有相同的名称,它们的 ansible_host 应该相同。

    假设您的所有 docker 主机都在组 dockerhosts 中,以下 playbook 应该可以完成这项工作。我目前无法自己进行测试,因此您可能需要进行一些调整。让我知道它是否对您有帮助,以及我是否需要编辑我的答案。

    请注意,尽管add_host 任务不会自然循环,但我在第一次播放时将主机保留在您的原始组中,以便正确收集事实并正确填充hostvars magic variable

    ---
    - name: Create dynamic inventory for docker containers
      hosts: dockerhosts
    
      tasks:
        - name: Add web container to inventory
          add_host:
            name: "web_{{ item }}"
            groups:
              - dockercontainers
            ansible_connection: docker
            ansible_host: web
            ansible_docker_extra_args: "-H=tcp://{{ hostvars[item].ansible_host }}:2375"
            ansible_user: root
          loop: "{{ groups['dockerhosts'] }}"
    
    - name: Play needed commands on containers
      hosts: dockercontainers
    
      tasks:
        - name: Remove old logging directory
          file:
            state: absent
            path: /var/log/old_logs
    

    【讨论】:

    • 谢谢,这看起来是个不错的方法。我包含的代码来自roles/<name_of_role>/tasks/docker_containers.yml,所以我认为我的结构错误。我应该把add_host 任务放在哪里? site.ymlmain.yml?
    • 对于这个问题,我可能会给你十几个不同的正确答案(插入位置、循环变量等)。您必须根据您的情况找出更有意义的方法,考虑维护等...如果您的角色只是处理容器中的操作,我会在我的静态组中的主要剧本中动态创建组docker 主机,然后在创建的组上扮演角色。
    • 谢谢,我将重新组织角色,以便在主机本身上运行的任务与应该在容器内运行的任务是分开的。
    猜你喜欢
    • 2023-04-07
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 2020-04-23
    相关资源
    最近更新 更多