Integrate gnmic for gNMI telemetry collection

Add gnmic container node subscribing to interface, BGP, system, and
VXLAN gNMI paths across all Arista cEOS nodes, exposed via a
Prometheus exporter. gNMI runs in plaintext (no SSL profile on
management api gnmi), so insecure:true is used instead of TLS.

Refs #43, Refs #44
This commit is contained in:
2026-07-09 13:33:21 +00:00
parent d12e057bc8
commit 71cc8de7d5
3 changed files with 305 additions and 125 deletions

283
README.md
View File

@@ -4,11 +4,11 @@ An extended Arista BGP EVPN-VXLAN multi-fabric lab using ContainerLab and cEOS.
## 🎯 Overview
| Zone | Devices |
| ------ | --------------------------------------------------------------------------------------- |
| DC | 2 spines, 8 leafs (4 MLAG VTEPs), 2 border leafs (MLAG), 4 access switches, 4 hosts |
| Core | 2 core routers (iBGP AS 65500, OSPF underlay with BLs, eBGP to DC & Campus BLs) |
| Campus | 2 spines, 4 leafs (2 MLAG VTEPs), 2 border leafs (MLAG), 2 access switches, 2 hosts |
| Zone | Devices |
| ------ | ----------------------------------------------------------------------------------- |
| DC | 2 spines, 8 leafs (4 MLAG VTEPs), 2 border leafs (MLAG), 4 access switches, 4 hosts |
| Core | 2 core routers (iBGP AS 65500, OSPF underlay with BLs, eBGP to DC & Campus BLs) |
| Campus | 2 spines, 4 leafs (2 MLAG VTEPs), 2 border leafs (MLAG), 2 access switches, 2 hosts |
Key design choices:
@@ -16,12 +16,12 @@ Key design choices:
- **OSPF area 0 + eBGP multi-hop** between each Border Leaf pair and both Core routers (over dot1q subinterfaces: `.100` = default VRF underlay, `.200` = VRF `gold`).
- **MLAG** everywhere there is dual-homing at the fabric layers (leaf pairs, border-leaf pairs, access → leafs, and DC host → access).
- **Host attachment pattern**:
- **DC hosts** (servers) are **dual-homed via LACP** to an access switch — typical DC
server redundancy.
- **Campus hosts** (user endpoints: PC, phone, printer) are **single-attached** to a
Campus access switch via one plain Ethernet link. Redundancy lives at the access-switch
layer (the access switch itself is dual-homed via LACP to its leaf MLAG pair), not at
the host.
- **DC hosts** (servers) are **dual-homed via LACP** to an access switch — typical DC
server redundancy.
- **Campus hosts** (user endpoints: PC, phone, printer) are **single-attached** to a
Campus access switch via one plain Ethernet link. Redundancy lives at the access-switch
layer (the access switch itself is dual-homed via LACP to its leaf MLAG pair), not at
the host.
- **VRF `gold`** is stretched end-to-end: DC leafs (VLAN 34 / 78) ↔ DC-BL ↔ Core ↔ Campus-BL ↔ Campus leafs (VLAN 60 / 70), all sharing L3 VNI `100001`.
- **VLAN 50** remains defined as a campus-local L2 VXLAN stretched between the two Campus VTEPs (infrastructure-only, not wired to any host in the current topology).
- **Convention**: L2 VNI = `110000 + vlan_id`, L3 VNI = `100001` for VRF `gold`, RT `1:100001` in both fabrics.
@@ -64,50 +64,50 @@ docker exec -it clab-arista-evpn-fabric-dc-border-leaf1 Cli
### Node Inventory
| Zone | Role | Nodes | AS |
| ------ | ----------------------- | ------------------------------------------------------ | ------ |
| DC | Spine | `dc-spine1`, `dc-spine2` | 65000 |
| DC | Leaf VTEP1 (MLAG) | `dc-leaf1`, `dc-leaf2` | 65001 |
| DC | Leaf VTEP2 (MLAG) | `dc-leaf3`, `dc-leaf4` | 65002 |
| DC | Leaf VTEP3 (MLAG) | `dc-leaf5`, `dc-leaf6` | 65003 |
| DC | Leaf VTEP4 (MLAG) | `dc-leaf7`, `dc-leaf8` | 65004 |
| DC | Border Leaf (MLAG) | `dc-border-leaf1`, `dc-border-leaf2` | 65005 |
| DC | Access (L2-only) | `dc-access1`-`dc-access4` | — |
| DC | Host | `dc-server1`-`dc-server4` | — |
| Core | Core router | `core1`, `core2` | 65500 |
| Campus | Spine | `campus-spine1`, `campus-spine2` | 66000 |
| Campus | Leaf VTEP1 (MLAG) | `campus-leaf1`, `campus-leaf2` | 66001 |
| Campus | Leaf VTEP2 (MLAG) | `campus-leaf3`, `campus-leaf4` | 66002 |
| Campus | Border Leaf (MLAG) | `campus-border-leaf1`, `campus-border-leaf2` | 66005 |
| Campus | Access (L2-only) | `campus-access1`, `campus-access2` | — |
| Campus | Host | `campus-host1`, `campus-host2` | — |
| Zone | Role | Nodes | AS |
| ------ | ------------------ | -------------------------------------------- | ----- |
| DC | Spine | `dc-spine1`, `dc-spine2` | 65000 |
| DC | Leaf VTEP1 (MLAG) | `dc-leaf1`, `dc-leaf2` | 65001 |
| DC | Leaf VTEP2 (MLAG) | `dc-leaf3`, `dc-leaf4` | 65002 |
| DC | Leaf VTEP3 (MLAG) | `dc-leaf5`, `dc-leaf6` | 65003 |
| DC | Leaf VTEP4 (MLAG) | `dc-leaf7`, `dc-leaf8` | 65004 |
| DC | Border Leaf (MLAG) | `dc-border-leaf1`, `dc-border-leaf2` | 65005 |
| DC | Access (L2-only) | `dc-access1`-`dc-access4` | — |
| DC | Host | `dc-server1`-`dc-server4` | — |
| Core | Core router | `core1`, `core2` | 65500 |
| Campus | Spine | `campus-spine1`, `campus-spine2` | 66000 |
| Campus | Leaf VTEP1 (MLAG) | `campus-leaf1`, `campus-leaf2` | 66001 |
| Campus | Leaf VTEP2 (MLAG) | `campus-leaf3`, `campus-leaf4` | 66002 |
| Campus | Border Leaf (MLAG) | `campus-border-leaf1`, `campus-border-leaf2` | 66005 |
| Campus | Access (L2-only) | `campus-access1`, `campus-access2` | — |
| Campus | Host | `campus-host1`, `campus-host2` | — |
### AS Numbering
| AS | Role |
| ----- | ---------------------------------- |
| 65000 | DC Spine |
| 65001 | DC VTEP1 (dc-leaf1/2) |
| 65002 | DC VTEP2 (dc-leaf3/4) |
| 65003 | DC VTEP3 (dc-leaf5/6) |
| 65004 | DC VTEP4 (dc-leaf7/8) |
| 65005 | DC Border Leaf pair |
| 65500 | Core (iBGP between core1 & core2) |
| 66000 | Campus Spine |
| 66001 | Campus VTEP1 (campus-leaf1/2) |
| 66002 | Campus VTEP2 (campus-leaf3/4) |
| 66005 | Campus Border Leaf pair |
| AS | Role |
| ----- | --------------------------------- |
| 65000 | DC Spine |
| 65001 | DC VTEP1 (dc-leaf1/2) |
| 65002 | DC VTEP2 (dc-leaf3/4) |
| 65003 | DC VTEP3 (dc-leaf5/6) |
| 65004 | DC VTEP4 (dc-leaf7/8) |
| 65005 | DC Border Leaf pair |
| 65500 | Core (iBGP between core1 & core2) |
| 66000 | Campus Spine |
| 66001 | Campus VTEP1 (campus-leaf1/2) |
| 66002 | Campus VTEP2 (campus-leaf3/4) |
| 66005 | Campus Border Leaf pair |
### Access Switches
| Access Switch | Uplink Pair | VLANs | Host | Host attachment |
| --------------- | ------------------------ | -------- | -------------- | ------------------------- |
| dc-access1 | dc-leaf1/2 (VTEP1) | 40 | dc-server1 | LACP Po1 (dual-homed) |
| dc-access2 | dc-leaf3/4 (VTEP2) | 34 | dc-server2 | LACP Po1 (dual-homed) |
| dc-access3 | dc-leaf5/6 (VTEP3) | 40 | dc-server3 | LACP Po1 (dual-homed) |
| dc-access4 | dc-leaf7/8 (VTEP4) | 78 | dc-server4 | LACP Po1 (dual-homed) |
| campus-access1 | campus-leaf1/2 (VTEP1) | 60 | campus-host1 | access port (single link) |
| campus-access2 | campus-leaf3/4 (VTEP2) | 70 | campus-host2 | access port (single link) |
| Access Switch | Uplink Pair | VLANs | Host | Host attachment |
| -------------- | ---------------------- | ----- | ------------ | ------------------------- |
| dc-access1 | dc-leaf1/2 (VTEP1) | 40 | dc-server1 | LACP Po1 (dual-homed) |
| dc-access2 | dc-leaf3/4 (VTEP2) | 34 | dc-server2 | LACP Po1 (dual-homed) |
| dc-access3 | dc-leaf5/6 (VTEP3) | 40 | dc-server3 | LACP Po1 (dual-homed) |
| dc-access4 | dc-leaf7/8 (VTEP4) | 78 | dc-server4 | LACP Po1 (dual-homed) |
| campus-access1 | campus-leaf1/2 (VTEP1) | 60 | campus-host1 | access port (single link) |
| campus-access2 | campus-leaf3/4 (VTEP2) | 70 | campus-host2 | access port (single link) |
All access switches are L2-only, LACP-bonded to their leaf MLAG pair via `Port-Channel10`. MSTP + edge-port BPDU guard.
@@ -122,71 +122,72 @@ Host-facing ports:
### Management (`172.16.0.0/24`)
| Node | IP | Node | IP |
| ------------------------- | --------------- | ------------------------- | --------------- |
| dc-spine1 | 172.16.0.1 | campus-spine1 | 172.16.0.20 |
| dc-spine2 | 172.16.0.2 | campus-spine2 | 172.16.0.21 |
| dc-border-leaf1 | 172.16.0.3 | campus-border-leaf1 | 172.16.0.22 |
| dc-border-leaf2 | 172.16.0.4 | campus-border-leaf2 | 172.16.0.23 |
| core1 | 172.16.0.10 | campus-leaf1-4 | 172.16.0.51-54 |
| core2 | 172.16.0.11 | campus-access1 | 172.16.0.61 |
| dc-leaf1 | 172.16.0.25 | campus-access2 | 172.16.0.62 |
| dc-leaf2 | 172.16.0.50 | dc-server1-4 | 172.16.0.101-104|
| dc-leaf3-8 | 172.16.0.27-32 | campus-host1 | 172.16.0.105 |
| dc-access1-4 | 172.16.0.41-44 | campus-host2 | 172.16.0.106 |
| Node | IP | Node | IP |
| --------------- | -------------- | ------------------- | ---------------- |
| dc-spine1 | 172.16.0.1 | campus-spine1 | 172.16.0.20 |
| dc-spine2 | 172.16.0.2 | campus-spine2 | 172.16.0.21 |
| dc-border-leaf1 | 172.16.0.3 | campus-border-leaf1 | 172.16.0.22 |
| dc-border-leaf2 | 172.16.0.4 | campus-border-leaf2 | 172.16.0.23 |
| core1 | 172.16.0.10 | campus-leaf1-4 | 172.16.0.51-54 |
| core2 | 172.16.0.11 | campus-access1 | 172.16.0.61 |
| dc-leaf1 | 172.16.0.25 | campus-access2 | 172.16.0.62 |
| dc-leaf2 | 172.16.0.50 | dc-server1-4 | 172.16.0.101-104 |
| dc-leaf3-8 | 172.16.0.27-32 | campus-host1 | 172.16.0.105 |
| dc-access1-4 | 172.16.0.41-44 | campus-host2 | 172.16.0.106 |
| | | gnmic | 172.16.0.70 |
Gateway: `172.16.0.254`.
### Router-ID Loopback0 (`Lo0`)
| Zone | Range | Nodes |
| ------ | ------------------- | --------------------------------------------------------------------- |
| DC | `10.0.250.0/24` | dc-spine1 .1, dc-spine2 .2, dc-leaf1-8 .11-.18, BL-dc1 .21, BL-dc2 .22 |
| Core | `10.0.200.0/24` | core1 `10.0.200.1`, core2 `10.0.200.2` |
| Campus | `10.1.250.0/24` | campus-spine1 .1, campus-spine2 .2, campus-leaf1-4 .11-.14, BL-campus1 .21, BL-campus2 .22 |
| Zone | Range | Nodes |
| ------ | --------------- | ------------------------------------------------------------------------------------------ |
| DC | `10.0.250.0/24` | dc-spine1 .1, dc-spine2 .2, dc-leaf1-8 .11-.18, BL-dc1 .21, BL-dc2 .22 |
| Core | `10.0.200.0/24` | core1 `10.0.200.1`, core2 `10.0.200.2` |
| Campus | `10.1.250.0/24` | campus-spine1 .1, campus-spine2 .2, campus-leaf1-4 .11-.14, BL-campus1 .21, BL-campus2 .22 |
### VTEP Loopback1 (`Lo1`) — shared per MLAG pair
| Fabric | VTEP | Address | Leafs |
| ------ | ------ | --------------- | ---------------------- |
| DC | VTEP1 | `10.0.255.11` | dc-leaf1, dc-leaf2 |
| DC | VTEP2 | `10.0.255.12` | dc-leaf3, dc-leaf4 |
| DC | VTEP3 | `10.0.255.13` | dc-leaf5, dc-leaf6 |
| DC | VTEP4 | `10.0.255.14` | dc-leaf7, dc-leaf8 |
| DC | BL | `10.0.255.15` | dc-border-leaf1/2 |
| Campus | VTEP1 | `10.1.255.11` | campus-leaf1/2 |
| Campus | VTEP2 | `10.1.255.12` | campus-leaf3/4 |
| Campus | BL | `10.1.255.21` | campus-border-leaf1/2 |
| Fabric | VTEP | Address | Leafs |
| ------ | ----- | ------------- | --------------------- |
| DC | VTEP1 | `10.0.255.11` | dc-leaf1, dc-leaf2 |
| DC | VTEP2 | `10.0.255.12` | dc-leaf3, dc-leaf4 |
| DC | VTEP3 | `10.0.255.13` | dc-leaf5, dc-leaf6 |
| DC | VTEP4 | `10.0.255.14` | dc-leaf7, dc-leaf8 |
| DC | BL | `10.0.255.15` | dc-border-leaf1/2 |
| Campus | VTEP1 | `10.1.255.11` | campus-leaf1/2 |
| Campus | VTEP2 | `10.1.255.12` | campus-leaf3/4 |
| Campus | BL | `10.1.255.21` | campus-border-leaf1/2 |
### Underlay P2P (`/31`)
| Segment | Subnets |
| -------------------------------- | --------------------------------------- |
| DC dc-spine1 ↔ leaf/BL | `10.0.1.0/31``10.0.1.18/31` |
| DC dc-spine2 ↔ leaf/BL | `10.0.2.0/31``10.0.2.18/31` |
| DC MLAG iBGP SVIs (per pair) | `10.0.3.0/31`, `.2/31`, `.4/31`, `.6/31`, `.8/31` (BL) |
| DC MLAG peer-link SVIs | `10.0.199.240/31``10.0.199.246/31` |
| DC-BL ↔ Core (default, `.100`) | `10.0.4.0/31` .. `10.0.4.6/31` |
| DC-BL ↔ Core (VRF gold, `.200`) | `10.0.14.0/31` .. `10.0.14.6/31` |
| Campus-BL ↔ Core (default) | `10.0.5.0/31` .. `10.0.5.6/31` |
| Campus-BL ↔ Core (VRF gold) | `10.0.15.0/31` .. `10.0.15.6/31` |
| Core1 ↔ Core2 (default) | `10.0.200.128/31` |
| Core1 ↔ Core2 (VRF gold) | `10.0.200.130/31` |
| Campus dc-spine1 ↔ leaf/BL | `10.1.1.0/31``10.1.1.10/31` |
| Campus dc-spine2 ↔ leaf/BL | `10.1.2.0/31``10.1.2.10/31` |
| Campus MLAG iBGP SVIs | `10.1.3.0/31`, `.2/31`, `.4/31` |
| Campus MLAG peer-link SVIs | `10.1.199.250/31``10.1.199.254/31` |
| Segment | Subnets |
| ------------------------------- | ------------------------------------------------------ |
| DC dc-spine1 ↔ leaf/BL | `10.0.1.0/31``10.0.1.18/31` |
| DC dc-spine2 ↔ leaf/BL | `10.0.2.0/31``10.0.2.18/31` |
| DC MLAG iBGP SVIs (per pair) | `10.0.3.0/31`, `.2/31`, `.4/31`, `.6/31`, `.8/31` (BL) |
| DC MLAG peer-link SVIs | `10.0.199.240/31``10.0.199.246/31` |
| DC-BL ↔ Core (default, `.100`) | `10.0.4.0/31` .. `10.0.4.6/31` |
| DC-BL ↔ Core (VRF gold, `.200`) | `10.0.14.0/31` .. `10.0.14.6/31` |
| Campus-BL ↔ Core (default) | `10.0.5.0/31` .. `10.0.5.6/31` |
| Campus-BL ↔ Core (VRF gold) | `10.0.15.0/31` .. `10.0.15.6/31` |
| Core1 ↔ Core2 (default) | `10.0.200.128/31` |
| Core1 ↔ Core2 (VRF gold) | `10.0.200.130/31` |
| Campus dc-spine1 ↔ leaf/BL | `10.1.1.0/31``10.1.1.10/31` |
| Campus dc-spine2 ↔ leaf/BL | `10.1.2.0/31``10.1.2.10/31` |
| Campus MLAG iBGP SVIs | `10.1.3.0/31`, `.2/31`, `.4/31` |
| Campus MLAG peer-link SVIs | `10.1.199.250/31``10.1.199.254/31` |
### Host Addressing
| Host | VLAN | VRF | IP / Mask | Gateway | Purpose |
| ------------- | ---- | -------- | ----------------- | ------------ | ------------------------------ |
| dc-server1 | 40 | default | 10.40.40.101/24 | — | DC L2 stretched (VTEP1↔VTEP3) |
| dc-server2 | 34 | gold | 10.34.34.102/24 | 10.34.34.1 | DC L3 VRF gold |
| dc-server3 | 40 | default | 10.40.40.103/24 | — | DC L2 stretched |
| dc-server4 | 78 | gold | 10.78.78.104/24 | 10.78.78.1 | DC L3 VRF gold |
| campus-host1 | 60 | gold | 10.60.60.101/24 | 10.60.60.1 | Campus L3 VRF gold |
| campus-host2 | 70 | gold | 10.60.70.102/24 | 10.60.70.1 | Campus L3 VRF gold |
| Host | VLAN | VRF | IP / Mask | Gateway | Purpose |
| ------------ | ---- | ------- | --------------- | ---------- | ----------------------------- |
| dc-server1 | 40 | default | 10.40.40.101/24 | — | DC L2 stretched (VTEP1↔VTEP3) |
| dc-server2 | 34 | gold | 10.34.34.102/24 | 10.34.34.1 | DC L3 VRF gold |
| dc-server3 | 40 | default | 10.40.40.103/24 | — | DC L2 stretched |
| dc-server4 | 78 | gold | 10.78.78.104/24 | 10.78.78.1 | DC L3 VRF gold |
| campus-host1 | 60 | gold | 10.60.60.101/24 | 10.60.60.1 | Campus L3 VRF gold |
| campus-host2 | 70 | gold | 10.60.70.102/24 | 10.60.70.1 | Campus L3 VRF gold |
> DC hosts are dual-homed in LACP over `bond0` with tagged VLAN sub-interfaces.
> Campus hosts are single-attached with one untagged `eth1` in a single access VLAN.
@@ -195,20 +196,20 @@ Gateway: `172.16.0.254`.
### L2 VNI Mapping
| VLAN | Description | VNI | Scope | RT |
| ---- | ------------------------------ | ------ | ------------------------------------------------------ | ---------- |
| 40 | DC L2 VXLAN (stretched) | 110040 | DC VTEP1 (dc-leaf1/2) + VTEP3 (dc-leaf5/6) | 40:110040 |
| 50 | Campus L2 VXLAN (stretched) | 110050 | Campus VTEP1 (campus-leaf1/2) + VTEP2 (campus-leaf3/4) | 50:110050 |
| 34 | DC VRF gold subnet (local) | 110034 | DC VTEP2 only (anycast GW 10.34.34.1) | 34:110034 |
| 78 | DC VRF gold subnet (local) | 110078 | DC VTEP4 only (anycast GW 10.78.78.1) | 78:110078 |
| 60 | Campus VRF gold subnet (local) | 110060 | Campus VTEP1 only (anycast GW 10.60.60.1) | 60:110060 |
| 70 | Campus VRF gold subnet (local) | 110070 | Campus VTEP2 only (anycast GW 10.60.70.1) | 70:110070 |
| VLAN | Description | VNI | Scope | RT |
| ---- | ------------------------------ | ------ | ------------------------------------------------------ | --------- |
| 40 | DC L2 VXLAN (stretched) | 110040 | DC VTEP1 (dc-leaf1/2) + VTEP3 (dc-leaf5/6) | 40:110040 |
| 50 | Campus L2 VXLAN (stretched) | 110050 | Campus VTEP1 (campus-leaf1/2) + VTEP2 (campus-leaf3/4) | 50:110050 |
| 34 | DC VRF gold subnet (local) | 110034 | DC VTEP2 only (anycast GW 10.34.34.1) | 34:110034 |
| 78 | DC VRF gold subnet (local) | 110078 | DC VTEP4 only (anycast GW 10.78.78.1) | 78:110078 |
| 60 | Campus VRF gold subnet (local) | 110060 | Campus VTEP1 only (anycast GW 10.60.60.1) | 60:110060 |
| 70 | Campus VRF gold subnet (local) | 110070 | Campus VTEP2 only (anycast GW 10.60.70.1) | 70:110070 |
### L3 VNI Mapping (end-to-end)
| VRF | L3 VNI | RT | Scope |
| ---- | ------- | ---------- | ----------------------------------------------------- |
| gold | 100001 | 1:100001 | DC VTEP2/VTEP4/DC-BL + Campus VTEP1/VTEP2/Campus-BL |
| VRF | L3 VNI | RT | Scope |
| ---- | ------ | -------- | --------------------------------------------------- |
| gold | 100001 | 1:100001 | DC VTEP2/VTEP4/DC-BL + Campus VTEP1/VTEP2/Campus-BL |
VRF `gold` is announced over EVPN Type-5 (IP prefix) inside each fabric, and **stitched by the Core** via eBGP IPv4 unicast in VRF gold (over the `.200` dot1q subinterfaces). L3 VNI `100001` is re-used end-to-end for symmetry; RT `1:100001` is consistent across both fabrics.
@@ -219,19 +220,19 @@ VRF `gold` is announced over EVPN Type-5 (IP prefix) inside each fabric, and **s
## 🔀 Control Plane Summary
| Segment | Protocol | Notes |
| ----------------------------------- | ------------------------------------ | ------------------------------------- |
| DC spine ↔ leaf/BL underlay | eBGP IPv4 (AS 65000 ↔ 650xx) | `maximum-paths 4 ecmp 64` |
| DC spine ↔ leaf/BL overlay | eBGP EVPN via Loopback0, multi-hop 3 | Spines reflect via `ebgp peer-group` |
| DC MLAG pair iBGP | iBGP over VLAN 4091 SVI | `next-hop-self` |
| DC-BL ↔ Core (default) | OSPF area 0 + eBGP AS 65005 ↔ 65500 | on `.100` dot1q subinterface |
| DC-BL ↔ Core (VRF gold) | eBGP AS 65005 ↔ 65500 | on `.200` dot1q subinterface |
| Core1 ↔ Core2 (default) | OSPF area 0 + iBGP AS 65500 | via Loopback0 |
| Core1 ↔ Core2 (VRF gold) | iBGP AS 65500 | VRF-aware over `.200` subinterface |
| Campus-BL ↔ Core (default / gold) | OSPF + eBGP AS 66005 ↔ 65500 | same pattern as DC-BL |
| Campus spine ↔ leaf/BL underlay | eBGP IPv4 (AS 66000 ↔ 660xx) | |
| Campus spine ↔ leaf/BL overlay | eBGP EVPN via Loopback0, multi-hop 3 | |
| Campus MLAG pair iBGP | iBGP over VLAN 4091 SVI | |
| Segment | Protocol | Notes |
| --------------------------------- | ------------------------------------ | ------------------------------------ |
| DC spine ↔ leaf/BL underlay | eBGP IPv4 (AS 65000 ↔ 650xx) | `maximum-paths 4 ecmp 64` |
| DC spine ↔ leaf/BL overlay | eBGP EVPN via Loopback0, multi-hop 3 | Spines reflect via `ebgp peer-group` |
| DC MLAG pair iBGP | iBGP over VLAN 4091 SVI | `next-hop-self` |
| DC-BL ↔ Core (default) | OSPF area 0 + eBGP AS 65005 ↔ 65500 | on `.100` dot1q subinterface |
| DC-BL ↔ Core (VRF gold) | eBGP AS 65005 ↔ 65500 | on `.200` dot1q subinterface |
| Core1 ↔ Core2 (default) | OSPF area 0 + iBGP AS 65500 | via Loopback0 |
| Core1 ↔ Core2 (VRF gold) | iBGP AS 65500 | VRF-aware over `.200` subinterface |
| Campus-BL ↔ Core (default / gold) | OSPF + eBGP AS 66005 ↔ 65500 | same pattern as DC-BL |
| Campus spine ↔ leaf/BL underlay | eBGP IPv4 (AS 66000 ↔ 660xx) | |
| Campus spine ↔ leaf/BL overlay | eBGP EVPN via Loopback0, multi-hop 3 | |
| Campus MLAG pair iBGP | iBGP over VLAN 4091 SVI | |
## 🧪 Testing & Validation
@@ -323,6 +324,36 @@ ssh admin@clab-arista-evpn-fabric-dc-border-leaf1 "show bgp evpn route-type ip-p
ssh admin@clab-arista-evpn-fabric-campus-border-leaf1 "show bgp evpn route-type ip-prefix ipv4"
```
## 📡 Telemetry
A [`gnmic`](https://gnmic.openconfig.net/) container node subscribes to gNMI (port `6030`,
`eos-native` provider) on every Arista `cEOS` node in the fabric, and exposes the
collected metrics on a Prometheus exporter endpoint.
Subscriptions (see issue #44 for the path-selection rationale):
| Subscription | Nodes | Paths |
| -------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `eos-interfaces` | all | `interfaces/interface/state/{oper-status,counters}` |
| `eos-bgp` | all | `.../bgp/neighbors/neighbor/state/session-state`, `.../afi-safis/afi-safi/state/prefixes` (IPv4/IPv6 unicast + L2VPN EVPN) |
| `eos-system` | all | `/system/cpus/cpu/state`, `/system/memory/state` |
| `eos-vxlan` | VTEP nodes only (leafs + border-leafs, both fabrics) | VLAN-to-VNI mapping + MAC table entries — joined in Prometheus to get MAC count per VNI |
- Config: `configs/gnmic/gnmic-config.yml`
- TLS: `insecure: true` — cEOS gNMI runs in plaintext here (no SSL profile configured on
`management api gnmi`), not TLS; `skip-verify` would fail the handshake
- `oper-status` and BGP `session-state` are string enums; gnmic's Prometheus output drops
non-numeric leaves, so the `state-to-int` event-processor maps them to `1`/`0`
- Prometheus exporter: `http://clab-arista-evpn-fabric-gnmic:9273/metrics`
```bash
# Validate gnmic is subscribed and streaming from all targets
docker logs clab-arista-evpn-fabric-gnmic
# Scrape the Prometheus exporter directly
docker exec clab-arista-evpn-fabric-gnmic wget -qO- http://localhost:9273/metrics | head
```
## 📁 Repository Structure
```
@@ -343,7 +374,9 @@ arista-evpn-vxlan-clab/
│ ├── campus-spine1.cfg, campus-spine2.cfg
│ ├── campus-leaf1.cfg … campus-leaf4.cfg
│ ├── campus-border-leaf1.cfg, campus-border-leaf2.cfg
── campus-access1.cfg, campus-access2.cfg
── campus-access1.cfg, campus-access2.cfg
│ └── gnmic/
│ └── gnmic-config.yml
└── hosts/
├── README.md
├── dc-server1_interfaces … dc-server4_interfaces

View File

@@ -0,0 +1,135 @@
username: admin
password: admin
port: 6030
timeout: 10s
common_eos_subscriptions: &common_eos_subs
insecure: true
subscriptions:
- eos-interfaces
- eos-bgp
- eos-system
vtep_eos_subscriptions: &vtep_eos_subs
insecure: true
subscriptions:
- eos-interfaces
- eos-bgp
- eos-system
- eos-vxlan
targets:
# DC fabric
dc-spine1: *common_eos_subs
dc-spine2: *common_eos_subs
dc-leaf1: *vtep_eos_subs
dc-leaf2: *vtep_eos_subs
dc-leaf3: *vtep_eos_subs
dc-leaf4: *vtep_eos_subs
dc-leaf5: *vtep_eos_subs
dc-leaf6: *vtep_eos_subs
dc-leaf7: *vtep_eos_subs
dc-leaf8: *vtep_eos_subs
dc-border-leaf1: *vtep_eos_subs
dc-border-leaf2: *vtep_eos_subs
dc-access1: *common_eos_subs
dc-access2: *common_eos_subs
dc-access3: *common_eos_subs
dc-access4: *common_eos_subs
# Core
core1: *common_eos_subs
core2: *common_eos_subs
# Campus fabric
campus-spine1: *common_eos_subs
campus-spine2: *common_eos_subs
campus-border-leaf1: *vtep_eos_subs
campus-border-leaf2: *vtep_eos_subs
campus-leaf1: *vtep_eos_subs
campus-leaf2: *vtep_eos_subs
campus-leaf3: *vtep_eos_subs
campus-leaf4: *vtep_eos_subs
campus-access1: *common_eos_subs
campus-access2: *common_eos_subs
subscriptions:
eos-interfaces:
mode: stream
stream-mode: sample
sample-interval: 10s
paths:
- /interfaces/interface/state/oper-status
- /interfaces/interface/state/counters
eos-bgp:
mode: stream
stream-mode: sample
sample-interval: 10s
paths:
- /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/session-state
- /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes
eos-system:
mode: stream
stream-mode: sample
sample-interval: 10s
paths:
- /system/cpus/cpu/state
- /system/memory/state
eos-vxlan:
mode: stream
stream-mode: sample
sample-interval: 10s
paths:
# VLAN-to-VNI mapping (join key for MAC-count-per-VNI in Prometheus)
- /interfaces/interface[name=Vxlan1]/arista-exp-eos-vxlan:arista-vxlan/vlan-to-vnis/vlan-to-vni
# MAC table entries, tagged by VLAN — joined with the mapping above to get per-VNI counts
- /network-instances/network-instance/fdb/mac-table/entries/entry
outputs:
prom-output:
type: prometheus
listen: :9273
event-processors:
- state-to-int
# oper-status and BGP session-state are string enums; the Prometheus output
# silently drops non-numeric values, so they're mapped to 1 (up/established) / 0 (anything else)
processors:
state-to-int:
event-strings:
value-names:
- ".*oper-status$"
- ".*session-state$"
transforms:
- replace:
apply-on: "value"
old: "UP"
new: "1"
- replace:
apply-on: "value"
old: "ESTABLISHED"
new: "1"
- replace:
apply-on: "value"
old: "DOWN"
new: "0"
- replace:
apply-on: "value"
old: "IDLE"
new: "0"
- replace:
apply-on: "value"
old: "CONNECT"
new: "0"
- replace:
apply-on: "value"
old: "ACTIVE"
new: "0"
- replace:
apply-on: "value"
old: "OPENSENT"
new: "0"
- replace:
apply-on: "value"
old: "OPENCONFIRM"
new: "0"

View File

@@ -290,6 +290,18 @@ topology:
exec:
- ifup eth1
# =====================================================
# TELEMETRY
# =====================================================
gnmic:
kind: linux
mgmt-ipv4: 172.16.0.70
image: ghcr.io/openconfig/gnmic:0.46.0
binds:
- configs/gnmic/gnmic-config.yml:/gnmic-config.yml:ro
cmd: --config /gnmic-config.yml --log subscribe
links:
# =====================================================
# DATACENTER FABRIC LINKS