-
Notifications
You must be signed in to change notification settings - Fork 1
Module Containerlab
This page describes the Containerlab module for dot2net.
Containerlab is a container-based networking lab platform that enables rapid deployment of network topologies using Docker containers. It supports various network operating systems (Nokia SR Linux, Arista cEOS, FRR, etc.) and provides a simple YAML-based topology definition.
- Official Website: https://containerlab.dev/
- GitHub: https://github.com/srl-labs/containerlab
The Containerlab module generates topo.yaml, the topology definition file for Containerlab:
name: mylab
topology:
nodes:
r1:
kind: linux
image: quay.io/frrouting/frr:8.5.4
network-mode: none
binds:
- r1/etc/frr/frr.conf:/etc/frr/frr.conf
- r1/etc/frr/daemons:/etc/frr/daemons
exec:
- vtysh -b
links:
- endpoints: ["r1:eth0", "r2:eth0"]| Section | Source | Description |
|---|---|---|
name |
YAML name field |
Lab name |
nodes |
DOT nodes | Node definitions with kind, image, binds, exec |
links |
DOT edges | Network connections between nodes |
-
binds: Automatically generated from FileDefinitions that have
pathset -
exec: Generated from user-defined
startupconfig block - links: Generated from DOT edge definitions
Generated nodes carry network-mode: none, so a lab has only the links its
topology describes. containerlab's management network is convenient — clab exec, the clab-* names — but it is also a second path between every pair of
nodes, and a reachability test that should have failed can pass through it
without anyone noticing. TiNET runs its nodes with --net none and Kathara
gives them no management network either, so this also brings the three into
line.
module_config:
containerlab:
management_network: true # put it backTurning it back on means naming the data interfaces something other than
eth0, which containerlab keeps for the management interface. dot2net says so
while generating rather than letting containerlab refuse at deploy time.
containerlab refuses to deploy while a bridge its topology names does not exist. A topology that uses a shared medium provided by the platform can pull in a ready-made class, and the module writes the script that makes them:
nodeclass:
- name: platform_sw
deploy: platform
use: [clabOvsBridgeSetup] # or clabLinuxBridgeSetup
values:
kind: ovs-bridgeThe entry script then makes the bridges on deploy and removes them on
destroy, so a lab that needs bridges comes up from the generated files with
nothing done by hand. Running containerlab deploy yourself skips that step,
and containerlab then refuses to deploy — its check for a named bridge runs
before any stage, so nothing inside the lab can make one.
The classes write this into worker_deploy and worker_destroy, the blocks any
topology can use to run commands on the machine — see
Machine-side hooks. A lab whose bridges
are provisioned some other way — Ansible, sudo rules, a different OVS database —
leaves the use: line out and writes its own worker_deploy instead, or
nothing at all.
When a topology declares worker groups, the topology file becomes
group-scoped: each machine gets its own, holding its nodes and the links it can
wire itself. A link that leaves a machine appears in neither, since no topology
file can make it — see
Placing nodes on machines.
Bind paths are stated from the machine's directory, because containerlab resolves a relative bind against the directory holding the topology file.
Each node deployed as a container must have both. A node with deploy: platform
— a bridge, a shared medium the platform provides rather than runs — needs only
kind: nothing is deployed for it, so there is no image to name.
| Parameter | Description | Example |
|---|---|---|
image |
Container image | quay.io/frrouting/frr:8.5.4 |
kind |
Containerlab node kind |
linux, srl, ceos
|
Define these in your NodeClass:
nodeclass:
- name: router
interface_policy: [p2p] # addresses for this node's interfaces
params: [lo] # and ip_loopback for the node itself
values:
image: quay.io/frrouting/frr:8.5.4
kind: linuxThe startup config block defines commands to run inside the container. This is used to generate the exec section in topo.yaml.
nodeclass:
- name: router
config:
- name: startup
template:
- "vtysh -b"
- "ip addr add {{ .ip_loopback }}/32 dev lo"Behavior: a topology must define a startup template somewhere — containerlab
reports node config templates named startup is required without one. A node
whose startup comes out empty gets no exec: section, which is where this
differs from TiNET: it writes a node_configs entry either way.
Files with path defined in FileDefinition are automatically mounted into containers:
file:
- name: frr.conf
path: /etc/frr/frr.conf # This triggers bind mount generation
- name: daemons
path: /etc/frr/daemonsGenerated binds:
binds:
- r1/etc/frr/frr.conf:/etc/frr/frr.conf
- r1/etc/frr/daemons:/etc/frr/daemonsname: ospf_lab
module:
- containerlab
- frr
file:
- name: frr.conf
path: /etc/frr/frr.conf
- name: daemons
path: /etc/frr/daemons
layer:
- name: ip
default_connect: true
policy:
- name: p2p
range: 10.0.0.0/16
prefix: 30
- name: lo
type: loopback
range: 10.255.0.0/24
nodeclass:
- name: router
interface_policy: [p2p] # addresses for this node's interfaces
params: [lo] # and ip_loopback for the node itself
values:
image: quay.io/frrouting/frr:8.5.4
kind: linux
config:
- file: frr.conf
template:
- "hostname {{ .name }}"
- "!"
- "router ospf"
- " router-id {{ .ip_loopback }}"
- file: daemons
sourcefile: ./daemons
- name: startup
template:
- "vtysh -b"graph {
r1 [class="router"]
r2 [class="router"]
r1 -- r2
}name: ospf_lab
topology:
nodes:
r1:
kind: linux
image: quay.io/frrouting/frr:8.5.4
network-mode: none
binds:
- r1/etc/frr/frr.conf:/etc/frr/frr.conf
- r1/etc/frr/daemons:/etc/frr/daemons
exec:
- vtysh -b
r2:
kind: linux
image: quay.io/frrouting/frr:8.5.4
network-mode: none
binds:
- r2/etc/frr/frr.conf:/etc/frr/frr.conf
- r2/etc/frr/daemons:/etc/frr/daemons
exec:
- vtysh -b
links:
- endpoints: [r1:eth0, r2:eth0]dot2net build -c input.yaml input.dot
sudo containerlab deploy -t topo.yaml
sudo containerlab destroy -t topo.yaml --cleanupmodule_config.containerlab.generate_scripts: true (off by default) writes
containerlab.sh beside the generated topo.yaml:
sudo ./containerlab.sh deploy
sudo ./containerlab.sh exec r1 vtysh -c "show ip ospf neighbor"
sudo ./containerlab.sh destroyIts destroy does more than containerlab's own: it runs the lab's teardown
commands, copies out the files it collects, destroys the lab, and runs the
lab's worker_destroy commands — reporting any step that failed. A topology
that collects files or has teardown commands needs the script for them to
happen at all. See Command Reference.
- Module System - How modules work
- File Output - File generation and bind mounts
- Module: TiNET - Alternative container-based platform
- Module: FRR - FRR configuration helpers