All work
Deep dive · ContainerLab

A whole network from a text file.

Getting startedDigital twinTest before you deploy

The safest place to try a network change is not the production network. ContainerLab lets you describe a topology in a short text file, spin a whole network up on a laptop in seconds, break it, fix it, and throw it away. It is the tool we reach for whenever a change is too risky to test in production, which in critical networks is most of them.

This is a getting-started guide. By the end you will know what ContainerLab is, what a lab file looks like, the four commands that run the whole lifecycle, and how we use it to build a digital twin of a real network with MikroTik and OT gear. If you would rather click than read, our OT security lab runs in a browser and you can follow along.

What ContainerLab is

ContainerLab is an open-source tool that runs network labs based on containers. You write a topology file, it starts the nodes, wires them together with virtual cabling, and manages their lifecycle. Because the nodes are just containers, a lab starts in seconds and costs you nothing when it is not running.

It distinguishes three kinds of nodes. Containerised network operating systems run natively. Traditional VM-based systems can be containerised through the vrnetlab integration. And any Linux container can join in, which is how you add hosts, servers, attackers or, in our case, simulated PLCs.

Text-based

The whole topology is one YAML file you can read, diff and check into Git. The lab is the file.

Reproducible

Anyone who clones the repo gets the exact same network. No snowflake VMs, no "works on my machine".

Disposable

One command up, one command down. Break things on purpose, then start clean in seconds.

The shape of a lab

A lab is a .clab.yml file. It has a name, a set of nodes, and the links between them. Each node has a kind that tells ContainerLab how to run it. Here is a trimmed version of one of our own labs: a MikroTik firewall and switch, plus a simulated PLC as a Linux container.

ot-sec-segmented.clab.yml
# a network, described once
name: ot-sec-segmented

mgmt:
  network: ot-sec-segmented
  ipv4-subnet: 192.168.100.0/24

topology:
  defaults:
    kind: mikrotik_ros            # MikroTik RouterOS, via vrnetlab
    image: vrnetlab/mikrotik_routeros:7.20

  nodes:
    gw-firewall:                   # the segmentation gateway
      mgmt-ipv4: 192.168.100.11
      startup-config: configs/gw-firewall.rsc
    sw-dist:
      mgmt-ipv4: 192.168.100.12
    wago-plc2a:                    # a PLC, as a Linux container
      kind: linux
      image: ghcr.io/narrowin/ot-sec-lab-plc:latest

  links:
    # virtual cabling between node interfaces
    - endpoints: ["gw-firewall:eth1", "sw-dist:eth1"]
    - endpoints: ["sw-dist:eth2", "wago-plc2a:eth1"]

That is the whole idea. The nodes are your devices, the links are the cables, and kind is the only bit of magic: it lets a Nokia, an Arista, a Cisco, a MikroTik and a plain Linux box all sit in the same file and behave like the real thing. The example here uses MikroTik because it is what a lot of our work runs on, but ContainerLab supports a long catalogue of kinds, from Nokia, Arista, Cisco and Juniper to firewalls like Fortinet and Palo Alto.

Four commands, the whole lifecycle

Once the file exists, you barely need to remember anything. Install once, then deploy, look, connect, and destroy.

the full loop
# install ContainerLab (one line, RHEL or Debian based)
curl -sL https://containerlab.dev/setup | sudo -E bash -s "all"

# bring the lab up
clab deploy -t ot-sec-segmented.clab.yml

# see what is running: names, kinds, management IPs
clab inspect -t ot-sec-segmented.clab.yml

# jump onto a node, it is just SSH
ssh admin@192.168.100.11

# tear the whole thing down, leave nothing behind
clab destroy -t ot-sec-segmented.clab.yml

ContainerLab adds the nodes to your /etc/hosts, so you can also reach them by name, like ssh admin@clab-ot-sec-segmented-gw-firewall.

Worth knowing early

A few things that make ContainerLab pleasant to learn on, beyond the four commands.

VS Code extension

A live topology viewer, a visual editor and one-click console access, if you would rather not live in the terminal.

Wireshark on any link

Capture traffic on a single virtual cable and open it straight in Wireshark. Seeing the frames is half of learning a protocol.

Link impairment

Add latency, jitter or packet loss to a link with netem, to see how a design behaves on a bad day, not just a perfect one.

Why we build on it: the digital twin

In a critical network you cannot test a firewall change, a segmentation redesign or a firmware roll-out by trying it on the live plant. So we build a digital twin: a faithful copy of the real network, running in ContainerLab, that we can plan against, test on, and validate before a single change touches production.

01

Plan

Model the target network as a topology file. The design is now something you can run, not just a diagram.

02

Test

Deploy the twin, apply the change, break it on purpose. Failures happen here, where they are free.

