问题描述
在使用Ansible时,有一个需求是希望从一个主机的任务中生成一个变量,然后使用该变量对另一个主机执行操作。具体来说,用户想要创建一个Kubernetes集群 – 在控制平面节点上,他可以将加入命令保存到一个变量中,但是这个变量似乎只在源主机上有效 – 他无法找到一种方法从另一个主机访问该变量。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Ansible中,可以使用delegate_to
和delegate_facts
来实现这个需求。
以下是一个示例的Ansible Playbook:
- hosts: all
remote_user: ansible
become: false
tasks:
- name: read join line from controlPlane
shell: kubeadm token create --print-join-command
when: inventory_hostname in groups['workerNodes']
register: joinCmd
delegate_to: "{{ item }}"
delegate_facts: true
with_items: "{{ groups['controlPlane'] }}"
- name: join all worker nodes to cluster
command: "{{ joinCmd.results[0].stdout }}"
become: yes
when: inventory_hostname in groups['workerNodes']
在上面的示例中,我们定义了一个名为read join line from controlPlane
的任务,它在workerNodes
组中的所有主机上运行。该任务使用delegate_to
属性将任务委托给controlPlane
组中的一个主机,并使用delegate_facts
属性将事实传递回当前主机。这样,我们就可以在当前主机上访问joinCmd
变量。
然后,我们定义了一个名为join all worker nodes to cluster
的任务,它在workerNodes
组中的所有主机上运行。该任务使用joinCmd.results[0].stdout
来执行加入命令。
请注意,delegate_to
属性和delegate_facts
属性是Ansible中的高级特性,需要确保你的Ansible版本支持这些特性。
方案2
使用文件传输和本地执行的方法可能会增加一些复杂性,并且需要确保文件的安全性。
另一种方法是将加入命令保存到本地文件中,然后将文件复制到工作节点并在工作节点上执行。这种方法可能会增加一些复杂性,并且需要确保文件的安全性。
以下是一个示例的Ansible Playbook:
- hosts: controlPlane
remote_user: ansible
become: false
tasks:
- name: read join line from controlPlane
shell: kubeadm token create --print-join-command
register: joinCmd
- name: save join command to file
copy:
content: "{{ joinCmd.stdout }}"
dest: /tmp/join_command.txt
- hosts: workerNodes
remote_user: ansible
become: true
tasks:
- name: copy join command file
copy:
src: /tmp/join_command.txt
dest: /tmp/join_command.txt
- name: execute join command
command: "bash /tmp/join_command.txt"
在上面的示例中,我们首先在controlPlane
组中的主机上运行一个任务,将加入命令保存到一个变量中。然后,我们使用copy
模块将加入命令保存到一个本地文件中。
接下来,在workerNodes
组中的主机上运行另一个任务,将加入命令文件复制到工作节点,并在工作节点上执行加入命令。
请注意,这种方法需要确保文件的安全性,以防止未经授权的访问。
总结
在使用Ansible时,可以使用delegate_to
和delegate_facts
来实现从一个主机的任务中生成变量,并在另一个主机上执行操作。另一种方法是将加入命令保存到本地文件中,并在工作节点上执行文件。根据具体需求选择合适的方法。