π§ͺ Beginner KVM Networking Lab with Alpine Linux (Step-by-Step)
In this tutorial, we will:
- Download Alpine Linux ISO
- Create
alpine1VM - Install Alpine to disk
- Verify NAT networking
- Clone and create
alpine2 - Test VM-to-VM communication
All using KVM + libvirt on Ubuntu.
We use:
Alpine Linux
because it is extremely lightweight and perfect for networking labs.
π§± Lab Architecture
We will use the default libvirt NAT network:
Host (Ubuntu)
βββ virbr0 (192.168.121.1/24)
βββ alpine1
βββ alpine2
- VMs can talk to each other
- VMs can access internet via NAT
- VMs are not reachable from outside
π₯ Step 1 β Download Alpine ISO
Download Alpine (virt edition recommended for KVM):
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-virt-3.19.1-x86_64.iso
Move it to libvirt image directory:
sudo mv alpine-virt-3.19.1-x86_64.iso /var/lib/libvirt/images/
Verify:
ls -lh /var/lib/libvirt/images/
π₯ Step 2 β Create alpine1 VM
Create a 4GB disk and attach ISO:
sudo virt-install \
--name alpine1 \
--memory 256 \
--vcpus 1 \
--disk path=/var/lib/libvirt/images/alpine1.qcow2,size=4,format=qcow2 \
--cdrom /var/lib/libvirt/images/alpine-virt-3.19.1-x86_64.iso \
--os-variant generic \
--network network=default \
--graphics none \
--console pty,target_type=serial
Explanation:
| Option | Purpose |
|---|---|
--memory 256 |
Lightweight VM |
--disk size=4 |
Create 4GB disk |
--network default |
Attach to NAT bridge |
--graphics none |
CLI only |
--console |
Serial console access |
π₯ Step 3 β Install Alpine Inside VM
Inside VM:
setup-alpine
Important answers:
- Hostname β
alpine1 - Network β
eth0 - IP β
dhcp - Proxy β
none - SSH server β
openssh - Disk β
sda - Install mode β
sys - Confirm erase β
y
After installation:
reboot
π§Ή Step 4 β Verify ISO Removed
On host:
sudo virsh domblklist alpine1
You should see:
Target Source
---------------------------------
hda /var/lib/libvirt/images/alpine1.qcow2
No ISO attached = good.
π Step 5 β Verify Networking
Connect to console:
sudo virsh console alpine1
Inside VM:
ip a
ip route
You should see something like:
inet 192.168.121.100/24
default via 192.168.121.1
Test internet:
ping 8.8.8.8
If it works β NAT is working π
π Step 6 β Inspect Networking From Host
Check bridge:
ip a | grep virbr0
You should see:
virbr0: 192.168.121.1/24
Check bridge members:
brctl show
You should see:
virbr0 vnetX
Check NAT rules:
sudo iptables -t nat -L -n
Look for:
MASQUERADE 192.168.121.0/24
This rule allows VM internet access.
π₯ Step 7 β Clone alpine1 to Create alpine2
Do NOT manually copy disk.
Use virt-clone:
sudo virt-clone \
--original alpine1 \
--name alpine2 \
--file /var/lib/libvirt/images/alpine2.qcow2
This:
- Copies disk safely
- Generates new MAC address
- Prevents network conflict
π₯ Step 8 β Start alpine2
sudo virsh start alpine2
sudo virsh console alpine2
Inside alpine2:
ip a
It should get a different IP:
alpine1 β 192.168.121.100
alpine2 β 192.168.121.101
π§ͺ Step 9 β Test VM-to-VM Communication
From alpine1:
ping <alpine2-ip>
Example:
ping 192.168.121.101
This traffic:
- Does NOT go through NAT
- Stays inside virbr0 bridge
- Pure Layer 2 switching
π Observe Host Again
brctl show
Now you will see:
virbr0
βββ vnet10 (alpine1)
βββ vnet11 (alpine2)
Each VM gets its own tap device.
π¦ What You Built
You now have:
β 2 lightweight VMs (256MB each)
β DHCP working
β NAT outbound internet
β VM-to-VM communication
β Real bridge networking
β Understanding of packet flow
π§ Packet Flow Explained
VM β Internet
VM β vnetX β virbr0 β host β iptables MASQUERADE β Internet
VM β VM
VM1 β vnetX β virbr0 β vnetY β VM2
No NAT involved.
π Resource Usage
Each Alpine VM:
- 256MB RAM
- 4GB disk
- ~60MB ISO
- Very fast boot
You can easily run 6β8 VMs on a normal 8GB machine.
π Next Phase (Preview)
In the next phase, we will:
- Create isolated network (no NAT)
- Create internal bridge
- Make one VM act as router
- Add static routes
- Simulate multi-subnet enterprise network
If you want, I can now generate:
- Phase 2 blog: Custom libvirt network (no NAT)
- Phase 3 blog: Multi-subnet routing lab
- Full 5-VM topology diagram
Youβre officially past beginner level now π₯

Top comments (0)