03

Deploy

Roll the proven configuration out to the real devices, with the same automation you tested in the lab.

04

Validate

Compare the real network back against the twin, and keep the two in sync as the source of truth.

In a critical network, you don't get to experiment on the live plant. So we build a digital twin, make our mistakes there, and only deploy what we have already proven.
Tomáš Horyl, Senior Network & Security Engineer, narrowin
Tomáš Horyl · Building digital twins with MikroTik CHR, ContainerLab and Ansible

Bringing in VM-based devices

Many network operating systems, Cisco, Juniper, Palo Alto and others are provided as virtual machines. ContainerLab handles that through vrnetlab, which packages a VM as container and by this it behaves like any other node in the topology. MikroTik is our worked example here because plenty of our work runs on it, and the mikrotik_ros kind in the file above is exactly this in action.

One thing worth knowing: ContainerLab uses its own advanced fork of the original vrnetlab (srl-labs/vrnetlab). Images built with the upstream project will not work, so build from the fork.

With the MikroTik nodes running, we drive their configuration the same way we drive the real boxes: with Ansible. RouterOS has no Python interpreter, so we use the community.routeros modules over the API for structured, idempotent changes. That is the bridge between the twin and production, and it is open: our ansible-mikrotik collection is the same one we use on customer networks.

A real example: the OT security lab

To make this concrete, we maintain a full OT network security lab in ContainerLab, built together with SWITCH. It is a realistic industrial network: MikroTik firewall and switches, and simulated PLCs from WAGO, Bosch Rexroth, Schneider and ABB running a Codesys runtime, laid out across VLAN zones for hygiene, process, disposal and a control room.

It ships in two shapes from the same repo. A flat topology, the insecure baseline where everything can talk to everything, and a segmented topology with proper zones and a firewall between them. Swapping one for the other is a one-word change on the command line, which makes the value of segmentation something you can demonstrate rather than describe.

flat vs segmented, same lab
clab deploy -t ot-sec-flat.clab.yml         # everything can reach everything
clab deploy -t ot-sec-segmented.clab.yml    # zones, VLANs and a firewall

On top of the lab sits a set of hands-on exercises: VLAN discovery and traffic analysis, an ARP spoofing attack, spanning-tree behaviour, and more. Because the whole thing runs in GitHub Codespaces, a participant needs nothing but a browser to get a real, riggable network in front of them. This lab is the backbone of our OT security courses.

How to start, today

Two paths, depending on whether you want to install anything.

A

The no-install path

Open our Mikrotik-ansible lab in GitHub Codespaces and wait a few minutes for it to build. You get a full network in the browser, no Docker/Podman on your machine. Then run clab deploy -t mikrotik.clab.yml and you are in.

B

The local path

On any machine running Docker/Podman (Windows WSL, macOS, Linux), install with the one-liner above, grab a topology from the examples or write your own, and clab deploy. Start with two nodes and one link, then grow it.

C

Just try it

Deploy, connect to a node, change something, and clab destroy. The first time you rebuild a "broken" lab in ten seconds, the test-before-deploy habit tends to stick.

Beyond the intro

A digital twin of your network

Building a twin of a real, messy network is more involved than a two-node example: capturing the topology, getting the right images, and wiring up the automation that keeps the twin and production in sync. That is work we do with customers.

Talk to an engineer → Or take the OT security course built on this lab.

Frequently asked

How is ContainerLab different from GNS3 or EVE-NG?
All three build virtual network labs, but ContainerLab is container-first and file-driven. The lab is a text file you check into Git, it starts in seconds because most nodes are containers rather than full VMs, and it fits cleanly into automation and CI pipelines. VM-based routers still run when you need them, through vrnetlab, so you do not lose the heavy devices. The trade-off is that it is CLI-driven by nature, though the VS Code extension adds a visual layer.
Do I need powerful hardware?
For containerised nodes and Linux hosts, no. A laptop runs a sizeable lab comfortably. VM-based nodes like MikroTik CHR cost more memory each, so a large twin of VM routers needs a real server. A good rule: prototype small on your machine, run the full twin on a lab server.
Can I run MikroTik, Cisco or Nokia in the same lab?
Yes. That is the point of kinds. Containerised systems like Nokia SR Linux run natively, and VM-based systems like MikroTik RouterOS, Cisco and Juniper run through vrnetlab, all in one topology file. You can mix vendors freely and add plain Linux hosts alongside them.
Is ContainerLab production tooling or just for learning?
Both. It is excellent for teaching, which is why our courses run on it, but the same reproducibility makes it a serious pre-production tool: validating segmentation designs, rehearsing firmware upgrades and testing automation against a twin before any of it reaches the live network.
← All work