Docker_swarm 模块 - ansible 的 join_token 参数不起作用

Czi*_*pO2 7 module ansible docker swarm

这是我的 ansible 剧本,任务是从 docker_swarm 模块文档复制的,因此它应该可以工作:

  - name: Init a new swarm with default parameters
    docker_swarm:
      state: present
      advertise_addr: "{{ manager_ip }}:2377"
    register: rezult
    when: "ansible_default_ipv4.address == '{{ manager_ip }}'"


  - name: Add nodes
    docker_swarm:
      state: join
      advertise_addr: "{{ manager_ip }}"
      join_token: rezult.swarm_facts.JoinTokens.Worker
      remote_addrs: "{{ manager_ip }}:2377"
    when: "ansible_default_ipv4.address != '{{ manager_ip }}'"
Run Code Online (Sandbox Code Playgroud)

它使用“manager_ip”--extra-var初始化群管理器,但在“添加节点任务”中失败并出现以下错误:

fatal: [vm2]: FAILED! => {"changed": false, "msg": "Can not join the Swarm Cluster: 500 Server Error: Internal Server Error (\"invalid join token\")"}
Run Code Online (Sandbox Code Playgroud)

如果我在 join_token 之后将“'{{ }}'”放在“rezult.swarm_facts.JoinTokens.Worker”周围,我会得到以下结果:

fatal: [vm2]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'swarm_facts'\n\nThe error appears to be in '/home/ansible/docker-ansible/docker.yml': line 47, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: Add nodes\n    ^ here\n"}
Run Code Online (Sandbox Code Playgroud)

如果我为 rezult.swarm_facts.JoinTokens.Worker 添加调试消息,我会得到正确的令牌:

ok: [opensuse1] => {
    "msg": "SWMTKN-1-5p7brhxxz4gzu716t78tt5woj7h6aflq0kdwvzwlbbe7ct0ba7-e59bg0t79q67ogd61ydwxc5yq"
}
Run Code Online (Sandbox Code Playgroud)

如果我通过服务器上的 docker swarm join 命令手动使用该令牌,我希望与管理器合并,它可以工作。因此变量具有正确的值并且节点之间的连接有效。但我就是无法让 join_token 工作。我正在运行 ansible 2.8.5 和 python 2.7.5。

我知道我可以使用 shell 模块,但我不想这样做。

San*_*aXL 5

这样的事情对我有用:

---
- name: Init swarm on the first node
  community.general.docker_swarm:
    state: present
    advertise_addr: "{{ ansible_host }}"
  register: result
  when: inventory_hostname == groups['swarm_managers'][0]

- name: Get join-token for manager nodes
  set_fact:
    join_token_manager: "{{ hostvars[groups['swarm_managers'][0]].result.swarm_facts.JoinTokens.Manager }}"

- name: Get join-token for worker nodes
  set_fact:
    join_token_worker: "{{ hostvars[groups['swarm_managers'][0]].result.swarm_facts.JoinTokens.Worker }}"

- name: Join other managers
  community.general.docker_swarm:
    state: join
    join_token: "{{ join_token_manager }}"
    advertise_addr: "{{ ansible_host }}"
    remote_addrs: "{{ hostvars[groups['swarm_managers'][0]].ansible_host }}"
  when:
    - inventory_hostname in groups['swarm_managers']
    - inventory_hostname != groups['swarm_managers'][0]

- name: Join workers
  community.general.docker_swarm:
    state: join
    join_token: "{{ join_token_worker }}"
    advertise_addr: "{{ ansible_host }}"
    remote_addrs: "{{ hostvars[groups['swarm_managers'][0]].ansible_host }}"
  when:
    - inventory_hostname not in groups['swarm_managers']
Run Code Online (Sandbox Code Playgroud)

swarm_managers组中,有经理,此清单中的所有其他主机都是工作人员。

  • @LennartRolland 在初始化任务之后,唯一知道加入令牌的主机是“groups['swarm_managers'][0]”。我们希望使这些令牌可供库存中的所有主机使用。因此,在接下来的 2 个任务中,每个主机通过从 `groups['swarm_managers'][0]` - `hostvars[groups['swarm_managers'][0]]` 部分获取这些变量来设置 `join_token_xxx` 事实。我能想到的唯一可以在这里添加的“when”是“when: inventory_hostname in groups['swarm_managers']”用于“获取管理器节点的加入令牌”任务,反之亦然。对于工作节点的任务 (2认同)

ach*_*ion 0

我认为这里的问题来自rezult.swarm_facts.JoinTokens.Worker. 在调试信息中,它显示为"msg": "SWMTKN-1-5p7..."join_token:Ansible 配置中的选项期望它只是普通令牌,没有额外的包装器等"msg":