Ansible 网络运维实战:网络测试、Bond查看、网络配置与主机名管理

前言

在运维工作中,网络配置和主机管理是最常见的任务。本文将介绍如何使用 Ansible 进行网络测试、Bond 网卡查看、网络配置和主机名配置等操作,提供实用的 Playbook 示例。

一、网络连通性测试

1.1 批量 Ping 测试

---
# ping_test.yml - 批量测试网络连通性
- name: 网络连通性测试
  hosts: all
  gather_facts: no
  tasks:
    - name: Ping 测试
      ping:
      register: ping_result

    - name: 显示 Ping 结果
      debug:
        msg: "{{ inventory_hostname }} - 连通性: OK"
      when: ping_result is succeeded

1.2 端口连通性测试

---
# port_test.yml - 测试指定端口连通性
- name: 端口连通性测试
  hosts: all
  gather_facts: no
  vars:
    test_ports:
      - { host: "192.168.1.1", port: 22, name: "SSH" }
      - { host: "192.168.1.1", port: 80, name: "HTTP" }
      - { host: "192.168.1.1", port: 443, name: "HTTPS" }
  tasks:
    - name: 测试端口连通性
      wait_for:
        host: "{{ item.host }}"
        port: "{{ item.port }}"
        timeout: 5
        state: started
      loop: "{{ test_ports }}"
      register: port_results
      ignore_errors: yes

    - name: 显示端口测试结果
      debug:
        msg: "{{ item.item.name }} ({{ item.item.host }}:{{ item.item.port }}) - {{ 'OK' if item is succeeded else 'FAILED' }}"
      loop: "{{ port_results.results }}"

1.3 网络延迟测试

---
# latency_test.yml - 测试网络延迟
- name: 网络延迟测试
  hosts: all
  tasks:
    - name: Ping 外网测试延迟
      shell: ping -c 4 8.8.8.8 | tail -1 | awk -F'/' '{print $5}'
      register: latency
      ignore_errors: yes

    - name: 显示延迟结果
      debug:
        msg: "{{ inventory_hostname }} 到 8.8.8.8 平均延迟: {{ latency.stdout }}ms"
      when: latency.rc == 0

二、Bond 网卡查看

2.1 查看 Bond 状态

---
# check_bond.yml - 查看 Bond 网卡状态
- name: 查看 Bond 网卡配置
  hosts: all
  tasks:
    - name: 获取 Bond 接口列表
      shell: ls /proc/net/bonding/ 2>/dev/null || echo "no_bond"
      register: bond_interfaces
      changed_when: false

    - name: 显示 Bond 状态
      shell: cat /proc/net/bonding/{{ item }}
      loop: "{{ bond_interfaces.stdout_lines }}"
      register: bond_status
      when: bond_interfaces.stdout != "no_bond"

    - name: 输出 Bond 详情
      debug:
        msg: "{{ item.stdout_lines }}"
      loop: "{{ bond_status.results }}"
      when: bond_status is defined and item.stdout is defined

2.2 Bond 健康检查

