RH358课程在每章的最后一个章节内容都是讲解如何使用Ansible对本章所学进行自动化管理。所以需要你有Ansible的基础。若对Ansible感兴趣,可订阅金鱼哥写的Ansible专栏。本章节属于第二章第三节内容。
专栏地址:https://blog.csdn.net/qq_41765918/category_11532281.html
rhel-system-roles包中提供的rhel-system-roles.network角色可用于自动化网络组的配置。
记住,这个角色是由Ansible控制节点上的/usr/share/ansible/roles目录中的包安装的,默认情况下,该目录位于本地安装角色的Ansible搜索路径中。
使用组接口及其端口所需的配置来设置network_connections变量。
用组接口(主接口)的定义开始network_connections变量的定义。下面的示例为名为team0的组接口配置名为team0的连接,该接口使用DHCP配置其IP地址。默认情况下,它使用rounddrobin运行器。
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
roles:
- rhel-system-roles.network
name变量定义NetworkManager连接名称。
interface_name的值决定了所创建的网络接口设备的名称。
对于组接口,类型变量的值必须设置为team。
在角色定义中,调用rhel-system-roles.network角色
为每个端口接口添加额外的变量定义:
将name设置为端口接口的唯一连接名称。
interface_ name设置为指定端口接口的网络设备名称。
将master设置为组接口的接口名称。
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
- name: team0-enp7s0
state: up
type: ethernet
interface_name: enp7s0
master: team0
- name: team0-enp8s0
state: up
type: ethernet
interface_name: enp8s0
master: team0
roles:
- rhel-system-roles.network
在前面的示例中,enp7so和enp8s0是现有的以太网网络接口,它们被用作组网络接口的物理端口。如果两个端口都有运营商信号并访问DHCP服务器,组接口将启动并在其中一个端口启动时被分配一个IP地址。
通过设置一个包含一个或多个地址值列表的ip变量,可以选择为组接口分配静态网络地址。
下面以team0接口配置一个名为team0的连接为例,该连接静态分配的IPv4地址为172.25.250.30/24。端口接口的配置设置还没有包括在这个剧本中。
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
ip:
address:
- 172.25.250.30/24
有一种更好的方法可以使用这个网络角色来配置许多服务器。将每个主机的team0的静态IP地址分配给host_vars文件中的一个变量。
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
ip:
address:
- "{{ team0_static_ip }}"
- name: team0-enp7s0
state: up
type: ethernet
interface_name: enp7s0
master: team0
- name: team0-enp8s0
state: up
type: ethernet
interface_name: enp8s0
master: team0
roles:
- rhel-system-roles.network
当前rhel-system-roles .network角色的实现有一些限制。其中之一是,它不能用于设置组界面的运行器。然而,使用Ansible还有其他方法来实现这一点。
使用command命令模块直接运行nmcli来调整运行器,然后断开连接并重新连接以更新其设置。下面的示例添加了一个任务来完成此任务。它在报告更改时调用两个处理程序重新启动连接:
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
ip:
address:
- "{{ team0_static_ip }}"
- name: team0-enp7s0
state: up
type: ethernet
interface_name: enp7s0
master: team0
- name: team0-enp8s0
state: up
type: ethernet
interface_name: enp8s0
master: team0
roles:
- rhel-system-roles.network
tasks:
- name: Adjust team0 runner
command: /usr/bin/nmcli con mod team0 team.runner activebackup
notify: restart team0
handlers:
- name: disconnect team0
command: /usr/bin/nmcli dev dis team0
listen: restart team0
- name: start team0
command: /usr/bin/nmcli con up team0
listen: restart team0
这个例子确实有一个问题。命令任务不是幂等的,即使team0的运行器已经设置为activebackup,它也将运行。即使不需要这样做,也会再次关闭和启动组接口,这可能会中断网络连接。
为了解决这个问题,添加一些任务来帮助根据组的状态有条件地运行那些其他任务:
- name: Configure team interface
hosts: servers
vars:
network_connections:
- name: team0
state: up
type: team
interface_name: team0
ip:
address:
- "{{ team0_static_ip }}"
- name: team0-enp7s0
state: up
type: ethernet
interface_name: enp7s0
master: team0
- name: team0-enp8s0
state: up
type: ethernet
interface_name: enp8s0
master: team0
tasks:
- name: Is team0 defined?
include_role:
name: rhel-system-roles.network
when: ansible_facts['team0'] is not defined
- name: Check team0 status
command: /usr/bin/teamdctl team0 state dump
register: team0_state
changed_when: false
- name: Import team0 status as JSON
set_fact:
team0_status: "{{ team0_state.stdout }}"
- name: Adjust team runner
command: /usr/bin/nmcli con mod team0 team.runner activebackup
notify: restart team0
when:
- team0_status['setup']['runner_name'] != "activebackup"
handlers:
- name: disconnect team0
command: /usr/bin/nmcli dev dis team0
listen: restart team0
- name: start team0
command: /usr/bin/nmcli con up team0
listen: restart team0
rhel-system-roles.network角色现在使用include_role作为任务调用,这样它就可以有一个条件,只在team0接口不存在的情况下运行。
当team0存在时,teamdctl team0 state dump的结果将保存到已注册的变量中。此任务总是报告changed更改,但由于它在托管主机上没有更改任何内容,因此将change when: false设置为ok。
set_fact模块确保teamdctl的标准输出,它是json格式化的,包含了接口的状态,可以像对待变量字典一样对待。
该输出用于确保组的runner仅在尚未设置为activebackup时才更改。
rhel-system-roles.network角色和命令模块可以使用nmcli来删除组接口。您需要删除组接口及其端口的NetworkManager连接,并断开team0接口以立即将其关闭。
在下面的例子中,当未定义team0 网络组时,Ansible条件将阻止任务运行。
- name: Remove team0 interface
hosts: servers
become: yes
vars:
network_connections:
- name: team0
persistent_state: absent
- name: team0-enp7s0
persistent_state: absent
- name: team0-enp8s0
persistent_state: absent
tasks:
- name: Deactivate team0
include_role:
name: rhel-system-roles.network
when: ansible_facts['team0'] is defined
- name: Disconnect team0
command: /usr/bin/nmcli dev dis team0
when: ansible_facts['team0'] is defined
[student@workstation ~]$ lab netlink-automation start
[student@workstation ~]$ cd ~/netlink-automation
[student@workstation netlink-automation]$ cat ansible.cfg
[defaults]
inventory=inventory
remote_user=devops
[privilege_escalation]
become=False
become_method=sudo
become_user=root
become_ask_pass=False
[student@workstation netlink-automation]$ cat inventory
[servers]
servera.lab.example.com
[student@workstation netlink-automation]$ ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.storage, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.storage, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.
[student@workstation netlink-automation]$ cat playbook.yml
---
- name: Configure team network device
hosts: servers
become: true
vars:
network_connections:
#Create a team profile
- name: team0
state: up
type: team
interface_name: team0
ip:
dhcp4: no
auto6: no
address:
- "192.168.0.100/24"
- name: team0-port1
state: up
type: ethernet
interface_name: eth1
master: team0
- name: team0-port2
state: up
type: ethernet
interface_name: eth2
master: team0
roles:
- rhel-system-roles.network
[student@workstation netlink-automation]$ ansible-playbook playbook.yml --syntax-check
playbook: playbook.yml
[student@workstation netlink-automation]$ ansible-playbook playbook.yml
[root@servera ~]# teamdctl team0 state
setup:
runner: roundrobin
ports:
eth1
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
eth2
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
[root@servera ~]# ping 192.168.0.254
[student@workstation netlink-automation]$ vim teamtest.yml
---
- name: Configure team network device
hosts: servers
become: true
tasks:
- name: Confirm team interface functions
command: ping -c1 -w2 192.168.0.254
[student@workstation netlink-automation]$ ansible-playbook teamtest.yml
[student@workstation netlink-automation]$ vim teamtune.yml
---
- name: Tune team network device
hosts: servers
become: true
tasks:
- name: Tune team runner to activebackup
command: nmcli con mod team0 team.runner activebackup
- name: Disconnect team interface
command: nmcli dev dis team0
- name: Reactivate team interface
command: nmcli con up team0
[student@workstation netlink-automation]$ ansible-playbook teamtune.yml
[root@servera ~]# teamdctl team0 state
setup:
runner: activebackup
ports:
eth1
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
eth2
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
runner:
active port: eth1
[root@servera ~]# ping -c2 192.168.0.254
[student@workstation ~]$ lab netlink-automation finish