Ansible问题:hostvars已定义却返回undefined,污点配置条件不生效
核心错误原因
你遇到的问题主要出在变量引用的上下文错误,以及可能的Play目标主机配置不当:
委托执行导致变量上下文混淆
任务通过delegate_to指定在controller节点执行,但你在when条件中使用hostvars['inventory_hostname']['storage'],这里的inventory_hostname指的是当前任务的目标主机——如果你的Play的hosts字段设置的是controllers,那inventory_hostname就是controller节点的主机名,而该节点并没有定义storage变量,自然条件永远不满足。变量引用逻辑错误
从任务名称和shell命令里的hostvars[host]['inventory_hostname']可以看出,你应该是想遍历worker节点列表(比如通过with_items),但when条件里却错误地引用了当前目标主机的变量,而非循环变量对应的worker节点的变量。
修正方案
步骤1:确保Play的目标主机正确
如果要处理worker节点,Play的hosts应该指向worker组(需要先在inventory中定义worker组):
# 修改后的inventory文件 [workers] worker01 ansible_host=172.20.15.78 ansible_ssh_user=service ansible_ssh_private_key_file=./variables/dev-cortex-stage/service.pri ansible_ssh_password= ansible_port=22 ansible_ssh_port=22 private_ip=172.20.15.78 worker=true ingress=false storage=true logging=true [controllers] # 填入你的controller节点信息
步骤2:修正任务的变量引用与条件
如果是遍历worker节点执行任务,修改Playbook如下:
- name: "Taint node '{{ hostvars[host]['inventory_hostname'] }}'" hosts: workers delegate_to: "{{ groups['controllers'][0] }}" become: true shell: "kubectl taint --overwrite=true nodes '{{ hostvars[host]['inventory_hostname'] }}' storage=true:NoSchedule" when: hostvars[host]['storage'] is defined and hostvars[host]['storage'] == 'true' with_items: "{{ groups['workers'] }}"
如果是针对单个worker节点执行(比如直接指定hosts为worker01),可以简化条件:
- name: "Taint node '{{ inventory_hostname }}'" hosts: worker01 delegate_to: "{{ groups['controllers'][0] }}" become: true shell: "kubectl taint --overwrite=true nodes '{{ inventory_hostname }}' storage=true:NoSchedule" when: storage is defined and storage == 'true'
补充说明
INI格式的inventory中,storage=true会被解析为字符串类型的"true",而非布尔值True。如果需要使用布尔值判断,可以改用YAML格式的inventory:
# YAML格式inventory示例 workers: hosts: worker01: ansible_host: 172.20.15.78 ansible_ssh_user: service ansible_ssh_private_key_file: ./variables/dev-cortex-stage/service.pri ansible_ssh_password: "" ansible_port: 22 private_ip: 172.20.15.78 worker: true ingress: false storage: true logging: true controllers: hosts: # 你的controller节点
此时条件可以直接写when: storage is defined and storage。
内容的提问来源于stack exchange,提问作者simone.benati

