示例:使用 Salt 配置运行 Junos OS 的设备
瞻博网络支持使用 Salt 管理运行 Junos OS 的设备。此示例使用 Salt 配置多个运行 Junos OS 的设备。
要求
此示例使用以下硬件和软件组件:
三个运行 Junos OS 并启用 NETCONF 的 MX 系列路由器
盐师具有以下要求:
Salt 版本 3001 或更高版本
可以在运行 Junos OS 的设备上执行 ping 和执行操作
概述
此示例定义一个 Salt 状态,用于在运行 Junos OS 的目标设备上配置 BGP 对等会话。 表 1 概述了设备主机名、代理 ID 和特定于设备的文件。
主机 名 |
代理编号 |
代理配置文件 (/SRV/pillar) |
BGP 数据文件 (/srv/pillar/bgp) |
---|---|---|---|
R1 |
R1 |
R1-proxy.sls |
r1.sls |
R 2 |
R 2 |
R2-proxy.sls |
r2.sls |
R3 |
R3 |
R3-proxy.sls |
r3.sls |
该示例使用以下组件:
Jinja2 配置模板 — 使用命令格式将
set
BGP 配置定义为 Jinja 模板。模板使用 .set 文件扩展名来指示格式。支柱文件 - 定义 Jinja2 模板所需的特定于设备的配置数据。每个设备的数据都存储在 Salt 主服务器上 / srv/pillar/bgp 目录下的单独文件中。
支柱顶部文件 - 将每个支柱文件映射到相应的代理工作节点。
状态文件 - 定义要应用于目标设备的状态。在这种情况下,状态文件使用该函数将
junos.install_config
BGP 配置应用于设备。状态顶部文件 - 将状态文件映射到应应用状态的设备。
在此示例中,您将创建一个 Jinja2 模板来生成在设备上加载和提交的 BGP 配置。该模板在变量中替换特定于设备的配置数据,以便可以根据需要重复使用这些数据。模板文件放置在 Salt 主服务器上的 / srv/salt/configs 目录下。
然后,为每个设备创建单独的 pillar 文件,并在文件中定义特定于设备的配置数据。每个 pillar 文件定义一个 BGP_data
键,其中包含配置模板中引用的所有变量参数。pillar top 文件将每个 pillar 文件映射到其各自的代理工作节点。将数据存储在支柱中可确保每个代理工作节点只能访问该设备的数据。
junos_bgp_config.sls 状态文件定义一个状态,该状态使用该函数在junos.install_config
模板中应用 BGP 配置。调用时,该函数将锁定配置数据库,加载特定于目标设备的配置,提交配置,然后解锁数据库。该函数包括用于diffs_file
将配置差异存储在代理工作节点服务器上的文件中的参数。文件名使用粒度为id
输出文件生成特定于设备的文件名。
状态顶级文件将 junos_bgp_config
状态应用于具有任何值的支柱键的任何 BGP_data
工作节点。当您运行高状态或将该状态应用于设备时,Salt 使用模板和支柱数据生成特定于目标的配置,然后调用函数以 junos.install_config
在设备上加载并提交配置。如果已应用配置, junos.install_config
则函数不会重新应用配置。
配置设备后,可以应用junos_bgp_verify_peers
状态。此状态在每个get-bgp-neighbor-information
设备上执行 RPC,直到它为该设备的支柱数据中定义的每个对等方返回peer-state
Established
值或超时。此状态假定设备上正在运行 BGP。
配置
要使用 Salt 配置设备,请执行本节中包含的任务。
定义支柱数据
分步过程
要定义与 Jinja2 模板一起使用以生成 BGP 配置的支柱数据,请执行以下操作:
在 Salt 主服务器上,为每个受管设备创建一个名为 / srv/pillar/bgp/hostname.sls 的单独文件。
在 r1.sls 文件中定义主机 r1 的数据。
BGP_data: loopback: 192.168.0.1 local_asn: 64521 neighbors: - interface: ge-0/0/0 name: to-r2 asn: 64522 peer_ip: 198.51.100.2 local_ip: 198.51.100.1 peer_loopback: 192.168.0.2 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.6 local_ip: 198.51.100.5 peer_loopback: 192.168.0.3
在 r2.sls 文件中定义主机 r2 的数据。
BGP_data: loopback: 192.168.0.2 local_asn: 64522 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.1 local_ip: 198.51.100.2 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.10 local_ip: 198.51.100.9 peer_loopback: 192.168.0.3
在 r3.sls 文件中定义主机 r3 的数据。
BGP_data: loopback: 192.168.0.3 local_asn: 64523 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.5 local_ip: 198.51.100.6 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r2 asn: 64522 peer_ip: 198.51.100.9 local_ip: 198.51.100.10 peer_loopback: 192.168.0.2
在支柱顶部文件中,将支柱文件与相应设备 ID 下的 BGP 数据映射,以使设备能够访问数据。
saltuser@salt-master:~$ cat /srv/pillar/top.sls base: 'r1': - r1-proxy - bgp/r1 'r2': - r2-proxy - bgp/r2 'r3': - r3-proxy - bgp/r3
刷新支柱数据。
saltuser@salt-master:~$ sudo salt '*' saltutil.refresh_pillar r3: True r1: True r2: True
定义 Jinja2 模板
分步过程
要创建用于生成 BGP 配置的 Jinja2 模板,请执行以下操作:
在 Salt 主节点上创建一个名为 / srv/salt/configs/junos-config-bgp-template.set 的文件。
将 BGP 配置模板添加到文件并保存。
saltuser@salt-master:~$ cat /srv/salt/configs/junos-config-bgp-template.set {% if pillar.BGP_data %} set interfaces lo0 unit 0 family inet address {{ pillar.BGP_data.loopback }}/32 set policy-options policy-statement bgp-ecmp then load-balance per-packet set policy-options policy-statement bgp-in then accept set policy-options policy-statement bgp-out then next-hop self set policy-options policy-statement bgp-out then accept set protocols bgp group underlay type external set protocols bgp group underlay import bgp-in set protocols bgp group underlay export bgp-out set protocols bgp group underlay local-as {{ pillar.BGP_data.local_asn }} set protocols bgp group underlay multipath multiple-as set routing-options router-id {{ pillar.BGP_data.loopback }} set routing-options forwarding-table export bgp-ecmp {% for neighbor in pillar.BGP_data.neighbors %} set interfaces {{ neighbor.interface }} unit 0 description {{ neighbor.name }} set interfaces {{ neighbor.interface }} unit 0 family inet address {{ neighbor.local_ip }}/30 set protocols bgp group underlay neighbor {{ neighbor.peer_ip }} peer-as {{ neighbor.asn }} set protocols lldp interface {{ neighbor.interface }} {% endfor %} {% endif %}
定义状态
定义配置状态文件
要定义应用配置的状态文件,请执行以下操作:
在 Salt 主节点上创建一个名为 / srv/salt/junos_bgp_config.sls 的文件。
定义一个状态,该状态使用该函数在
junos.install_config
模板中应用 BGP 配置。saltuser@salt-master:~$ cat /srv/salt/junos_bgp_config.sls Apply BGP configuration: junos.install_config: - name: salt://configs/junos-config-bgp-template.set - comment: Configuring BGP using Salt - diffs_file: /var/log/salt/output/{{ grains['id'] }}_junos_bgp_config_diff - template_vars: True
注意:如果模板仅包含 Salt 内部变量(如支柱数据、粒度数据和函数),则可能需要定义
template_vars: True
该junos.install_config
函数才能呈现模板。在顶部文件中,定义应用 junos_bgp_config 状态的目标。目标包括定义了
BGP_data
支柱项目的所有设备。saltuser@salt-master:~$ cat /srv/salt/top.sls base: BGP_data:*: - match: pillar - junos_bgp_config
定义 BGP 验证状态文件
要定义验证 BPG 对等方是否具有 peer-state
的状态 Established
:
在 Salt 主节点上创建一个名为 / srv/salt/junos_bgp_verify_peers.sls 的文件。
定义一个状态,该状态使用该
junos.rpc
函数执行 RPC,get-bgp-neighbor-information
然后检查 RPC 回复中是否有peer-state
Established
。saltuser@salt-master:~$ cat /srv/salt/junos_bgp_verify_peers.sls {% for peer in pillar['BGP_data']['neighbors'] %} validate_bgp_session_state_with_{{ peer['peer_ip'] }}: loop.until: - name: junos.rpc - condition: m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' - period: 5 - timeout: 20 - m_args: - get-bgp-neighbor-information - m_kwargs: neighbor-address: {{ peer['peer_ip'] }} {% endfor %}
结果
执行高状态时,文件中的状态 top.sls
将应用于相应的目标设备。
saltuser@salt-master:~$ sudo salt '*' state.apply r1: ---------- ID: Apply BGP configuration Function: junos.install_config Name: salt://configs/junos-config-bgp-template.set Result: True Comment: Started: 07:07:14.449582 Duration: 3379.914 ms Changes: ---------- message: Successfully loaded and committed! out: True Summary for r1 ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 3.380 s r2: ---------- ID: Apply BGP configuration Function: junos.install_config Name: salt://configs/junos-config-bgp-template.set Result: True Comment: Started: 07:07:14.485640 Duration: 3132.677 ms Changes: ---------- message: Successfully loaded and committed! out: True Summary for r2 ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 3.133 s r3: ---------- ID: Apply BGP configuration Function: junos.install_config Name: salt://configs/junos-config-bgp-template.set Result: True Comment: Started: 07:07:14.388629 Duration: 3431.723 ms Changes: ---------- message: Successfully loaded and committed! out: True Summary for r3 ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 3.432 s
验证
验证 BGP 配置
目的
验证是否已为每个邻居地址建立 BGP 会话。
行动
将 junos_bgp_verify_peers
状态应用于目标设备并查看输出。
saltuser@salt-master:~$ sudo salt '*' state.apply junos_bgp_verify_peers r1: ---------- ID: validate_bgp_session_state_with_198.51.100.2 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:01.825414 Duration: 125.241 ms Changes: ---------- ID: validate_bgp_session_state_with_198.51.100.6 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:01.950786 Duration: 148.944 ms Changes: Summary for r1 ------------ Succeeded: 2 Failed: 0 ------------ Total states run: 2 Total run time: 274.185 ms r3: ---------- ID: validate_bgp_session_state_with_198.51.100.5 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:02.849612 Duration: 99.527 ms Changes: ---------- ID: validate_bgp_session_state_with_198.51.100.9 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:02.949265 Duration: 165.041 ms Changes: Summary for r3 ------------ Succeeded: 2 Failed: 0 ------------ Total states run: 2 Total run time: 264.568 ms r2: ---------- ID: validate_bgp_session_state_with_198.51.100.1 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:02.811094 Duration: 143.335 ms Changes: ---------- ID: validate_bgp_session_state_with_198.51.100.10 Function: loop.until Name: junos.rpc Result: True Comment: Condition m_ret['rpc_reply']['bgp-information']['bgp-peer']['peer-state'] == 'Established' was met Started: 07:17:02.954551 Duration: 170.651 ms Changes: Summary for r2 ------------ Succeeded: 2 Failed: 0 ------------ Total states run: 2 Total run time: 313.986 ms
意义
状态文件要求每个对等方的 等于peer-state
Established
。输出指示每个设备上的所有对等方都满足此条件。或者,您可以使用该junos.cli
函数在设备上执行show bgp summary
命令并查看输出以验证是否已为每个邻居地址建立 BGP 会话。
故障 排除
排查配置加载错误
问题
Salt 主节点生成一个 ConfigLoadError
错误,指示由于语法错误,它无法在设备上加载配置。
message: Could not load configuration due to : "ConfigLoadError(severity: error, bad_element: interface1, message: error: syntax error)"
解决 方案
Salt 使用 Jinja2 模板和为该设备定义的支柱数据呈现 Junos OS 配置。当 Jinja2 模板生成无效配置时,Salt 会生成语法错误。若要更正此错误,请更新 Jinja2 模板以更正错误消息中的键标识 bad_element
的元素。