将所有这一切整合在一起
以下用例是使用 Apstra Freeform 功能不同方法和技术的不同网络设计的示例。这些示例旨在帮助您更好地了解 Apstra 和 Freeform 的功能如何用于解决各种网络用例。
用例 1 - 伦敦地铁小版本 - CloudLabs 拓扑
此用例使用伦敦地下系统的小型版本作为映射,从任意交换机设计网络拓扑。这里的概念是使用 Jinja 模板和物业集创建一个非常简单的网络设计。此用例演示了如何使用简单的 Jinja 模板和属性集创建完整的网络设计。
此用例可作为使用瞻博网络 Apstra Cloudlabs 的动手实验提供。还有一个 GitHub 存储库,包括您可参考、贡献甚至叉子的 Jinja 文件和 JSON 财产集。
-
环境拓扑。
蓝图中的设计
显示通过拓扑编辑器/API 分配的标记和 IP 地址的所有系统链路。
-
最终状态呈现的配置。对于 Bond-Street 设备,此处是呈现配置的示例。
接口 阻止 策略选项 阻止 协议 阻止 interfaces { replace: xe-0/0/0 { unit 0 { interfaces { replace: xe-0/0/0 { unit 0 { description "facing_oxford-circus:xe-0/0/1"; family inet { address 192.168.0.2/31; } } } replace: xe-0/0/1 { unit 0 { description "facing_green-park:xe-0/0/1"; family inet { address 192.168.0.8/31; } } } replace: lo0 { unit 0 { family inet { address 10.0.0.2/32; }
protocols { lldp { port-id-subtype interface-name; port-description-type interface-description; neighbour-port-info-display port-id; interface all; } replace: rstp { bridge-priority 0; bpdu-block-on-edge; } bgp { group external-peers { type external; export send-direct; neighbor 192.168.0.3 { peer-as 22; export add-med-110; } neighbor 192.168.0.9 { peer-as 86; export add-med-177; } } } } routing-options { autonomous-system 47; }
protocols { lldp { port-id-subtype interface-name; port-description-type interface-description; neighbour-port-info-display port-id; interface all; } replace: rstp { bridge-priority 0; bpdu-block-on-edge; } bgp { group external-peers { type external; export send-direct; neighbor 192.168.0.3 { peer-as 22; export add-med-110; } neighbor 192.168.0.9 { peer-as 86; export add-med-177; } } } } routing-options { autonomous-system 47; }
-
Show Config 模板
Config 模板系统。jinja 说明 system { host-name {{hostname}}; }
这是主.jinja 配置模板。此模板是 system.jinja 模板,它使用设备上下文中的内置“主机名”变量将系统主机名称设置为此。 配置模板接口。jinja 说明 {% set this_router=hostname %} interfaces { {% for interface_name, iface in interfaces.iteritems() %} replace: {{ interface_name }} { unit 0 { description "{{iface['description']}}"; family inet { address {{iface['ipv4_address']}}/{{iface['ipv4_prefixlen']}}; } } } {% endfor %} replace: lo0 { unit 0 { family inet { address {{ property_sets.data[this_router]['loopback'] }}/32; } } } }
设置可变this_router=主机名
对于通过接口并插入 junos 的正确接口部分语法的环路,包括接口说明以及设备上下文中的家族 inet 地址和前缀长度。您可以通过拓扑编辑中的链接来填充这些值。
这会将此路由器环路地址的property_set数据插入回传部分。
Config 模板协议。jinja 说明 {% set this_router=hostname %} policy-options { policy-statement send-direct { term 1 { from protocol direct; then accept; } } {% for interface_name, iface in interfaces.iteritems() %} {% set link_med = iface.link_tags[0] %} {# this may create multiple identical policy-statements, but JunOS is smart enough to squash them. #} policy-statement add-med-{{ link_med }} { from { route-filter 0.0.0.0/0 longer; } then { metric add {{ link_med }}; } then { accept } } {% endfor %} } protocols { lldp { port-id-subtype interface-name; port-description-type interface-description; neighbour-port-info-display port-id; interface all; } replace: rstp { bridge-priority 0; bpdu-block-on-edge; } bgp { group external-peers { type external; export send-direct; {% for interface_name, iface in interfaces.iteritems() %} neighbor {{ iface.neighbor_interface.ipv4_address }} { {% set peer_hostname=iface.neighbor_interface.system_hostname %} peer-as {{ property_sets.data[peer_hostname]['asn'] }}; export add-med-{{ iface.link_tags[0] }}; } {% endfor %} } } } routing-options { autonomous-system {{ property_sets.data[this_router]['asn'] }}; }
从设备上下文中设置可变this_router = 主机名。
设置策略选项部分,发送所有直接连接的路由。
走接口树。
通过拓扑将变量link_med设置到接口上的标记集。
设置 LLDP 参数
设置 RSTP 参数
创建 bgp 部分
组外部对等方
外部类型 (ebgp)
直接发送的出口策略
走接口树,为任何具有 ipv4 地址的邻接方插入邻接方。将peer_hostname变量设置为邻接接口主机名。
从property_sets数据“asn”中抓住对等方
Peer-as 部分设置为添加 med 标记的导出策略
使用属性集 asn 值中的自治系统设置路由选项部分。
-
属性集
属性集“数据” 说明 { "bond-street": { "asn": 47, "loopback": "10.0.0.2" }, "green-park": { "asn": 86, "loopback": "10.0.0.4" }, "tottenham-court-road": { "asn": 48, "loopback": "10.0.0.3" }, "leicester-square": { "asn": 137, "loopback": "10.0.0.5" }, "piccadilly-circus": { "asn": 23, "loopback": "10.0.0.1" }, "oxford-circus": { "asn": 22, "loopback": "10.0.0.0" } }
财产集简单明了,表示为包括以下内容的字典列表:
-
系统或站的名称是密钥,密钥内部有两个参数
-
Asn,这是 BGP 对等互联的自治系统编号
-
环路,这是与系统/站对等的环路地址。
-
用例 2 - 用于驱动第 2 天配置的标记和属性集
下面显示的小拓扑结构是在 Freeform 拓扑编辑中构建的。它有三个交换机和两个外部系统,名为 ESXi-1 和 ESXi-2。两个主机面向的链路分别标记为 esxBlueTrunk 和 esxRedTrunk。此用例的目标是展示如何使用 Freeform 功能动态构建面向 ESXi 主机的交换机中继,由属性集中的条目和拓扑中分配的标记决定。
此实例中的标记角色是指示应在何处配置中继 / 创建。
在此实例中,属性集的作用是保存配置中继成员、VLAN 和 IRB 所需的相关数据。
此示例说明了利用精心制作的配置模板 (Jinja2)、标记和属性集来构建配置的能力,而无需重新制作配置模板。由于将新标记分配给拓扑,或将新 VN 分配给属性集,相关配置将动态为这些中继构建。
最终状态配置
对于标记为 esxBlueTrunk 的接口,最终 Junos 配置将包括:
接口块 | IRB 块 | VLAN 块 |
---|---|---|
interfaces { ae2 { description esxBlueTrunk unit 0 { family ethernet-switching { interface-mode trunk vlan { members [ vn99 vn100 vn101 ] } } } } |
irb { unit 99 { family inet { mtu 9000; address 1.1.99.1/24; } } unit 100 { family inet { mtu 9000; address 1.1.100.1/24; } } unit 101 { family inet { mtu 9000; address 1.1.101.1/24; } } } } |
vlans { vn99 { vlan-id 99; description vMotionVN-99; l3-interface irb.99; } vn100 { vlan-id 100; description storageVN-100; l3-interface irb.100; } vn101 { vlan-id 101; description mgmtVN-101; l3-interface irb.101; } } |
esxTrunk 财产集
属性集包括构建 Junos 中继配置所需的必要详细信息
esxTrunk 属性集 | 说明 |
---|---|
![]() |
esxTrunk 财产集(左侧)是作为字典的字典构建的,有充分的理由:启用递归查找。esxBlueTrunk 字典已扩展为显示值 99、100、101,在此实例中既用作 VLAN ID,也用作下方字典的键。下方的字典提供键:子网的值对、网关和说明。在此示例中,子网并非必需,存在纯粹用于参考。 借助这种方式组织的数据,Config 模板设计为通过两个数据结构再次出现,以搜索匹配标记:
当两个数据集中的标记匹配时,Config 模板将生成所需的配置。通过交叉引用上面的 Junos 配置输出左侧的属性集,您可以看到:
esx(红色/粉红色)中继,都保存着与 esxBlueTrunk 类似的信息 为了实现在左侧的属性集和分配给拓扑链路的标记的高效递归步行,标记被专门分配为相同的值
|
Jinja2 base Config 模板状态机
下面介绍了 Config 模板 esxTrunks.jinja 流。
Jinja2 基地配置模板
配置模板 | 说明 |
---|---|
{% set Rendered_VNs = {} %} {% for ps_tag in property_sets.esxTrunk %} {% for interface_name, iface in interfaces.iteritems() %} {% if ((iface.link_tags) and (ps_tag in iface.link_tags)) %} interfaces { {{interface_name}} { description {{ ps_tag }} unit 0 { family ethernet-switching { interface-mode trunk vlan { members [ {% for vlan_id in property_sets.esxTrunk[ps_tag] %} {% set _ = Rendered_VNs.update({vlan_id: ps_tag}) %} vn{{ vlan_id }} {% endfor %} ] } } } } {% endif %} {% endfor %} {% endfor %} irb { {% for vn in Rendered_VNs %} {% set tag = Rendered_VNs[vn] %} unit {{ vn }} { family inet { mtu 9000; address {{ property_sets.esxTrunk[tag][vn]['gateway'] }}; } } {% endfor %} } } vlans { {% for vn in Rendered_VNs|unique %} {% set tag = Rendered_VNs[vn] %} vn{{ vn }} { vlan-id {{ vn }}; description {{ property_sets.esxTrunk[tag][vn]['description'] }}-{{ vn }}; l3-interface irb.{{ vn }}; } {% endfor %} } |
一本全局字典,用于存储 VN 以呈现 首先要遍历上面显示的 esxTrunk 属性集。检索并存储在变量ps_tag(属性集标记)中的第一个值是以下字符串之一:
现在通过拓扑中的接口遍历或“迭代” 如果存在接口link_tag且ps_tag在接口链路标记列表中,则会满足中继配置将呈现的情况 开始输出接口块。输出ps_tag等于接口链路标记的interface_name。可选分配说明,尽管 Freeform 已经从拓扑中分配了此说明 设置单元编号和关联配置以描述中继 设置中继成员 使用ps_tag遍历 esxTrunk 属性集检索 VLAN ID 输入字典中的每一个 VLAN ID,在第 1 行声明以后使用 输出 esxTrunk 属性集中详述的 vn VLAN ID 当 esxTrunk 属性集中不再有条目时,请结束环路 在上面的 if 语句结束语句 结束上述语句 结束上述语句 开始输出 IRB 块 遍历Rendered_VNs字典 为了实现可读性,将可变标记设置为字典中存储的标记 使用vlan_id设置单元号 使用标记、vn 和密钥“网关”设置存储在 esxTrunk PropertySet 中的网关地址,以访问存储的字符串 结束上述语句 凝视器输出 vlan 块 如上文的 iRB 块,请遍历Rendered_VNs字典 为了实现可读性,将可变标记设置为字典中存储的标记 设置 vn 编号 设置vlan_id ID 根据需要设置说明 设置第 3 层 IRB 编号 结束上述语句 |
基于下方的 Jinja2 Config 模板利用分配的标记和属性集来构建所需的配置。
用例 3 - 使用 CRB 的高级示例 - CloudLabs 拓扑
此最终用例是 Apstra Engineering 编写的完整 CRB 示例。此示例完全采用静态 Jinja 模板构建,所有数据均在网络/设备的属性集中。这允许此 CRB 示例的用户仅通过编辑属性集来操作/扩展/更改网络,并且允许您不接触底层的 Jinja 模板。此用例的目的是为您提供一个可能的艺术示例,并展示 Freeform 功能的灵活性和力量。所有配置模板、属性集以及 jinja 模板和功能都嵌入了文档,可帮助您了解使用和功能。
此用例作为使用瞻博网络 Apstra Cloudlabs 的完全部署动手沙盒可供您使用。还有一个 GitHub 存储库,包含所有相同的文件。您可以将这些用作如何执行某些功能以使自己的高级配置模板用于您的用例 https://www.juniper.net/us/en/forms/apstra-free-trial.html