使用lineinfile模块保存注册变量时缺失主机信息的问题排查
问题分析与解决方案
你的问题是Ansible playbook配置了3台主机,但lineinfile模块写入文件时只保留了2台的信息,主要有两个可能的原因及对应解决办法:
可能原因1:并发写入的竞争问题
Ansible默认并行执行任务(默认forks=5),当3台主机同时通过delegate_to: localhost向本地文件写入内容时,lineinfile的文件操作不是原子性的,多个进程同时修改同一个文件会导致部分写入操作丢失,最终只保留了前两台的内容。
可能原因2:第三台主机任务执行失败
比如128.6.6.18主机无法正常连接、kamctl online命令执行出错,导致ep变量没有正确获取到值,进而跳过了写入步骤。可以通过查看Ansible执行日志,确认第三台主机的任务是否全部成功执行。
推荐解决方案:先收集所有结果再一次性写入
避免并发写入问题的最可靠方式是先在所有远程主机上收集结果,再在本地主机汇总后一次性写入文件,修改后的playbook如下:
--- - name: 收集所有主机的端点数量 hosts: all become_user: root tasks: - name: 执行命令获取在线端点数 shell: kamctl online | wc -l register: ep - name: 将所有结果写入本地文件 hosts: localhost tasks: - name: 创建文件(如果不存在) file: path: /home/codemaster/count.txt state: touch force: yes - name: 写入所有主机的结果 copy: content: | {% for host in groups['webrtc'] %} {{ host }} {{ hostvars[host]['ep'].stdout }} {% endfor %} dest: /home/codemaster/count.txt
备选方案:调整lineinfile的执行方式(不推荐)
如果一定要使用lineinfile,可以通过设置串行执行来避免竞争,但这种方式效率较低:
- 在playbook开头添加
serial: 1,强制串行执行任务:
--- - name: Ansbile script to save command line output hosts: all become_user: root serial: 1 # 串行执行,一次只处理一台主机 tasks: # 后续任务保持不变
- 同时将创建文件的任务改为只执行一次:
- name: create a file file: path: /home/codemaster/count.txt state: touch force: yes delegate_to: localhost run_once: yes
内容的提问来源于stack exchange,提问作者Kishore Kumar
相关产品推荐
相关产品推荐

