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

问题描述 投票:1回答:1

我目前正在设置一些Ansible角色来设置Kubernetes集群。到目前为止,我有一个角色来配置幂等EC2(1x主/ 2x工作者)和后续角色来设置这些主/工作节点与Docker / Kubernetes依赖。我正在使用AWS ec2.ini/.py dynamic-inventory来发现我的create_ec2角色提供的实例的IP。

尝试使用我从主节点检索的join命令将我的worker连接到集群时遇到了问题。我有两个单独的角色用于主人和工作人员配置。在master的任务中,我得到了join命令:

kubeadm token create --print-join-command

然后注册一个变量,然后我用它来设置主机事实:

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

我遇到的问题是当我在运行worker角色时尝试在我的工作节点上访问此事实。我试图访问这个事实:

"{{ 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
amazon-web-services ansible ansible-inventory ansible-role
1个回答
0
投票

因此,您自己排除故障的方法是使用debug:任务来显示整个事实缓存并找到自己的关系:

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

然而,话虽如此,我很确定tag_Type_master被定义为一个组,因此不会出现在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中,以弥合两组之间的事实差距,并使其看起来好像工人在整个时间里都有join_command事实


另外,虽然这不是你问的,如果你用"kubernetes.io/role/master": ""和/或"kubernetes.io/role": "master"标记这些实例,你可以通过已经拥有cloud-provider is expecting的标签而受益。我不知道在ec2.py会是什么样子,但我相信找到使用ansible-inventory -i ec2.py --list会很便宜

我用相应的kubernetes.io/role: worker标记工人,即使我很确定AWS云提供商不关心它,而是选择在现有节点上使用metadata.labels进行ELB注册等。

© www.soinside.com 2019 - 2024. All rights reserved.