
Modern network automation requires safe, isolated environments for testing configurations and validating automation scripts. Google Cloud Platform combined with ContainerLab for Network Automation Labs provides an excellent foundation for creating these lab environments. In this post, we’ll walk through deploying a Google Cloud VM with nested virtualization support and installing ContainerLab.
Google Cloud offers several advantages for network automation testing:
Additionally, my personal opinion is that GCP is very intuitive, has great documentation, CLI tools and very responsive and easy to navigate UI.
Before starting, ensure you have:
gcloud CLI tool installed and configuredFirst, enable the necessary Google Cloud APIs:
gcloud services enable compute.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.comGoogle Cloud now provides a simpler method to enable nested virtualization without requiring custom images. Previously, you needed to create a custom image with the enable-vmx license, but Google now recommends using the --enable-nested-virtualization flag directly.
Nested virtualization allows us to run virtual network devices (like router and switch containers) inside our cloud VM. This is essential for ContainerLab, which relies on containerized network operating systems that need access to virtualization features.
Create your VM instance with nested virtualization enabled:
gcloud compute instances create containerlab-server \
--zone=us-central1-a \
--machine-type=n1-standard-4 \
--network-tier=PREMIUM \
--maintenance-policy=MIGRATE \
--can-ip-forward \
--provisioning-model=STANDARD \
--enable-nested-virtualization \
--min-cpu-platform="Intel Haswell" \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--boot-disk-size=100GB \
--boot-disk-type=pd-standard \
--boot-disk-device-name=containerlab-server \
--tags=containerlab-serverKey Parameters Explained:
--enable-nested-virtualization: Enables running VMs inside the VM--min-cpu-platform="Intel Haswell": Required for nested virtualization--machine-type=n1-standard-4: 4 vCPUs and 15GB RAM (adjust based on your needs)--boot-disk-size=100GB: Sufficient space for containers and network topologies--can-ip-forward: Enable IP Forwarding to use VPC routesConnect to your newly created instance:
gcloud compute ssh containerlab-server --zone=us-central1-aOnce connected, verify that nested virtualization is enabled:
# Check for VMX support
grep -c vmx /proc/cpuinfo
# Verify KVM support
sudo apt update
sudo apt install -y cpu-checker
kvm-okYou should see output confirming VMX support and KVM acceleration availability.
ContainerLab requires Docker to run network device containers:
# Install Docker using the official script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to the docker group
sudo usermod -aG docker $USER
# Start and enable Docker service
sudo systemctl start docker
sudo systemctl enable docker
# Log out and back in for group changes to take effect
exitReconnect to your VM and verify Docker installation:
gcloud compute ssh containerlab-server --zone=us-central1-a
docker --version
docker run hello-worldInstall the latest version of ContainerLab:
# Download and install ContainerLab
curl -sL https://containerlab.dev/setup | sudo -E bash -s "all"
# Verify installation
containerlab version
# Check available container images for network devices
containerlab inspect --allContainerLab supports various network operating systems including:

Create a simple test topology to verify everything works:
# Create a test directory
mkdir ~/clab-test
cd ~/clab-test
# Create a basic topology file
cat > simple-test.yml << 'EOF'
name: simple-test
topology:
nodes:
alpine1:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.1.1/24 dev eth1
alpine2:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.1.2/24 dev eth1
links:
- endpoints: ["alpine1:eth1", "alpine2:eth1"]
EOF
# Deploy the topology
sudo containerlab deploy -t simple-test.yml
# Verify deployment
sudo containerlab inspect -t simple-test.yml
# Test connectivity between containers
sudo docker exec clab-simple-test-alpine1 ping -c 3 172.20.20.3
# Access container shell
sudo docker exec -it clab-simple-test-alpine1 sh
# Clean up when done
sudo containerlab destroy -t simple-test.ymlThis test creates two Alpine Linux containers connected via a virtual link and verifies they can communicate.
Example output of the inspect command after deployment:
$ sudo containerlab inspect -t simple-test.yml
16:03:28 INFO Parsing & checking topology file=simple-test.yml
╭──────────────────────────┬───────────────┬─────────┬───────────────────╮
│ Name │ Kind/Image │ State │ IPv4/6 Address │
├──────────────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-simple-test-alpine1 │ linux │ running │ 172.20.20.2 │
│ │ alpine:latest │ │ 3fff:172:20:20::2 │
├──────────────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-simple-test-alpine2 │ linux │ running │ 172.20.20.3 │
│ │ alpine:latest │ │ 3fff:172:20:20::3 │
╰──────────────────────────┴───────────────┴─────────┴───────────────────╯Testing connectivity and shell access:
$ sudo docker exec clab-simple-test-alpine1 ping -c 3 172.20.20.3
PING 172.20.20.3 (172.20.20.3): 56 data bytes
64 bytes from 172.20.20.3: seq=0 ttl=64 time=0.133 ms
64 bytes from 172.20.20.3: seq=1 ttl=64 time=0.086 ms
64 bytes from 172.20.20.3: seq=2 ttl=64 time=0.075 ms$ sudo docker exec -it clab-simple-test-alpine1 sh
/ # route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.20.20.1 0.0.0.0 UG 0 0 0 eth0
172.20.20.0 * 255.255.255.0 U 0 0 0 eth0
192.168.1.0 * 255.255.255.0 U 0 0 0 eth1
/ # exitHistorical Context: You may encounter older tutorials that create custom images with VMX licenses. Here’s why this was necessary and why it’s no longer recommended:
# Legacy method (NOT recommended for new deployments)
gcloud compute images create nested-ubuntu-jammy \
--source-image-family=ubuntu-2204-lts \
--source-image-project=ubuntu-os-cloud \
--licenses https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmxWhy the VMX license was needed: Google Cloud’s hypervisor doesn’t expose Intel VT-x virtualization instructions to VMs by default. The enable-vmx license instructed the hypervisor to enable these hardware virtualization features, allowing nested VMs to run.
Modern approach advantage: The --enable-nested-virtualization flag achieves the same result without requiring custom image creation, simplifying deployment and maintenance.
For optimal performance in your network labs:
htop and docker stats to monitor resource consumptionIssue: “KVM acceleration cannot be used”
Solution: Ensure you selected Intel Haswell or newer CPU platform and enabled nested virtualization
Issue: Docker permission denied
Solution: Ensure user is added to docker group and you’ve logged out/in
Issue: ContainerLab deployment fails
Solution: Check available disk space and ensure Docker daemon is running
When running network labs in the cloud:
With your Google Cloud VM and ContainerLab properly configured, you’re ready to:
In our next post, we’ll explore deploying a NetOps server environment and enabling advanced routing features for realistic network automation testing.
To keep costs under control:
This foundation provides a robust platform for network automation development and testing. The combination of Google Cloud’s infrastructure and ContainerLab’s networking capabilities creates an ideal environment for modern network operations teams.
Related Posts:
At Netodata, we specialize in helping organizations build robust network automation practices. Contact us to learn how we can help you implement similar solutions in your environment.
