Lab Hygiene

Updated

September 4, 2026

Lab Hygiene

Brilliant topologies rot without hygiene: colliding subnets, random hostnames, uncommitted click-ops, and mystery cables. This chapter is the professional layer on top of Containerlab—how to keep labs reproducible, reviewable, and kind to future you.

Learning goals

By the end of this chapter you can:

  • Write an addressing plan before deploy
  • Apply consistent node and interface naming
  • Structure a lab repo/directory for git
  • Keep diagrams and inventories in sync
  • Run a personal definition-of-done for every lab
  • Avoid cross-lab contamination on one host

Why hygiene is a skill

Without hygiene With hygiene
“Which 10.0.0.0/24 is this?” Documented per-lab blocks
Works once after 40 hand edits Destroy/deploy/verify loop
Cannot explain a failure Journal + captures
Peer cannot run your lab README + pins + scripts

Hygiene is not bureaucracy; it is how lab craft scales.

Addressing plans

Never invent IPs mid-SSH.

Template

# Addressing — lab triangle-ospf

| Node | Interface | Address | Notes |
|------|-----------|---------|-------|
| r1 | eth1 | 10.0.12.1/24 | to r2 |
| r2 | eth1 | 10.0.12.2/24 | to r1 |
| r1 | eth2 | 10.0.13.1/24 | to r3 |
| r3 | eth2 | 10.0.13.2/24 | to r1 |
| r2 | eth2 | 10.0.23.1/24 | to r3 |
| r3 | eth1 | 10.0.23.2/24 | to r2 |
| h1 | eth1 | 192.168.1.10/24 | gw 192.168.1.1 (r1 lo/lan) |

Loopbacks:
| Node | lo | 
|------|-----|
| r1 | 1.1.1.1/32 |
| r2 | 2.2.2.2/32 |
| r3 | 3.3.3.3/32 |

VLANs: n/a
ASNs: n/a
Mgmt: Containerlab default pool

Allocation strategy (personal lab supernets)

Pick a lab supernet you will not confuse with home LAN:

Use Example block
Home LAN (real) 192.168.1.0/24 (do not reuse in labs if VPN splits break)
Lab underlay P2P 10.0.0.0/16 carved into /24 or /30
Lab customer VRFs 10.10.0.0/16
Loopbacks 10.255.0.0/24 as /32s
“Internet” sim 203.0.113.0/24 (documentation range) / 192.0.2.0/24

Documentation ranges (RFC 5737) are great for examples in prose; inside isolated labs private space is fine—just write it down.

Naming conventions

Lab name

name: l2-vlan-trunk   # short, hyphenated, unique among active labs

Container names become clab-<name>-<node>.

Node names

Pattern Examples
Role + number r1, r2, sw1, h1
Role + site edge-a, core-1
Avoid test, node, foo, router

Interface names

Stick to what the image uses (eth1, eth2… for many Linux kinds). Document any breakout or rename.

Git branches / folders

labs/
  03-l2-vlan-trunk/
  04-static-triangle/
  05-ospf-single-area/

Numeric prefixes match book order when useful.

Directory layout (canonical)

labs/04-static-triangle/
  README.md           # intent, pins, how to run
  topology.clab.yml
  addressing.md
  journal.md
  verify.sh
  up.sh               # optional deploy wrapper
  down.sh             # destroy --cleanup
  config/
    r1/
    r2/
    h1/
  captures/
  diagrams/
    logical.png       # or .svg / .drawio

README skeleton

# Static triangle

## Intent
Three FRR routers, static routes, dual hosts ping.

## Images
- quay.io/frrouting/frr:10.2.1
- alpine:3.20

## Run
sudo containerlab deploy -t topology.clab.yml
./verify.sh
sudo containerlab destroy -t topology.clab.yml --cleanup

## Failure drills
- shut transit link r1-r2
- remove return route on r3

Git habits

