Build Routing Labs with Containerlab on Gozunga Cloud
Build repeatable routing and network scenarios in minutes with Containerlab, Gozunga Cloud VMs, and private cloud networks.
Network labs do not need a rack, a pile of routers, or a weekend of recabling. With a Gozunga Cloud VM, Containerlab, and Gozunga Cloud networking, you can create isolated routing scenarios on demand, connect them to real cloud networks, and delete every resource when the test is finished.
- What You Will Build
- Why Use Gozunga Cloud for Network Labs
- Choose a Lab Platform
- Choose the VM Network
- Create the Lab VM
- Install Containerlab
- Create a Three-Router BGP Lab
- Deploy and Verify the Topology
- Connect the Lab to Gozunga Cloud Networks
- Scenarios to Try
- Security and Cost Controls
- Clean Up
1. What You Will Build
This guide uses a single Gozunga Cloud VM to host a small Containerlab topology: three virtual routers running FRRouting (FRR). The topology has two edge routers and a transit router, which makes it a useful foundation for BGP policy and failure-testing exercises.
The lab VM needs one Gozunga Cloud network connection for SSH and package downloads. The routers and links in this starter scenario stay inside the VM; add a separate Gozunga Cloud transit network only when you want to connect the lab to application VMs, test subnets, or another lab VM. The result is a practical split between:
| Layer | Purpose |
|---|---|
| Gozunga Cloud networking | Isolated project networks, routers, security groups, and VM-to-VM connectivity |
| Lab host VM | Docker and Containerlab runtime |
| Containerlab topology | The routers, links, protocols, and failures you want to test |
Containerlab is ideal when the platforms you need are available as containers. If you need appliance images or a graphical topology editor, see Choose a Lab Platform.
2. Why Use Gozunga Cloud for Network Labs
A cloud lab is especially useful when a scenario needs to be repeatable or shared. Instead of preserving a one-off device configuration, keep the topology YAML and router configuration in Git. A new lab becomes a new VM plus one deploy command.
Gozunga Cloud provides the cloud side of the exercise:
- Private project networks let you isolate a lab from your public workloads.
- Routers and subnets let you model multiple sites or application segments.
- Security groups make exposure explicit: allow SSH to the host, and only open lab services when you need them.
- Additional VM interfaces let a lab host connect to more than one Gozunga Cloud network.
- Snapshots and volumes let you preserve a known-good host or retain captures and configuration between experiments.
đź’ˇ Pro Tip: Treat the Gozunga Cloud network as the underlay and the Containerlab topology as the overlay. This keeps cloud connectivity simple while allowing you to iterate on routing protocols quickly inside the lab.
3. Choose a Lab Platform
There are two common ways to run virtual networking scenarios in the cloud:
| Platform | Best for | Considerations |
|---|---|---|
| Containerlab | FRR, SR Linux, Arista cEOS, Nokia SR OS, and other containerized network operating systems | Fast startup, topology-as-code, low overhead; image availability and licensing vary by vendor |
| EVE-NG | Mixed appliance images, QEMU-based virtual routers/firewalls, and a browser-based lab UI | Familiar visual workflow; requires more CPU, RAM, disk, and may require nested virtualization support |
This article uses Containerlab because it works well on a standard Linux cloud VM and makes the entire topology easy to review in source control. EVE-NG is a valid alternative when your scenario depends on QEMU images. Before building an EVE-NG lab, confirm the instance size and nested-virtualization requirements with the image vendor and your cloud environment.
4. Choose the VM Network
For the starter topology, you do not need to create an Gozunga Cloud private network. Containerlab creates the router containers and virtual links inside the lab-host VM, so the three-router BGP scenario is entirely self-contained.
Attach the VM to the Internet network for remote SSH access and for downloading packages and container images during first boot. In the Gozunga Cloud Portal, go to Networking → Security Groups, create a lab-host security group, and add only the rules you need:
- Inbound TCP/22 from your administration IP address for SSH.
- Inbound ICMP from approved addresses if you want basic reachability troubleshooting.
- No inbound access to the Docker API or router management ports from the public Internet.
A dedicated private network, such as netlab-transit, is optional. Add it later only when the lab needs to exchange traffic with another cloud VM or model a multi-network Gozunga Cloud scenario; Connect the Lab to Gozunga Cloud Networks covers that pattern.
⚠️ Security note: Network operating systems often expose management services by default. Do not publish a lab subnet or a router's management address with a broad
0.0.0.0/0rule unless it is intentionally temporary and protected by strong credentials.
5. Create the Lab VM
The easiest way to launch the host is through the Gozunga Cloud Portal:
- Select your project, then open Servers and click Create a Cloud Server.
- Choose Ubuntu 26.04.
- Select General Purpose and choose
gp.small1or larger. The tested three-router FRR lab runs ongp.small1; larger labs need more RAM and storage. - Choose the Internet network and select your SSH key pair.
- Add the lab-host security group you created in the previous section.
- Under Cloud Configuration, paste the
networking/ubuntu-containerlab.yamlconfig from the Gozunga Cloud-Init Collection. - Name the VM and click Create Server. Once it is active, allow cloud-init a few minutes to finish before connecting.
If you prefer automation, use the OpenStack CLI after sourcing your project OpenRC file:
openstack server create \
--image ubuntu-26.04 \
--flavor gp.small1 \
--key-name my-ssh-key \
--network Internet \
--security-group netlab-host \
--wait \
clab-host-01
If you later add a private test network, attach it as a second interface while keeping the Internet interface for management:
openstack server add network clab-host-01 netlab-transit
Check the assigned addresses:
openstack server show clab-host-01 -c addresses -c status
Connect using the address reachable from your workstation:
ssh ubuntu@<lab-host-ip>
6. Install Containerlab
Containerlab uses Docker to create the virtual links between nodes. For a fresh Gozunga Cloud VM, use the Ubuntu Containerlab cloud-init config from the Gozunga Cloud-Init Collection and supply it as Cloud Configuration at launch. It installs Docker and Containerlab, enables IP forwarding for approved lab-to-test-network scenarios, and pre-pulls the FRR image used below. The official installation documentation is the best source for current package and platform requirements.
sudo apt update
sudo apt install -y ca-certificates curl docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"
bash -c "$(curl -sL https://get.containerlab.dev)"
Log out and back in so the Docker group membership takes effect, then verify both tools:
docker version
containerlab version
đź’ˇ Pro Tip: Pin the Containerlab version in a team runbook or cloud-init script once you have a known-good lab environment. That makes recreating a topology more predictable.
7. Create a Three-Router BGP Lab
Create a working directory and save the following as bgp-lab.clab.yml:
mkdir -p ~/netlabs/bgp-lab
cd ~/netlabs/bgp-lab
nano bgp-lab.clab.yml
name: bgp-lab
topology:
nodes:
edge-1:
kind: linux
image: quay.io/frrouting/frr:10.2.1
binds:
- edge-1/daemons:/etc/frr/daemons
- edge-1/frr.conf:/etc/frr/frr.conf
rr-1:
kind: linux
image: quay.io/frrouting/frr:10.2.1
binds:
- rr-1/daemons:/etc/frr/daemons
- rr-1/frr.conf:/etc/frr/frr.conf
edge-2:
kind: linux
image: quay.io/frrouting/frr:10.2.1
binds:
- edge-2/daemons:/etc/frr/daemons
- edge-2/frr.conf:/etc/frr/frr.conf
links:
- endpoints: ["edge-1:eth1", "rr-1:eth1"]
- endpoints: ["rr-1:eth2", "edge-2:eth1"]
Enable the FRR daemons on each node. The following creates the same minimal daemons file for all three routers:
for node in edge-1 rr-1 edge-2; do
mkdir -p "$node"
cat > "$node/daemons" <<'EOF2'
zebra=yes
bgpd=yes
EOF2
done
Now add the routing configuration. rr-1 is the transit router between the two edge routers:
cat > edge-1/frr.conf <<'EOF'
frr defaults traditional
hostname edge-1
interface eth1
ip address 10.0.12.1/30
ip route 192.0.2.0/24 Null0
router bgp 65001
no bgp ebgp-requires-policy
bgp router-id 10.255.0.1
neighbor 10.0.12.2 remote-as 65000
network 192.0.2.0/24
!
EOF
Create the remaining configuration files. rr-1 is a transit router in this initial eBGP topology; you can later evolve it into a route reflector by adding iBGP clients.
cat > rr-1/frr.conf <<'CONFIG_END'
frr defaults traditional
hostname rr-1
interface eth1
ip address 10.0.12.2/30
interface eth2
ip address 10.0.23.1/30
router bgp 65000
no bgp ebgp-requires-policy
bgp router-id 10.255.0.2
neighbor 10.0.12.1 remote-as 65001
neighbor 10.0.23.2 remote-as 65002
!
CONFIG_END
cat > edge-2/frr.conf <<'CONFIG_END'
frr defaults traditional
hostname edge-2
interface eth1
ip address 10.0.23.2/30
ip route 198.51.100.0/24 Null0
router bgp 65002
no bgp ebgp-requires-policy
bgp router-id 10.255.0.3
neighbor 10.0.23.1 remote-as 65000
network 198.51.100.0/24
!
CONFIG_END
This topology is deliberately small: each edge originates a documentation-only test prefix, and the transit router exchanges the routes between them. The ip route … Null0 lines put those prefixes into the local routing table so FRR can advertise them, while no bgp ebgp-requires-policy keeps this introductory eBGP lab from requiring export policies. Use the Containerlab documentation for more complete examples and node kinds.
8. Deploy and Verify the Topology
Deploy the topology from the directory containing the YAML file:
sudo containerlab deploy -t bgp-lab.clab.yml
Containerlab prints the node names and management addresses it created. Inspect the resulting containers:
sudo containerlab inspect -t bgp-lab.clab.yml
sudo docker ps --format 'table {{.Names}}\t{{.Status}}'
Open an FRR shell on a router and inspect BGP after the sessions establish:
sudo docker exec -it clab-bgp-lab-edge-1 vtysh
show ip bgp summary
show ip route bgp
The fast iteration loop is the reason Containerlab is effective for training and validation: update the YAML or FRR configuration, destroy the topology, and deploy it again. The host VM and its Gozunga Cloud network remain available for the next run.
9. Connect the Lab to Gozunga Cloud Networks
Use Gozunga Cloud networks to give the lab a real endpoint outside its containers. In the Gozunga Cloud Portal, open Networking → Networks and create a private network such as netlab-transit with a subnet such as 10.50.0.0/24. Attach it to a Gozunga Cloud router only if the scenario needs to reach another network.
Then attach netlab-transit to the lab host as a second interface and connect an application test VM to the same network. This makes the host the controlled point where you originate, advertise, filter, or observe routes.
For example, launch a small test endpoint with the OpenStack CLI:
openstack server create \
--image ubuntu-26.04 \
--flavor gp.nano1 \
--key-name my-ssh-key \
--network netlab-transit \
--security-group netlab-test \
--wait \
app-test-01
You can add a Containerlab link from an edge router to a host interface or bridge. Keep this integration explicit: document which interface, subnet, and route belongs to the cloud underlay versus the lab topology. When forwarding traffic between namespaces, containers, and a Gozunga Cloud VM interface, you may need to enable IP forwarding on the host and add specific routes on the test VM.
sudo sysctl -w net.ipv4.ip_forward=1
For advanced designs—such as routing traffic on behalf of other VMs—review Gozunga Cloud port-security and anti-spoofing behavior first. Use a dedicated test network and make only the minimum port-security changes required by the scenario. Do not weaken protections on shared or production networks.
10. Scenarios to Try
Once the base lab works, change the topology rather than rebuilding hardware. Here are useful exercises:
- BGP policy testing: advertise test prefixes, filter a route, prepend an AS path, and verify the selected path.
- OSPF convergence: add a triangular link, change interface cost, then stop a link and measure reconvergence.
- Route reflector behavior: add clients, test cluster IDs, and verify that reflected routes follow the expected rules.
- VRFs and tenant segmentation: create separate VRFs for simulated customers and leak only selected routes between them.
- Firewall insertion: place a virtual firewall between an edge router and a test VM, then validate permitted and denied flows.
- Multi-site design: deploy a second lab host on another Gozunga Cloud private network and use a tunnel or routed transit segment between sites.
- Failure drills: stop a container, withdraw a prefix, or apply a restrictive security-group rule to confirm your monitoring and runbooks catch the condition.
Keep the topology definition, FRR configurations, and expected test results in the same repository. A pull request then becomes a reviewable network change, not a screenshot of a console session.
11. Security and Cost Controls
Labs are intentionally flexible, which makes guardrails important:
- Limit SSH security-group rules to trusted source addresses.
- Use SSH keys and disable password authentication on the lab host.
- Store vendor images and registry credentials outside the topology file; never commit secrets.
- Use project quotas and a dedicated project for training or experimentation when possible.
- Snapshot a clean host before a workshop, but delete unneeded VMs, volumes, floating IPs, and routers when finished.
- Check the licensing terms for every network operating system image you use.
⚠️ Important: A lab can generate real traffic and consume real resources. Do not bridge an experimental topology into production without an approved design, explicit route filtering, and an understanding of the Gozunga Cloud security controls involved.
12. Clean Up
Destroy the Containerlab topology when you are finished:
cd ~/netlabs/bgp-lab
sudo containerlab destroy -t bgp-lab.clab.yml
When the entire exercise is complete, remove the cloud resources as well:
openstack server delete --wait app-test-01 clab-host-01
Delete any lab-only routers, networks, floating IPs, and volumes from the Gozunga Cloud Portal after confirming they are no longer needed. Because the lab is defined in YAML and configuration files, you can recreate it later without leaving idle infrastructure running.
Ready to start? Create your Gozunga Cloud account and use the included $100 in free credits to build your first routing scenario.