第282篇:数据中心网络自动化:Ansible 批量配置
关键词
Ansible、网络自动化、Playbook、Inventory、Module、批量配置、配置推送、配置备份、Network Automation
一、Ansible 网络自动化基础
1.1 为什么用 Ansible
传统 CLI 操作 vs Ansible 自动化:
┌─ 传统方式(单设备 CLI) └─ Ansible 方式(Playbook) --- - name: Config leaf switches hosts: leafs tasks: - name: Configure interface huawei_switch_interface: interface: 10GE1/0/1 mode: trunk vlan: 100
一次编写,50 台同时执行,可重复、可审计
1.2 Ansible 架构
Ansible 网络自动化架构:
| 控制节点(Control Node) ┌──────────────────────────────────┐ └──────────────────────────────────┘ ┌──────────────────────────────────┐ └──────────────────────────────────┘ ┌──────────────────────────────────┐ └──────────────────────────────────┘ ┌──────────────────────────────────┐ | Inventory(主机清单) [leafs] leaf01 ansible_host=10.1.1.1 leaf02 ansible_host=10.1.1.2 leaf03 ansible_host=10.1.1.3 Playbook(任务剧本) - name: Config VLAN hosts: leafs tasks: - huawei_vlan: ... Module/Plugin(模块/插件) huawei_switch_interface huawei_bgp huawei_vlan Connection(连接方式) network_cli (SSH) httpapi (RESTCONF) | |
|---|---|---|
| │ | ||
| SSH / RESTCONF / NETCONF | ||
| │ | ||
| ┌──────────┴───────────────────────────────┐ | ||
| │ 受管节点(Managed Nodes) │ | ||
| │ leaf01 leaf02 leaf03 ... leafN │ | ||
| └──────────────────────────────────────────┘ |
1.3 环境准备
安装 Ansible(Python 3.8+):
python -m pip install ansible
网络自动化常用集合(Collection):
# 华为设备
ansible-galaxy collection install community.network
# 通用网络模块
ansible-galaxy collection install ansible.netcommon
验证安装:
ansible --version
ansible-doc -l | grep huawei
二、Inventory 主机清单
2.1 静态 Inventory
Inventory 文件:inventory/hosts.ini
# 按角色分组
[leafs]
leaf01 ansible_host=192.168.1.11 ansible_user=admin
leaf02 ansible_host=192.168.1.12 ansible_user=admin
leaf03 ansible_host=192.168.1.13 ansible_user=admin
[spines]
spine01 ansible_host=192.168.1.21 ansible_user=admin
spine02 ansible_host=192.168.1.22 ansible_user=admin
[dc:children] # 子组
leafs
spines
[all:vars] # 全局变量
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=community.network.ce
ansible_password=Huawei@123
ansible_become=yes
ansible_become_method=enable
YAML 格式:inventory/hosts.yml
all:
children:
leafs:
hosts:
leaf01:
ansible_host: 192.168.1.11
leaf02:
ansible_host: 192.168.1.12
spines:
hosts:
spine01:
ansible_host: 192.168.1.21
vars:
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: community.network.ce
ansible_user: admin
2.2 变量定义
变量定义方式:
# 1. 组变量:inventory/group_vars/leafs.yml
---
vxlan_vni: 10001
bgp_as: 65001
loopback_ip: "{{ ansible_host }}"
ntp_server: 192.168.1.100
snmp_community: public
# 2. 主机变量:inventory/host_vars/leaf01.yml
---
interface_config:
- name: 10GE1/0/1
mode: trunk
vlan: 100-200
- name: 10GE1/0/2
mode: access
vlan: 10
# 3. 变量使用
vars:
vlan_id: 100
vlan_name: "VLAN_{{ vlan_id }}_DATA"
三、Playbook 实战
3.1 VLAN 批量配置
# playbooks/vlan_config.yml
---
- name: Bulk VLAN configuration on leaf switches
hosts: leafs
gather_facts: no
vars:
vlans:
- { id: 100, name: DATA_VLAN }
- { id: 200, name: VOICE_VLAN }
- { id: 300, name: MGMT_VLAN }
tasks:
- name: Create VLANs
community.network.ce_vlan:
vlan_id: "{{ item.id }}"
name: "{{ item.name }}"
state: present
loop: "{{ vlans }}"
- name: Verify VLANs
community.network.ce_command:
commands:
- display vlan summary
register: vlan_output
- name: Show VLAN summary
debug:
var: vlan_output.stdout_lines
运行 Playbook:
ansible-playbook playbooks/vlan_config.yml -i inventory/hosts.ini
3.2 接口批量配置
# playbooks/interface_config.yml
---
- name: Configure interfaces on leaf switches
hosts: leafs
gather_facts: no
tasks:
- name: Configure uplink trunks to spines
community.network.ce_interface:
interface: "{{ item.interface }}"
description: "{{ item.desc }}"
mode: trunk
pvid: 1
loop:
- { interface: 40GE1/0/1, desc: "To-Spine01-40GE1/0/1" }
- { interface: 40GE1/0/2, desc: "To-Spine02-40GE1/0/1" }
- { interface: 40GE1/0/3, desc: "To-Spine01-40GE1/0/2" }
- { interface: 40GE1/0/4, desc: "To-Spine02-40GE1/0/2" }
- name: Configure server-facing access ports
community.network.ce_interface:
interface: "{{ item.interface }}"
description: "Server-{{ item.server }}"
mode: access
default_vlan: "{{ item.vlan }}"
loop:
- { interface: 10GE1/0/1, server: "SVR01-eth0", vlan: 100 }
- { interface: 10GE1/0/2, server: "SVR02-eth0", vlan: 100 }
- { interface: 10GE1/0/3, server: "SVR03-eth0", vlan: 200 }
- name: Save configuration
community.network.ce_command:
commands:
- save
- Y
3.3 BGP EVPN 配置
# playbooks/bgp_evpn_config.yml
---
- name: Configure BGP EVPN on leaf switches
hosts: leafs
gather_facts: no
vars:
bgp_as: 65001
router_id: "{{ lookup('ansible.builtin.env', 'HOSTNAME') }}"
tasks:
- name: Enable EVPN
community.network.ce_evpn:
state: present
- name: Configure BGP
community.network.ce_bgp:
bgp_as: "{{ bgp_as }}"
router_id: 10.1.1.1
peer_group:
- { name: UNDERLAY, type: ebgp }
peers:
- { address: 10.0.12.1, remote_as: 65000, group: UNDERLAY }
- { address: 10.0.13.1, remote_as: 65000, group: UNDERLAY }
- name: Configure EVPN address family
community.network.ce_evpn_bgp:
bgp_as: "{{ bgp_as }}"
peer_group:
- { name: UNDERLAY, advertise_evpn: yes }
- name: Configure VXLAN
community.network.ce_vxlan:
vni: 10001
bridge_domain: 10
state: present
3.4 配置备份
# playbooks/backup_config.yml
---
- name: Backup configurations of all devices
hosts: dc
gather_facts: no
vars:
backup_dir: "./backups/{{ ansible_date_time.date }}"
tasks:
- name: Create backup directory
ansible.builtin.file:
path: "{{ backup_dir }}"
state: directory
delegate_to: localhost
run_once: yes
- name: Backup running config
community.network.ce_command:
commands:
- display current-configuration
register: config_output
- name: Save to file
ansible.builtin.copy:
content: "{{ config_output.stdout[0] }}"
dest: "{{ backup_dir }}/{{ inventory_hostname }}_running.cfg"
delegate_to: localhost
- name: Show backup status
ansible.builtin.debug:
msg: "{{ inventory_hostname }} backup saved to {{ backup_dir }}"
四、多厂商兼容
Ansible 多厂商支持:
华为 CloudEngine(CE 系列):
┌─ Collection: community.network
├─ Module: ce_*, huawei_*
├─ ansible_network_os: community.network.ce
└─ Connection: network_cli
思科 Nexus(NX-OS):
┌─ Collection: cisco.nxos
├─ Module: nxos_*
├─ ansible_network_os: cisco.nxos.nxos
└─ Connection: network_cli / httpapi
华三(Comware V7):
┌─ Collection: community.network
├─ Module: hp_comware_*
├─ ansible_network_os: community.network.hp_comware
└─ Connection: network_cli
Playbook 兼容两厂商示例:
---
- name: Config VLAN on multi-vendor
hosts: all
tasks:
- name: Create VLAN
community.network.ce_vlan:
vlan_id: 100
name: DATA
when: ansible_network_os == 'community.network.ce'
- name: Create VLAN on Cisco
cisco.nxos.nxos_vlan:
vlan_id: 100
name: DATA
when: ansible_network_os == 'cisco.nxos.nxos'
五、生产环境最佳实践
5.1 Playbook 结构规范
推荐的项目结构:
dc-automation/
├── ansible.cfg # 全局配置
├── inventory/
│ ├── hosts.ini # 主机清单
│ ├── group_vars/
│ │ ├── all.yml # 全局变量
│ │ ├── leafs.yml # Leaf 组变量
│ │ └── spines.yml # Spine 组变量
│ └── host_vars/
│ ├── leaf01.yml # 主机变量
│ └── leaf02.yml
├── playbooks/
│ ├── site.yml # 主入口
│ ├── vlan_config.yml
│ ├── bgp_evpn.yml
│ ├── backup.yml
│ └── rollback.yml # 回滚 Playbook
├── roles/
│ ├── common/ # 通用角色:NTP/SNMP/AAA
│ ├── vxlan/ # VXLAN 配置角色
│ ├── bgp/ # BGP 配置角色
│ └── monitoring/ # 监控配置角色
├── templates/ # Jinja2 模板
│ ├── interface.j2
│ └── bgp.j2
└── backups/ # 备份目录
5.2 安全注意事项
Ansible 生产安全实践:
1. 密码管理
┌─ 不在 Inventory 明文写密码
├─ 使用 ansible-vault 加密敏感变量
├─ 集成 HashiCorp Vault
└─ 使用 SSH Key 认证
ansible-vault encrypt inventory/group_vars/all.yml
ansible-playbook playbook.yml --ask-vault-pass
2. 变更控制
┌─ Playbook 存储在 Git
├─ 分支策略:feature → dev → staging → prod
├─ 变更需要 PR 审批
└─ 每次变更留审计日志
3. 先验证再执行
┌─ 使用 --check 模式做干运行
├─ 使用 --diff 显示变更内容
├─ 分批执行(serial: 1 逐台执行)
└─ 配置自动回滚
ansible-playbook playbook.yml --check --diff
ansible-playbook playbook.yml --serial 1 # 逐台执行
5.3 执行策略
执行策略配置:ansible.cfg
[defaults]
# 连接超时
timeout = 30
# SSH 参数
host_key_checking = False
# 并行数
forks = 20
# 日志
log_path = ./ansible.log
# 角色路径
roles_path = ./roles
[ssh_connection]
# SSH 参数优化
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
六、效果对比
| 维度 | 手工 CLI | Ansible 自动化 |
|---|---|---|
| 50 台加 VLAN | ~2 小时 | ~2 分钟 |
| 配置备份 | ~1 小时 | ~3 分钟 |
| BGP 全量配置 | ~8 小时 | ~10 分钟 |
| 人工错误率 | ~3-5% | ~0%(可重复执行) |
| 可审计性 | 需人工记录 | Git + 日志自动记录 |
| 学习成本 | 低 | 中(Playbook 语法) |
总结
| 关键点 | 说明 |
|---|---|
| Ansible 优势 | 无 Agent,纯 SSH,批量执行 |
| 核心组件 | Inventory + Playbook + Module |
| 网络模块 | community.network 覆盖华为/思科/华三 |
| 安全实践 | ansible-vault 加密,--check 预检,Git 版本控制 |
| 典型任务 | 加 VLAN、配置接口、BGP EVPN、配置备份 |
| 生产建议 | 角色化 Playbook,分批执行,自动回滚 |
思考
- Ansible 相比手工 CLI 有哪些优势?效率提升多少?
- Inventory 的组变量和主机变量有什么区别?优先级如何?
- 如何一次性在 50 台交换机上批量创建 VLAN?
- ansible-vault 有什么作用?如何使用?
- --check 和 --diff 参数有什么用处?
- 如何让 Playbook 支持华为和思科两个厂商?
下篇预告:第283篇 - ZTP(零接触部署)在数据中心的实践,介绍如何实现交换机上电即用的零接触部署。