git status
git add labs/04-static-triangle
git commit -m "lab: static triangle with verify.sh"

Commit:

  • Topology YAML
  • Configs
  • addressing.md
  • verify.sh
  • journal highlights (not necessarily huge pcaps)

Usually ignore:

  • Large pcaps (store sparse samples or regenerate)
  • Ephemeral logs
# example snippet
labs/**/captures/*.pcap
!labs/**/captures/.gitkeep

Never commit

  • Production credentials
  • Private keys
  • Proprietary images

Diagram habit

Minimum viable diagram set:

  1. Logical — nodes and links
  2. Addressing — subnets/VLAN IDs on links
  3. Failure — which link you shut for the drill

ASCII is valid:

h1--r1------r2--h2
     \      /
      \    /
        r3

Illustrated topology SVGs (self-contained light canvas) match this book’s lab figures under images/; conceptual models may stay monochrome. See images/README.md.

Configuration hygiene

Do Don’t
Edit files under config/ Treasure unique vtysh-only state
Reload/restart from files Assume memory is durable
Diff configs in git Copy-paste from chat without review
Comment tricky policy lines Leave “magic” prefix-lists

FRR example: comment intent

! block lab RFC1918 from leaking to "isp" peer
ip prefix-list LAB-PRIV seq 5 permit 10.0.0.0/8 le 32

verify.sh hygiene

  • set -euo pipefail
  • Explicit container names
  • Timeouts on ping
  • Exit non-zero on failure
  • Print which check failed
#!/usr/bin/env bash
set -euo pipefail
PASS=0
fail() { echo "FAIL: $*" >&2; exit 1; }

docker exec clab-static-h1 ping -c 2 -W 1 10.2.0.10 \
  || fail "h1 cannot reach h2"

echo "OK: all checks passed"

Cross-lab contamination

Symptoms:

  • Wrong SSH target (same hostname different lab)
  • Stale docker networks
  • IP confusion in your brain

Mitigations:

sudo containerlab inspect --all 2>/dev/null || true
docker ps --format 'table {{.Names}}\t{{.Status}}' | grep clab || true
# Only one “heavy” lab running when learning
sudo containerlab destroy -t old.clab.yml --cleanup

Use unique lab name: fields always.

Time hygiene

Put dates in journals; note Containerlab and image versions:

Date: 2026-08-04
containerlab: 0.xx.x
frr image: 10.2.1
kernel: $(uname -r)

Future breakage is often a version drift story.

Definition of done (lab)

  • Intent one-liner in README
  • addressing.md complete
  • topology deploys clean on fresh destroy
  • verify.sh green
  • One failure drill documented
  • Diagrams match YAML
  • Secrets absent
  • Image tags pinned
  • Committed to git

Predict → observe → fix: hygiene drill

  1. Predict: A peer can clone your lab folder and pass verify.sh without asking you questions.
  2. Observe: Remove your personal aliases; follow only README.
  3. Fix: Gaps become README bullets.
  4. Harden: Add up.sh/down.sh.
#!/usr/bin/env bash
# up.sh
set -euo pipefail
sudo containerlab deploy -t topology.clab.yml
./verify.sh
#!/usr/bin/env bash
# down.sh
set -euo pipefail
sudo containerlab destroy -t topology.clab.yml --cleanup

Collaboration norms (optional)

If sharing labs:

  • Prefer open images only
  • Include expected verify output sample
  • Note host requirements (RAM)
  • License your configs clearly (e.g. MIT notes)

Summary

  • Address first, deploy second
  • Name labs and nodes for humans and docker ps
  • Canonical directory: topology, configs, verify, journal, diagrams
  • Git is part of networking practice
  • One clean destroy/deploy is worth ten fragile demos
  • Definition of done prevents “almost labs”

Part checkpoint: topology-as-code should feel like muscle memory. Next part enters layer 2—Ethernet, VLANs, loops, aggregation, and failure drills.