Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

 
 

将一切整合在一起

介绍

以下用例是利用我们讨论过的 Apstra Freeform 功能的不同方法和技术的不同网络设计示例。这些示例旨在帮助您更好地了解如何使用 Apstra 和 Freeform 的功能来解决各种网络用例。

用例 1:小型版 London Tube(CloudLabs 拓扑)

此用例使用伦敦地铁系统的小型版本作为地图,从任意交换机设计网络拓扑。这里的概念是使用 Jinja 模板和属性集创建简单的网络设计。此用例演示了如何使用简单的 Jinja 模板和属性集创建完整的网络设计。

此用例可作为使用 Juniper Apstra Cloudlabs 的动手实验室提供(有关 CloudLabs 的更多信息,请参阅本文末尾的相关链接部分)。GitHub 存储库包含可以引用、贡献甚至分支的 Jinja 文件和 JSON 属性集。

下图显示了此用例的环境拓扑。

在下图中,请注意,所有系统链路都显示通过拓扑编辑器/API 分配的标记和 IP 地址:

用例 1 的渲染配置

以下示例呈现了拓扑中设备的配置 Bond-Street

接口代码块:

策略选项代码块:

协议代码块:

配置模板

以下是用例 1 的配置模板示例。

配置模板 system.jinja.

main.jinja这是配置模板。此模板是system.jinja使用设备上下文中的内置“主机名”变量来设置系统主机名的模板。

配置模板 interfaces.jinja.