---
# bond_health.yml - Bond 网卡健康检查
- name: Bond 健康检查
  hosts: all
  tasks:
    - name: 检查 Bond 从属接口状态
      shell: |
        for bond in /proc/net/bonding/*; do
          echo "=== $(basename $bond) ==="
          grep -E "Slave Interface|MII Status" $bond
        done
      register: bond_health
      changed_when: false

    - name: 显示 Bond 健康状态
      debug:
        var: bond_health.stdout_lines

    - name: 检查是否有故障接口
      shell: grep -l "MII Status: down" /proc/net/bonding/* 2>/dev/null || true
      register: failed_bonds
      changed_when: false

    - name: 告警 - 发现故障接口
      debug:
        msg: "警告: {{ inventory_hostname }} 发现 Bond 故障接口!"
      when: failed_bonds.stdout != ""

2.3 Bond 配置信息收集

---
# bond_info.yml - 收集 Bond 配置信息
- name: 收集 Bond 配置信息
  hosts: all
  tasks:
    - name: 获取 Bond 模式
      shell: grep "Bonding Mode" /proc/net/bonding/* 2>/dev/null | head -5
      register: bond_mode
      ignore_errors: yes

    - name: 获取 Bond 从属接口
      shell: grep "Slave Interface" /proc/net/bonding/* 2>/dev/null
      register: bond_slaves
      ignore_errors: yes

    - name: 生成 Bond 报告
      set_fact:
        bond_report:
          hostname: "{{ inventory_hostname }}"
          mode: "{{ bond_mode.stdout_lines | default([]) }}"
          slaves: "{{ bond_slaves.stdout_lines | default([]) }}"

    - name: 显示 Bond 报告
      debug:
        var: bond_report

三、网络配置

3.1 配置静态 IP (RHEL/CentOS)

---
# static_ip_rhel.yml - 配置静态 IP (RHEL/CentOS)
- name: 配置静态 IP 地址
  hosts: target_servers
  vars:
    network_interface: eth0
    ip_address: 192.168.1.100
    netmask: 255.255.255.0
    gateway: 192.168.1.1
    dns_servers:
      - 8.8.8.8
      - 114.114.114.114
  tasks:
    - name: 配置网卡 (nmcli)
      nmcli:
        conn_name: "{{ network_interface }}"
        ifname: "{{ network_interface }}"
        type: ethernet
        ip4: "{{ ip_address }}/24"
        gw4: "{{ gateway }}"
        dns4: "{{ dns_servers }}"
        state: present
        autoconnect: yes
      notify: restart network

  handlers:
    - name: restart network
      service:
        name: NetworkManager
        state: restarted

3.2 配置静态 IP (Ubuntu/Debian - Netplan)

---
# static_ip_ubuntu.yml - 配置静态 IP (Ubuntu)
- name: 配置静态 IP (Netplan)
  hosts: ubuntu_servers
  vars:
    netplan_config:
      network:
        version: 2
        renderer: networkd
        ethernets:
          eth0:
            addresses:
              - 192.168.1.100/24
            gateway4: 192.168.1.1
            nameservers:
              addresses:
                - 8.8.8.8
                - 114.114.114.114
  tasks:
    - name: 备份原配置
      copy:
        src: /etc/netplan/00-installer-config.yaml
        dest: /etc/netplan/00-installer-config.yaml.bak
        remote_src: yes
      ignore_errors: yes

    - name: 写入 Netplan 配置
      copy:
        content: "{{ netplan_config | to_nice_yaml }}"
        dest: /etc/netplan/01-static-ip.yaml
        mode: '0600'

    - name: 应用 Netplan 配置
      command: netplan apply

3.3 配置 DNS

---
# dns_config.yml - 配置 DNS
- name: 配置 DNS 服务器
  hosts: all
  vars:
    dns_servers:
      - 8.8.8.8
      - 114.114.114.114
      - 223.5.5.5
  tasks:
    - name: 配置 resolv.conf
      template:
        src: resolv.conf.j2
        dest: /etc/resolv.conf
        mode: '0644'
      when: ansible_os_family == "RedHat"

    - name: 配置 systemd-resolved (Ubuntu)
      lineinfile:
        path: /etc/systemd/resolved.conf
        regexp: '^#?DNS='
        line: "DNS={{ dns_servers | join(' ') }}"
      when: ansible_os_family == "Debian"
      notify: restart resolved

  handlers:
    - name: restart resolved
      service:
        name: systemd-resolved
        state: restarted

3.4 配置路由

---
# route_config.yml - 配置静态路由
- name: 配置静态路由
  hosts: all
  vars:
    static_routes:
      - dest: 10.0.0.0/8
        gateway: 192.168.1.254
      - dest: 172.16.0.0/12
        gateway: 192.168.1.253
  tasks:
    - name: 添加静态路由
      command: ip route add {{ item.dest }} via {{ item.gateway }}
      loop: "{{ static_routes }}"
      ignore_errors: yes

    - name: 持久化路由 (RHEL/CentOS)
      lineinfile:
        path: /etc/sysconfig/network-scripts/route-eth0
        line: "{{ item.dest }} via {{ item.gateway }}"
        create: yes
      loop: "{{ static_routes }}"
      when: ansible_os_family == "RedHat"

四、主机名配置

4.1 设置主机名

---
# set_hostname.yml - 设置主机名
- name: 配置主机名
  hosts: all
  vars:
    new_hostname: "{{ inventory_hostname }}"
  tasks:
    - name: 设置主机名
      hostname:
        name: "{{ new_hostname }}"

    - name: 更新 /etc/hostname
      copy:
        content: "{{ new_hostname }}\n"
        dest: /etc/hostname

    - name: 更新 /etc/hosts
      lineinfile:
        path: /etc/hosts
        regexp: '^127\.0\.1\.1'
        line: "127.0.1.1    {{ new_hostname }}"
        state: present

4.2 批量设置主机名 (基于 Inventory)

---
# batch_hostname.yml - 批量设置主机名
- name: 批量配置主机名
  hosts: all
  tasks:
    - name: 设置主机名为 inventory 名称
      hostname:
        name: "{{ inventory_hostname_short }}"

    - name: 配置 /etc/hosts 本地解析
      blockinfile:
        path: /etc/hosts
        block: |
          {{ ansible_default_ipv4.address }}  {{ inventory_hostname }} {{ inventory_hostname_short }}
        marker: "# {mark} ANSIBLE MANAGED - HOSTNAME"

4.3 主机名与 IP 映射

---
# hosts_mapping.yml - 配置主机名与 IP 映射
- name: 配置集群主机名解析
  hosts: all
  vars:
    cluster_hosts:
      - { ip: "192.168.1.101", hostname: "node01", alias: "master" }
      - { ip: "192.168.1.102", hostname: "node02", alias: "worker1" }
      - { ip: "192.168.1.103", hostname: "node03", alias: "worker2" }
  tasks:
    - name: 添加集群主机解析
      lineinfile:
        path: /etc/hosts
        regexp: ".*{{ item.hostname }}$"
        line: "{{ item.ip }}    {{ item.hostname }} {{ item.alias }}"
        state: present
      loop: "{{ cluster_hosts }}"

五、综合示例:网络巡检 Playbook

---
# network_audit.yml - 网络配置巡检
- name: 网络配置巡检
  hosts: all
  tasks:
    - name: 收集网络信息
      setup:
        gather_subset:
          - network

    - name: 显示 IP 地址
      debug:
        msg: "{{ inventory_hostname }}: {{ ansible_default_ipv4.address | default('N/A') }}"

    - name: 显示网关
      debug:
        msg: "网关: {{ ansible_default_ipv4.gateway | default('N/A') }}"

    - name: 显示 DNS
      shell: cat /etc/resolv.conf | grep nameserver | head -3
      register: dns_info
      changed_when: false

    - name: 显示主机名
      debug:
        msg: "主机名: {{ ansible_hostname }} (FQDN: {{ ansible_fqdn }})"

    - name: 检查 Bond 状态
      shell: ls /proc/net/bonding/ 2>/dev/null | wc -l
      register: bond_count
      changed_when: false

    - name: 显示 Bond 数量
      debug:
        msg: "Bond 接口数量: {{ bond_count.stdout }}"

    - name: 生成网络报告
      set_fact:
        network_report:
          hostname: "{{ ansible_hostname }}"
          ip: "{{ ansible_default_ipv4.address | default('N/A') }}"
          gateway: "{{ ansible_default_ipv4.gateway | default('N/A') }}"
          interface: "{{ ansible_default_ipv4.interface | default('N/A') }}"
          mac: "{{ ansible_default_ipv4.macaddress | default('N/A') }}"
          bond_count: "{{ bond_count.stdout }}"

    - name: 输出完整报告
      debug:
        var: network_report

六、Inventory 示例

# inventory/hosts
[webservers]
web01 ansible_host=192.168.1.101
web02 ansible_host=192.168.1.102

[dbservers]
db01 ansible_host=192.168.1.201
db02 ansible_host=192.168.1.202

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa

总结

本文介绍了使用 Ansible 进行网络运维的常见场景:

  • 网络测试:Ping 测试、端口测试、延迟测试
  • Bond 查看:状态检查、健康监控、配置收集
  • 网络配置:静态 IP、DNS、路由配置
  • 主机名配置:单机设置、批量配置、hosts 映射

这些 Playbook 可以根据实际环境进行调整,建议在测试环境验证后再应用到生产环境。

发表回复

后才能评论