Release 0.83#
2026-11-06 · Full Changelog
ALE OmniSwitch vAOS#
The new ale_vaos kind adds support for Alcatel-Lucent Enterprise OmniSwitch virtual AOS 8.x as a vrnetlab-backed QEMU VM:
Data interfaces eth1 through eth10 map to vAOS ports 1/1/1 through 1/1/10, with eth11 and eth12 mapping to 1/1/29A and 1/1/30A. The launcher applies startup configuration over the serial console, configures the EMP management interface and saves the configuration. containerlab save writes the output of show configuration snapshot back to the node's startup-config file.
See the ALE OmniSwitch vAOS kind documentation for image acquisition, management access and configuration options.
Done in #3556 thanks to @Mathias-gt
Packet capture with containerlab capture#
The new capture command records packets from one or more lab link interfaces into a single pcapng file, or streams them live into Wireshark. It works with Docker, Podman and c9s, without installing capture tools in the nodes:
# watch both ends of a link live in Wireshark
containerlab capture --name srl \
--target srl1:e1-1 --target srl2:e1-1 -w - | wireshark -k -i -
# capture two interfaces for 30 seconds
containerlab capture -t srl.clab.yml \
--target srl1:e1-1,e1-2 --duration 30s -w srl.pcapng
# list capturable interfaces and their peers
containerlab capture --name srl --list
Interfaces can be selected by their name or topology alias, and every packet is associated with its <node>:<interface> name in the capture. Packets from all targets are merged in timestamp order. Captures can be bounded by duration or packet count, truncated to a snap length, and stopped cleanly with Ctrl+C while leaving a valid pcapng stream.
With Docker and Podman, containerlab captures through packet sockets in the node network namespaces; the command needs root, like deploy, but neither the host nor the node needs tcpdump. VLAN tags are preserved, interfaces that go down and back up remain captured, and a node restart is reattached with the missed interval reported as a gap. With c9s, the clabwire sidecar captures the packets, and long captures are chained without duplicating packets at the handover.
The inspect interfaces command now supports c9s as well, reporting lab interfaces with the same names, aliases and fields as the local runtimes.
Done in #3542 thanks to @FloSch62
c9s runtime improvements#
clabernetes 0.11 or newer required
The c9s runtime now requires clabernetes 0.11 or newer, which provides Node run state and the clabwire packet-capture contract. Containerlab checks the cluster's published Node schema before the first cluster operation and reports a clear error for older releases. Offline commands such as validate, deploy --emit-crs and file-based graph do not need cluster access.
Controller-managed lifecycle and persistent state#
stop, start and restart now ask the clabernetes controllers to manage a node through its Node resource instead of editing Deployments. A stopped node stays stopped across deploy/apply operations and starts with its updated definition when explicitly started. Nodes sharing a pod through network-mode: container: follow their primary node's lifecycle.
Persistent node volumes now survive a plain destroy, just as a local lab directory does. A subsequent deploy adopts the retained PersistentVolumeClaims and boots from the saved device state. destroy --cleanup removes the claims and managed namespace, while deploy --reconfigure and redeploy --cleanup also start from clean storage.
Docker-compatible inspection and events#
The c9s runtime now presents nodes using Docker's state and event vocabulary, allowing clients to consume local and cluster labs in the same way:
inspectreportscreated,runningandexitedstates, stable<namespace>/<lab>/<node>container IDs, the deployed topology file, and c9s-specific pod, container, Node UID, namespace, exposed-port and LoadBalancer fields in JSON output.- Container events use familiar actions such as
create,start,stop,die,destroyandhealth_status, with the corresponding containerlab labels and node attributes. - Interface events and
inspect interfacesexpose the node's lab links, management interface and loopback under their Docker-equivalent names, while hiding clabernetes' internal pod interfaces. - Events can be scoped to one lab or namespace, and
inspect --allanddestroy --allhonor the namespace override. graph --mermaid,--dot,--drawioand HTML with--offlinerender directly from a topology file without connecting to a cluster.
Done in #3539, #3541 and #3543, thanks to @FloSch62
Node logs and lab-runtime access#
The new logs command displays or follows a node's log with Docker, Podman and c9s. With c9s it reads the log of the node's primary device container:
Containerlab's Go API gained lab-runtime interfaces for locating nodes, opening interactive terminals, streaming logs, forwarding TCP ports, sampling CPU and memory usage, and capturing packets. The c9s implementation supports Kubernetes user impersonation per runtime or per call, applying the selected identity to REST requests, watches, logs, exec and port-forward connections. These APIs let services such as clab-api-server provide node access while Kubernetes RBAC continues to authorize each user.
Done in #3540 thanks to @FloSch62
Selecting the management network of mgmt-net links#
With multiple management networks, an extended mgmt-net link can now select its attachment network with the network key:
name: multi
mgmt:
- network: oob
ipv4-subnet: 172.31.10.0/24
- network: lab
ipv4-subnet: 172.31.20.0/24
bridge: br-lab
topology:
nodes:
r1:
kind: linux
image: alpine
mgmt-net: oob
links:
- type: mgmt-net
network: lab
endpoint:
node: r1
interface: eth1
host-interface: r1-eth1
Without network, the link keeps attaching to the first management network, preserving existing behavior. Unknown networks and networks not using the bridge driver are rejected.
Done in #3495 thanks to @FloSch62
MikroTik CHR improvements#
Up to 64 data interfaces on AMD64#
The mikrotik_chr kind places data NICs behind PCI bridges on AMD64, raising the supported interface limit from ether29 to ether64 while preserving interface numbering and MAC addresses. ARM64 continues to support up to ether30.
At high port counts, the launcher verifies that RouterOS discovered every data NIC and re-plugs missing NICs before reporting the node healthy. It repeats the check after RouterOS reboots itself, so interfaces are recovered after an in-router reboot as well. Interface limits are checked during deployment, with errors naming the offending topology interface.
Done in #3521 and #3568, thanks to @tomashoryl
Native management VRF and safer saves#
CHR management ether1 now lives in a native mgmt VRF, while data interfaces remain in main. SSH, HTTP/HTTPS, API, Winbox, Telnet and SNMP are bound to the management VRF, so lab routes no longer take management replies away from ether1. LLDP, CDP and MNDP are disabled on management ether1 by default while remaining enabled on data interfaces; a startup configuration can select another discovery policy.
Repeated configuration saves now omit an invalid empty default keymat-provider entry emitted by recent RouterOS versions, preserve intentional discovery and service VRF settings, and filter launcher-owned management configuration more reliably.
Recreate nodes using the previous management setup
The native VRF setup requires a fresh node container. Export the user configuration before recreating an existing node that uses the previous policy-routing setup; the launcher does not migrate it in place.
Done in #3545, #3546 and #3547, thanks to @mischadiehm
SR Linux links survive chassis reboots#
A reboot issued from within an SR Linux node, such as tools platform chassis reboot, now brings the node back with its links, saved configuration and management address intact.
Each nokia_srlinux node uses an internal <node-name>-netns holder container for its network namespace. The holder is hidden from inspect unless --all is set and is removed with the node. SR Linux nodes now default to the unless-stopped restart policy, while an explicitly configured policy is preserved. Nodes with a user-defined network-mode keep the previous behavior.
Done in #3567 thanks to @sacckth and @kaelemc
Per-node runtime deprecated#
The node-level runtime parameter is deprecated and will be removed in a future release. Mixing runtimes within a lab is not supported because management networking and lab-wide operations use the lab-wide runtime. Setting runtime on a node, group, kind or defaults block still works but emits a deprecation notice.
Use the global --runtime flag or CLAB_RUNTIME environment variable instead:
Done in #3527 thanks to @FloSch62
Miscellaneous#
tools snapshot savenow snapshots the deployed nodes of a partially built lab instead of failing on nodes whose containers were not created. #3537- Ciena SAOS nodes now stage a topology-supplied license file—provided as a path, URL or embedded blob—into
/config/licenseand expose it to the vrnetlab launcher throughSAOS_LICENSE_PATH. #3535 - SR-SIM finds its running instance using the full process command line, fixing discovery when FEX emulates SR OS on ARM hosts. #3538
containerlab eventsno longer misses interfaces created while a watcher starts. Failed netlink subscriptions are retried and re-established, with changes during the outage reconciled instead of silently ending interface reporting. #3532- FRR keeps
vtyshavailable throughout installation of the configuration-save wrapper, closing a startup race that could prevent the initial configuration from loading. #3555 - Cisco IOL now propagates a
mgmt-intfoverride to the VM launcher when a non-default management interface is selected. #3557 - Destroy and reconfigure operations reliably remove
vxlan-stitchhost interfaces by waiting for node deletion before host-link cleanup, including partial labs with no remaining containers. #3571 - Open vSwitch bridges no longer accumulate stale auto-generated
clab-*ports across deploy and redeploy operations when endpoint names require sanitized Linux interface names. Destroy also cleans up orphaned generated ports, andovs-vsctlcleanup calls time out instead of hanging whenovs-vswitchdis unavailable. #3573 - Empty node, kind and defaults definitions are handled correctly: nodes without a body inherit kind, group and configuration values, while empty kind or defaults blocks no longer cause panics. #3518
- Docker and Podman resolve
network-mode: container:targets correctly when a lab name contains the node name, fixing deployments of SR Linux nodes with their new network-namespace holders. #3577 - The go-jose dependency was updated to 4.1.8. #3569
- Documentation was clarified for OcNOS image requirements, HwSKU-dependent Dell SONiC interface names, and SR Linux platform licensing. #3552 #3553 #3575