请注意以下几点:

  • {% set this_router=hostname %}:设置变量 this_router=hostname

  • {% for interface_name, iface in interfaces.iteritems() %}:一个 for 循环,用于遍历接口并为 Junos 插入正确的接口节语法。这包括接口的描述以及设备上下文中的家族 inet 地址和前缀长度。可以通过拓扑编辑器中的“链接”视图填充这些值。

  • replace: lo0 { unit 0 { family inet { address {{ property_sets.data[this_router]['loopback'] }}/32; } }:此代码将此 property_set 路由器环路地址的数据插入到环路节中。

配置模板 protocols.jinja.

请注意以下几点:

  • {% set this_router=hostname %}:从设备上下文设置变量 this_router = hostname

  • policy-statement send-direct { term 1 { from protocol direct; then accept; }:设置 policy-options 要发送到所有直连路由的节。

  • {% set link_med = iface.link_tags[0] %}:将变量 link_med 设置为通过拓扑与接口关联的标记。

  • protocols的部分设置lldp链路层发现协议 (LLDP) 参数。

  • protocols的部分设置rstp快速生成树协议 (RSTP) 参数。

  • group external-peers { 在 下 bgp: 组 external-peers

  • type external;:设置外部策略的类型 (eBGP)。

  • export send-direct;:的 send-direct出口政策。

  • {% for interface_name, iface in interfaces.iteritems() %}:遍历接口树并为具有 IPv4 地址的任何邻接方插入邻接方。

  • neighbor {{ iface.neighbor_interface.ipv4_address }}:将 peer_hostname 变量设置为邻居接口主机名。

  • {% set peer_hostname=iface.neighbor_interface.system_hostname %} :从数据“asn”中 property_sets 抓取对等方。

  • peer-as {{ property_sets.data[peer_hostname]['asn'] }}; export add-med-{{ iface.link_tags[0] }};Peer-as 节设置了标签的 add-med- 导出策略。

  • routing-options { autonomous-system {{ property_sets.data[this_router]['asn'] }};}routing-options:根据属性集的“asn”值设置自治系统的节。

呈现的属性集

这个简单的属性集表示为包含以下内容的字典列表:

  • 系统的名称(地铁站)是关键。例如, "bond-street".

  • ASN,即自治系统编号 BGP 对等互连。例如, "asn": 47.

  • 环路,这是系统的环路地址,与对等的工作站。例如, "loopback": "10.0.0.2".

用例 2:用于驱动第 2 天配置的标记和属性集

介绍

下面显示的小拓扑是在自由格式拓扑编辑器中构造的。它有三个交换机和两个外部系统,分别命名为ESXi-1和ESXi-2。面向两台主机的链路分别用 和 esxRedTrunk进行esxBlueTrunk标记。此用例演示了如何使用 Freeform 动态构建面向 ESXi 主机的交换机中继,该中继由属性集中的条目和拓扑中分配的标记决定。

标签在此实例中的作用是指示应在何处配置/创建中继。在这种情况下,属性集的作用是保存配置中继成员、VLAN 和 IRB 所需的相关数据。

此用例说明了利用精心制作的配置模板 (Jinja2)、标记和属性集来构建配置的好处,而无需重新制作配置模板。当新标签分配给拓扑或新 VN 分配给属性集时,系统会为这些中继动态构建关联的配置。

最终状态配置

对于标记为 的 esxBlueTrunk接口,最终的 Junos 配置将包括:

接口块

IRB 区块

VLAN 块

esx 属性集

以下属性集包含构建 Junos 中继配置所需的必要详细信息:

表 1:esxTrunk 属性集

esx中继属性集

描述

      "esxRedtrunk": {
        "200": {
          "subnet": "1.1.200.0/24",
          "description": "going nowhere",
          "gateway": "1.1.200.1/24"
        },
        "201": {
          "subnet": "1.1.201.0/24",
          "description": "going somewhere",
          "gateway": "1.1.201.1/24"
        }
      },
      "esxBlueTrunk": {
        "99": {
          "subnet": "1.1.99.0/24",
          "description": "vMotionVN",
          "gateway": "1.1.99.1/24"
        },
        "100": {
          "subnet": "1.1.100.0/24",
          "description": "storageVN",
          "gateway": "1.1.100.1/24"
        },
        "101": {
          "subnet": "1.1.101.0/24",
          "description": "mgmtVN",
          "gateway": "1.1.101.1/24"
        }
      },
      "esxPinkTrunk": {
        "88": {
          "subnet": "1.1.88.0/24",
          "description": "vMotionVN",
          "gateway": "1.1.88.1/24"
        },
        "89": {
          "subnet": "1.1.89.0/24",
          "description": "storageVN",
          "gateway": "1.1.89.1/24"
        },
        "90": {
          "subnet": "1.1.90.0/24",
          "description": "mgmtVN",
          "gateway": "1.1.90.1/24"
        }
esxTrunk 属性集(左侧)被构造为字典字典是有充分理由的:启用递归查找。esxBlueTrunk 字典已扩展为显示值 99、100、101,在本例中,这些值既用作 VLAN ID,又用作其下字典的键。以下字典提供了子网、网关和描述的键:值对。在此示例中,子网不是必需的,它的存在纯粹是为了参考。

通过以这种方式组织数据,配置模板被设计为通过两个数据结构递归以搜索匹配的标记:

1. esx中继属性集

2. 拓扑编辑器中的拓扑

当两个数据集中的标记匹配时,配置模板将生成所需的配置。

通过将左侧的属性集与“最终状态配置”部分中的 Junos 配置输出交叉引用,您可以看到:

  • 值 esx[红色 |蓝色 |Pink]Trunk,用作匹配的标签,因为我们遍历两个数据集。
  • 值 99、100、101 用作 VLAN ID
  • 网关用作 IRB 地址
  • 描述用于覆盖原始接口描述(根据需要)

两个 esx(红色/粉红色)主干都保存与 esxBlueTrunk 类似的信息

为了能够有效地递归遍历左侧的属性集和分配给拓扑中链接的标记,已特意为标记分配了相同的值

  • esxRedTrunk
  • esxBlueTrunk
  • esx粉红树干

这个 esxTrunk 属性集被构造为字典字典是有充分理由的:启用递归查找。esxBlueTrunk 字典已扩展为显示值 99、100、101,在本例中,这些值既用作 VLAN ID,又用作其下字典的键。以下字典提供了子网、网关和描述的键:值对。在此示例中,子网不是必需的,它的存在纯粹是为了参考。

通过以这种方式组织数据,配置模板被设计为通过两个数据结构递归以搜索匹配的标记:

  • esxTrunk 属性集

  • 拓扑编辑器中的拓扑

当两个数据集中的标记匹配时,配置模板将生成所需的配置。

通过将属性集与上面的 Junos 配置输出交叉引用,您可以看到:

  • 值 esx[红色 |蓝色 |Pink]Trunk,用作匹配的标签,因为我们遍历两个数据集。
  • 值 99、100、101 用作 VLAN ID
  • 网关用作 IRB 地址
  • 描述用于覆盖原始接口描述(根据需要)

两个 esx(Red / Pink)Trunk 都包含与 esxBlueTrunk 相似的信息。

为了实现属性集和分配给拓扑中链接的标记的高效递归遍历,特意为标记分配了相同的值

  • esxRedTrunk
  • esxBlueTrunk
  • esx粉红树干

Jinja2 基础配置模板状态机

配置模板 esxTunks.jinja 流程如下所述。

Jinja2 基本配置模板

以下基于 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(属性集标记)中的第一个值是以下字符串之一:

  • esxRedTrunk
  • esxBlueTrunk
  • esx粉红树干

现在遍历或“迭代”拓扑中的接口

如果接口link_tag存在,并且ps_tag在接口链路标记列表中,则表示满足呈现中继配置的条件

开始输出接口块

输出interface_name,其中 ps_tag 等于接口链路标记

(可选)指定描述,尽管 Freeform 已从拓扑中分配了此描述

设置单元号和相关配置以描述中继

设置中继成员

使用ps_tag遍历 esxTrunk 属性集以检索 VLAN ID

在第 1 行声明的字典中输入每个 VLAN ID 供以后使用

输出 esxTrunk 属性集中详述的 vn VLAN ID

当 esxTrunk 属性集中没有更多条目时结束 for 循环

结束上面的 if 语句

结束上面的 for 语句

结束上面的 for 语句

开始输出 irb 块

遍历Rendered_VNs字典

为了便于阅读,请将变量标签设置为存储在字典中的标签

使用vlan_id设置单元号

使用标记、vn 和密钥“网关”设置存储在 esxTrunk 属性集中的网关地址,以访问存储的字符串

结束上面的 for 语句

开始输出 VLAN 块

按照上面的 irb 块,遍历Rendered_VNs字典,

为了便于阅读,请将变量标签设置为存储在字典中的标签

设置 VN 编号

设置vlan_id ID

根据需要设置描述

设置第 3 层 IRB 编号

结束上面的 for 语句

用例 3:使用集中路由桥接的高级示例(CloudLabs 拓扑)

此用例是由 Apstra Engineering 编写的完整 CRB 示例。此示例完全使用静态 Jinja 模板构建,所有数据都在网络和设备的属性集中。这样,此 CRB 示例的用户只需编辑属性集即可操作、扩展和更改网络,并且您不必触摸底层 Jinja 模板。此用例旨在为您提供一个可能艺术的示例,并展示 Freeform 功能的灵活性和强大功能。所有配置模板、属性集以及 Jinja 模板和函数都嵌入了文档,以帮助您了解用法和功能。

此用例可作为使用 Juniper Apstra Cloudlabs 的完全部署的动手沙盒使用。还有一个包含所有相同文件的 GitHub 存储库。您可以以此作为执行某些功能的示例,为您的用例创建自己的高级配置模板。

高级 CRB 模板本质上是模块化的,从根级别开始,然后包括其他模板。下图显示了如何根据不同的 Jinja 模板开发渲染的配置。

请注意,属性集可用于任何 Jinja 配置模板,并充当全局变量。

高级 CRB 示例有助于了解在设计中使用 jinja 和属性集可以走多远。我们不会在这里包含所有的配置模板和属性集,我们将只概述几个示例并详细讨论它们以解释关键要点。

首先,重要的是要了解 包括 crb_root.jinja 另一组称为 jinja 的整套 jinja junos_configuration.jinja ,这包含在 Freeform 标准发行版中。

在此用例中,我们使用以下属性集,称为 routing_instances.json

请注意,有两个字典,在里面,它们列出了它们适用的系统,因此我们可以使用以下 Jinja 来检查系统名称是否与属性集匹配。

Jinja for crb_policy_options.jinja 主要是静态的,因为它对于大多数设备都是相同的,但如果设备是主干,我们需要提供外部连接,因此我们需要在配置的该部分添加更多信息。下面的 if 语句检查系统值是否包含设备的主机名,如果包含,则添加外部策略和路由过滤器。

接下来,让我们看一下 crb_routing_instances.jinja 它使用了一个复杂的 Jinja “for” 循环,该循环查找绑定到所选系统的所有 IRB 接口的值并呈现这些接口 irb.x。代码记录清晰,显示了“.”(点)在金贾中使用“systems.%s.ipv4_address”的符号。首先,让我们检查属性集中 vlans.json的 VLAN “20”。

%s 语法是表示selectattr('systems.%s.ipv4_address' %主机名的字符串),其中主机名是系统的名称。因此,此行基本上返回此示例中的键 20:

完整的配置模板和属性集可在“相关信息”部分中引用的 GitHub 存储库中找到。大多数配置模板都是自行记录的,因此您可以轻松查看代码并边走边学。请使用这些执行某些功能的示例,为您想要的用例制作自己的高级配置模板。

总结

Apstra 的数据中心参考设计旨在提供即插即用解决方案,自动执行“幕后”操作,从而简化第 0 天到第 2 天的操作并提高效率。但有时,我们的客户需要为其数据中心交换矩阵定制参考设计。Freeform 旨在满足这些自定义需求,为您提供指定自己的参考设计的工具,同时仍可利用 Apstra 的许多基于意图的分析功能。

本文将带领读者从 Freeform 使用的基本构造(标记、设备上下文、属性集和配置模板)到创建简单的 Freeform 蓝图,再到许多高级案例研究。

有关编辑 Jinja 文档的文档,请参阅 https://<apstra_ip>/static/jinja_docs/ 。