Ansible Playbook修改inventory.ini主机默认网关IP(不覆盖interfaces全文件)
问题根因分析
- 原Shell命令失效的核心原因:
- Shell重定向优先级高于管道执行,执行
> /etc/network/interfaces时会第一时间清空目标文件内容,后续grep操作根本读不到原文件的有效配置 - 管道仅会输出匹配
default关键字的行,直接覆盖原文件会直接丢弃文件内其他网卡配置、静态路由等内容
- Shell重定向优先级高于管道执行,执行
- 原Playbook的设计缺陷:
- 无提权配置,普通用户权限无法修改系统级网络配置文件
- 无配置备份机制,修改错误无法快速回滚
- 无变更前校验,一旦配置写错直接重启网络服务会造成主机断连
- 硬拼复杂Shell管道的写法无幂等性,重复执行会产生不可预期的副作用
优化实现方案
纯Shell场景的正确修改方式
如果仅做单主机手动修改,直接用sed做原地精准替换即可,不需要管道中转:
# 匹配default gateway所在行,将网关IP最后一段替换为6,同时生成.bak备份文件 sed -i.bak '/default gateway/ s/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/\16/' /etc/network/interfaces
注意:执行完务必检查修改后的文件内容,确认仅网关行被改动,其他配置无变化后再重启网络服务
Ansible批量场景的最佳实践
完全替换硬拼的Shell管道,用Ansible原生模块实现带备份、带校验、带幂等的安全修改:
--- - name: 批量调整主机默认网关最后一段 hosts: all become: true tasks: - name: 连通性测试 ansible.builtin.ping: - name: 备份原网络配置文件 ansible.builtin.copy: src: /etc/network/interfaces dest: "/etc/network/interfaces.bak.{{ ansible_date_time.iso8601_basic_short }}" remote_src: true mode: "0644" - name: 精准替换网关行的IP最后一段 ansible.builtin.replace: path: /etc/network/interfaces regexp: '^(.*default gateway\s+\d{1,3}\.\d{1,3}\.\d{1,3})\.\d{1,3}(.*)$' replace: '\1.6\2' backup: true - name: 预校验网络配置语法 ansible.builtin.command: ifup --no-act eth0 register: config_precheck changed_when: false failed_when: config_precheck.rc != 0 - name: 校验通过后重启网络服务 ansible.builtin.service: name: networking state: restarted - name: 校验当前生效的默认网关 ansible.builtin.command: ip route show default register: route_result changed_when: false - name: 打印最终生效的网关配置 ansible.builtin.debug: var: route_result.stdout ...
方案优化点
- 全程使用Ansible原生模块操作,仅修改匹配到的网关行内容,不会影响文件内其他配置
- 改前自动生成带时间戳的备份,出错可直接回滚
- 增加配置预校验环节,只有配置语法正确才会重启网络服务,避免批量操作导致主机断连
- 所有操作具备幂等性,重复执行不会产生额外变更
- 执行完自动校验网关生效状态,不需要手动登录主机排查
通用避坑提示
- 严禁用
cat|grep|awk管道结果直接重定向回原文件,这是Shell操作的经典陷阱,要么走临时文件中转、要么用支持原地修改的文本编辑工具 - 批量修改网络配置前,必须先在1-2台测试主机上全流程验证,确认无断连风险后再推送全量主机
- 所有涉及系统路径的操作必须加
become: true提权,避免权限不足导致修改失败 - 尽量避免在Playbook里硬拼长管道的Shell命令,优先选择功能明确的Ansible内置模块,减少不可预期的执行结果
内容的提问来源于stack exchange,提问作者Jinja_dude
相关产品推荐
相关产品推荐

