示例:使用 Salt 配置运行 Junos OS 的设备
瞻博网络支持使用 Salt 管理运行 Junos OS 的设备。此示例使用 Salt 配置多个运行 Junos OS 的设备。
要求
此示例使用以下硬件和软件组件:
三台运行 Junos OS 并启用 NETCONF 的 MX 系列路由器
盐师傅具有以下要求:
Salt 版本 3001 或更高版本
可以在运行 Junos OS 的设备上执行 ping 命令并执行作
概述
此示例定义一个 Salt 状态,用于在运行 Junos OS 的目标设备上配置 BGP 对等会话。 表 1 列出了设备主机名、代理 ID 和特定于设备的文件。
主机名 |
代理 ID |
代理配置文件 (/SRV/支柱) |
BGP 数据文件 (/SRV/支柱/BGP) |
|---|---|---|---|
R1 |
R1 |
r1-proxy.sls |
R1.sls |
R2 |
R2 |
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 目录下。
然后,您可以为每个设备创建单独的支柱文件,并在该文件中定义特定于设备的配置数据。每个支柱文件都定义了一个 BGP_data 键,其中包含配置模板中引用的所有变量参数。支柱顶部文件将每个支柱文件映射到其各自的代理工作节点。将数据存储在支柱中可确保每个代理工作节点只能访问该设备的数据。
junos_bgp_config.sls 状态文件定义一个状态,该状态使用该junos.install_config函数在模板中应用 BGP 配置。调用时,该函数将锁定配置数据库,加载特定于目标设备的配置,提交配置,然后解锁数据库。该函数包括diffs_file用于将配置差异存储在代理工作节点服务器上的文件中的参数。文件名使用id粒度为输出文件生成特定于设备的文件名。
状态顶部文件将状态 junos_bgp_config 应用于具有任何值的 BGP_data 支柱键的任何工作节点。当您运行 highstate 或将该状态应用于设备时,Salt 会使用模板和支柱数据生成特定于目标的配置,然后调用该 junos.install_config 函数以在设备上加载并提交配置。如果已应用配置,则 junos.install_config 该函数不会重新应用该配置。
配置设备后,应用状态 junos_bgp_verify_peers 。此状态在 get-bgp-neighbor-information 每个设备上执行 RPC,直到它返回 peer-state 该设备的支柱数据中定义的每个对等方的值 或 Established 超时。此状态假定设备上正在运行 BGP。
配置
要使用 Salt 配置设备,请执行本节中包含的任务。
定义支柱数据
分步过程
要定义用于生成 BGP 配置的 Jinja2 模板的支柱数据,请执行以下作:
在 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 Master 上创建名为 /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函数执行get-bgp-neighbor-informationRPC,然后检查 RPC 回复中的peer-stateEstablished。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 %}
结果
当您执行 highstate 时,文件中的 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 标识的元素。