-
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 scenario 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-bridgeThis writes setup-bridges.sh beside the topology, holding one line per bridge.
A lab whose bridges are provisioned some other way — Ansible, sudo rules, a
different OVS database — leaves the use: line out and gets no script. The
entry script deletes them again when the lab is destroyed.
When a scenario 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:
- If
startupexists and is non-empty →execsection is generated - If
startupis missing or empty →execsection is omitted
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]After generating files with dot2net:
# Generate configuration files
dot2net build -c input.yaml input.dot
# Deploy the lab
sudo containerlab deploy -t topo.yaml
# Destroy the lab
sudo containerlab destroy -t topo.yaml- Module System - How modules work
- File Output - File generation and bind mounts
- Module: TiNET - Alternative container-based platform
- Module: FRR - FRR configuration helpers