AWS / Ansible-如何从动态清单中定义的主机跨角色/主机访问事实?

时间:2019-04-27 00:57:55

标签: amazon-web-services ansible ansible-inventory ansible-role

我目前正在设置许多Ansible角色来设置Kubernetes集群。到目前为止,我已经负责提供幂等的EC2(1个Master / 2x Worker)以及后续角色,以设置具有Docker / Kubernetes依赖性的这些master / worker节点。我正在使用AWS ec2.ini/.py dynamic-inventory来发现由我的create_ec2角色配置的实例的IP。

当尝试使用从主节点检索的join命令将我的工作人员加入集群时遇到问题。我有2个单独的角色,负责主服务器和辅助服务器的配置。在主服务器的任务中,我使用以下命令获得join命令:

kubeadm token create --print-join-command

然后注册一个变量,然后将其用于设置主机事实:

set_fact:
  join_command: "{{ join_command_stdout.stdout_lines[0] }}"

我遇到的问题是,当我运行工作角色时,尝试在工作节点上访问此事实。我正在尝试通过以下方式访问事实:

"{{ hostvars['tag_Type_master'].join_command }} --ignore-preflight-errors all  >> node_joined.txt"

但是由于我为hostvars提供的主机显然是未定义的,所以失败了。

作为参考,我将这个值保存在我的动态广告资源中(省略了IP):

  "tag_Type_master": [
    "1.2.3.4"

我收到的错误是:

"{"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['tag_Type_master']\" is undefined"

我正在努力弄清楚如何访问动态清单中定义的EC2实例的主机事实。

我尝试将EC2 IP直接添加到hostvars(hostvars['1.2.3.4'].join_command)中,但是该任务只是挂起,什么也不做。

我也尝试过将Magic变量(hostvars['inventory_hostname].join_command)无效。

似乎人们已经成功地从静态清单文件中定义的主机访问主机事实,但是由于EC2服务器的动态特性,将无法使用这种方法来创建群集。

run.yml:

  name: Setup K8s master node
  hosts: tag_Name_kube_master    
  gather_facts: true    
  roles:    
  - setup_kube_master


  name: Setup K8s worker nodes
  hosts: tag_Name_kube_worker
  gather_facts: true
  roles: 
  - setup_kube_worker

setup_kube_master / tasks / set_fact.yml:

  name: Get join command for workers    
  shell: kubeadm token create --print-join-command    
  register: join_command_stdout    
  name: Persist variable for workers    
  set_fact:    
   join_command: "{{ join_command_stdout.stdout_lines[0] }}"

setup_kube_worker / tasks / get_fact.yml:

  name: join cluster
  shell: "{{ hostvars['tag_Type_master'].join_command }} --ignore-preflight-errors all  >> node_joined.txt"    
  args:    
   chdir: $HOME    
   creates: node_joined.txt

1 个答案:

答案 0 :(得分:0)

因此,您自己解决此问题的方法是使用debug:任务来显示整个事实缓存并为您自己找到关系:

- name: show the state of affairs
  debug: var=hostvars verbosity=0

但是,话虽如此,我很确定tag_Type_master被定义为 group ,因此不会出现在hostvars中,因为-意味着-主机vars

不是vars

您必须执行一个间接级别来获得属于该组成员的主机:

- hosts: tag_Name_kube_worker
  tasks:
  - name: promote the "join_command" fact from the masters group
    set_fact:
      join_command: '{{ some_master.join_command }}'
    vars:
      some_master: '{{ hostvars[groups["tag_Type_master"][0]] }}'

为了简洁起见,我对some_master定义有了一些自由-在生产代码中,您实际上想检查该组是否存在并且其内容不为空等,等等,但是我大约80%的人相信它即使以书面形式也可以工作

您希望将其显示在run.ymlhosts: tag_Type_master之间的hosts: tag_Type_worker中,以弥合两组之间的事实差距,并使其看起来像是工人拥有{ {1}}一直以来的事实


另外,虽然这不是您要的,但是如果您要用join_command和/或"kubernetes.io/role/master": ""标记这些实例,则已经有了cloud-provider is expecting 。我不知道在"kubernetes.io/role": "master"中会是什么样,但是我敢肯定,使用ec2.py

会很便宜

即使我非常确定AWS云提供商并不关心它,我也用相应的ansible-inventory -i ec2.py --list标记了工作人员,而是选择只在现有节点上使用kubernetes.io/role: worker进行ELB注册等。