종합적인 솔루션
다음 사용 사례는 논의된 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; }
-
구성 템플릿 표시
구성 템플릿 시스템.jinja 설명 system { host-name {{hostname}}; }
이 템플릿은 디바이스 컨텍스트에서 내장된 "hostname" 변수를 사용하여 시스템 호스트 이름을 이것으로 설정합니다. 구성 템플릿 interfaces.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=호스트 이름 설정
인터페이스를 거치고 인터페이스에 대한 설명과 디바이스 컨텍스트에서의 제품군 inet 주소 및 접두사 길이를 포함하여 junos에 대한 적절한 인터페이스 stanza 구문을 삽입하는 루프의 경우. 토폴로지 편집기 의 링크를 통해 이러한 값을 채울 수 있습니다.
이렇게 하면 이 라우터의 루프백 주소에 대한 property_set 데이터가 루프백 stanza에 삽입됩니다.
구성 템플릿 프로토콜.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 = 호스트 이름을 설정합니다.
정책 옵션 stanza를 설정하여 직접 연결된 모든 경로를 전송합니다.
인터페이스 트리를 걷습니다.
토폴로지에서 인터페이스에 설정된 태그에 변수 link_med 설정합니다.
LLDP 매개 변수 설정
RSTP 매개 변수 설정
bgp stanza 만들기
그룹 외부 피어
외부 유형(ebgp)
send-direct 내보내기 정책
인터페이스 트리를 걷고 ipv4 주소가 있는 모든 이웃에 이웃을 삽입합니다. peer_hostname 변수를 이웃 인터페이스 호스트 이름에 설정합니다.
property_sets 데이터 "asn"에서 피어를 잡아라
add-med-tags의 내보내기 정책으로 설정된 Peer-as stanza
속성 세트의 ASN(Autonomous System)으로 routing-options stanza를 설정합니다.
-
속성 세트
속성 세트 "데이터" 설명 { "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" } }
속성 집합은 다음과 같은 사전 목록으로 간단하게 표시됩니다.
-
시스템 또는 스테이션의 이름이 핵심이며, 그 키 내부에는 두 가지 매개 변수가 있습니다.
-
BGP 피어링을 위한 ASN(Autonomous System Number)입니다.
-
피어할 시스템/스테이션의 루프백 주소인 루프백입니다.
-
사용 사례 #2 - Day 2 구성을 위한 태그 및 속성 세트
아래에 표시된 작은 토폴로지는 Freeform 토폴로지 편집기에서 구성되었습니다. 스위치 3개와 ESXi-1 및 ESXi-2라는 외부 시스템이 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 사전은 이 인스턴스에서 VLAN ID와 그 아래 사전의 키로 사용되는 값 99, 100, 101을 표시하도록 확장되었습니다. 아래 사전에서는 서브넷, 게이트웨이 및 설명에 대한 값 쌍의 키를 제공합니다. 이 예에서 서브넷은 필요하지 않으며 순전히 참조를 위해 존재합니다. 이러한 방식으로 구성된 데이터를 통해 Config 템플릿은 일치하는 태그를 검색하기 위해 두 개의 데이터 구조를 통해 재귀하도록 설계되었습니다.
두 데이터 세트의 태그가 일치하면 구성 템플릿이 원하는 구성을 생성합니다. 위의 Junos 구성 출력과 함께 속성 세트를 왼쪽으로 교차 참조하면 다음을 확인할 수 있습니다.
두 esx(빨간색/분홍색) 트렁크 모두 esxBlueTrunk와 유사한 정보를 보유합니다. 속성 세트를 왼쪽으로, 그리고 토폴로지의 링크에 할당된 태그를 효율적으로 재귀적으로 걷기 위해 태그는 의도적으로 동일한 값을 할당했습니다.
|
Jinja2 기본 구성 템플릿 상태 머신
구성 템플릿 esxTrunks.jinja flow는 아래에 설명되어 있습니다.
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를 검색합니다. 이후 사용을 위해 1행에 선언된 사전에 각 VLAN ID를 입력합니다. esxTrunk 속성 집합에 자세히 설명된 vn VLAN ID 출력 esxTrunk 속성 집합에 더 이상 항목이 없을 때 루프 종료 위의 if 문 종료 위의 문에 대한 종료 위의 문에 대한 종료 irb 블록 출력 시작 Rendered_VNs 사전을 트래버스합니다. 가독성을 위해 사전에 저장된 태그에 변수 태그를 설정합니다. vlan_id 사용하여 장치 번호를 설정합니다. 태그, vn 및 키 '게이트웨이'를 사용하여 esxTrunk PropertySet에 저장된 게이트웨이 주소를 설정하여 저장된 문자열에 액세스합니다. 위의 문에 대한 종료 vlans 블록을 출력하는 Starer 위의 irb 블록에 따라 Rendered_VNs 사전을 통과합니다. 가독성을 위해 사전에 저장된 태그에 변수 태그를 설정합니다. vn 번호 설정 vlan_id ID 설정 필요에 따라 설명 설정 레이어3 irb 번호 설정 위의 문에 대한 종료 |
아래에 표시된 Jinja2 기반 구성 템플릿은 할당된 태그와 속성 세트를 모두 활용하여 필요한 구성을 구축합니다.
사용 사례 #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