A mini data center on one PC
A data center that fits in your laptop. We live in the future.
Big data centers use a simple, powerful shape: every leaf switch connects to every spine switch, with BGP choosing between all the paths at once. With Containerlab and the free FRRouting software, you can build one on a single Linux machine in minutes.
🧰 What you need
- A Linux machine or VM (Ubuntu works well) with 4 GB of RAM or more. Windows users can use WSL2
- Docker (see the old laptop lab, step 6)
Let's build it
Install Containerlab
bash -c "$(curl -sL https://get.containerlab.dev)"Make a project folder
mkdir minidc && cd minidcTell FRR which routing daemons to run
Save as daemons:
bgpd=yes
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"Describe the topology
Save as minidc.clab.yml: two spines, two leaves, every leaf cabled to every spine.
name: minidc
topology:
defaults:
kind: linux
image: quay.io/frrouting/frr:10.2.1
nodes:
spine1: {binds: [spine1.conf:/etc/frr/frr.conf, daemons:/etc/frr/daemons]}
spine2: {binds: [spine2.conf:/etc/frr/frr.conf, daemons:/etc/frr/daemons]}
leaf1: {binds: [leaf1.conf:/etc/frr/frr.conf, daemons:/etc/frr/daemons]}
leaf2: {binds: [leaf2.conf:/etc/frr/frr.conf, daemons:/etc/frr/daemons]}
links:
- endpoints: ["spine1:eth1", "leaf1:eth1"]
- endpoints: ["spine1:eth2", "leaf2:eth1"]
- endpoints: ["spine2:eth1", "leaf1:eth2"]
- endpoints: ["spine2:eth2", "leaf2:eth2"]Configure the spines
Save as spine1.conf. For spine2.conf, change the hostname to spine2 and 10.0.0.1 to 10.0.0.2 in both places.
frr defaults datacenter
hostname spine1
interface lo
ip address 10.0.0.1/32
router bgp 65000
bgp router-id 10.0.0.1
neighbor FABRIC peer-group
neighbor FABRIC remote-as external
neighbor eth1 interface peer-group FABRIC
neighbor eth2 interface peer-group FABRIC
address-family ipv4 unicast
redistribute connected
exit-address-familyConfigure the leaves
Save as leaf1.conf. For leaf2.conf, use hostname leaf2, AS 65102 and 10.1.1.2 in both places.
frr defaults datacenter
hostname leaf1
interface lo
ip address 10.1.1.1/32
router bgp 65101
bgp router-id 10.1.1.1
neighbor FABRIC peer-group
neighbor FABRIC remote-as external
neighbor eth1 interface peer-group FABRIC
neighbor eth2 interface peer-group FABRIC
address-family ipv4 unicast
redistribute connected
exit-address-familyBring the data center to life
sudo containerlab deploy -t minidc.clab.ymlLook at the fabric
sudo docker exec clab-minidc-leaf1 vtysh -c "show bgp summary"Both spines show as neighbours with prefixes received.
✅ How you know it worked
Ping leaf2's loopback from leaf1's loopback, then look at the route:
sudo docker exec clab-minidc-leaf1 ping -c3 -I 10.1.1.1 10.1.1.2
sudo docker exec clab-minidc-leaf1 ip route show 10.1.1.2The ping works, and the route to 10.1.1.2 has two next hops, one through each spine. Both paths are used at once: that's ECMP.
💥 Break it on purpose
Pull a "cable" on leaf1:
sudo docker exec clab-minidc-leaf1 ip link set eth1 downCheck the route again: one next hop left, and the ping still works through the other spine. Bring it back with ip link set eth1 up. When you're done, sudo containerlab destroy -t minidc.clab.yml cleans it all away.
🧠 What's really going on
In spine-and-leaf, every leaf is exactly two hops from every other leaf, and adding capacity just means adding another spine. Each switch runs BGP with its neighbours. The neighbor eth1 interface lines use "BGP unnumbered": the links need no IP addresses at all, because BGP finds its neighbour on the cable automatically. Every leaf learns every other leaf's routes through every spine and uses all of those paths at once. (Those odd fe80:: next hops in the route are the link addresses BGP unnumbered uses in place of IPs on each cable.)
← Back to all network labs · Stuck? Email me