DEV Community

iapilgrim
iapilgrim

Posted on

Beginner KVM Networking Lab with Alpine Linux (Step-by-Step)

πŸ§ͺ Beginner KVM Networking Lab with Alpine Linux (Step-by-Step)

In this tutorial, we will:

  • Download Alpine Linux ISO
  • Create alpine1 VM
  • 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
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

Move it to libvirt image directory:

sudo mv alpine-virt-3.19.1-x86_64.iso /var/lib/libvirt/images/
Enter fullscreen mode Exit fullscreen mode

Verify:

ls -lh /var/lib/libvirt/images/
Enter fullscreen mode Exit fullscreen mode

πŸ₯ˆ 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Important answers:

  • Hostname β†’ alpine1
  • Network β†’ eth0
  • IP β†’ dhcp
  • Proxy β†’ none
  • SSH server β†’ openssh
  • Disk β†’ sda
  • Install mode β†’ sys
  • Confirm erase β†’ y

After installation:

reboot
Enter fullscreen mode Exit fullscreen mode

🧹 Step 4 β€” Verify ISO Removed

On host:

sudo virsh domblklist alpine1
Enter fullscreen mode Exit fullscreen mode

You should see:

Target   Source
---------------------------------
hda      /var/lib/libvirt/images/alpine1.qcow2
Enter fullscreen mode Exit fullscreen mode

No ISO attached = good.


🌐 Step 5 β€” Verify Networking

Connect to console:

sudo virsh console alpine1
Enter fullscreen mode Exit fullscreen mode

Inside VM:

ip a
ip route
Enter fullscreen mode Exit fullscreen mode

You should see something like:

inet 192.168.121.100/24
default via 192.168.121.1
Enter fullscreen mode Exit fullscreen mode

Test internet:

ping 8.8.8.8
Enter fullscreen mode Exit fullscreen mode

If it works β†’ NAT is working πŸŽ‰


πŸ” Step 6 β€” Inspect Networking From Host

Check bridge:

ip a | grep virbr0
Enter fullscreen mode Exit fullscreen mode

You should see:

virbr0: 192.168.121.1/24
Enter fullscreen mode Exit fullscreen mode

Check bridge members:

brctl show
Enter fullscreen mode Exit fullscreen mode

You should see:

virbr0    vnetX
Enter fullscreen mode Exit fullscreen mode

Check NAT rules:

sudo iptables -t nat -L -n
Enter fullscreen mode Exit fullscreen mode

Look for:

MASQUERADE  192.168.121.0/24
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

This:

  • Copies disk safely
  • Generates new MAC address
  • Prevents network conflict

πŸ₯ˆ Step 8 β€” Start alpine2

sudo virsh start alpine2
sudo virsh console alpine2
Enter fullscreen mode Exit fullscreen mode

Inside alpine2:

ip a
Enter fullscreen mode Exit fullscreen mode

It should get a different IP:

alpine1 β†’ 192.168.121.100
alpine2 β†’ 192.168.121.101
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Step 9 β€” Test VM-to-VM Communication

From alpine1:

ping <alpine2-ip>
Enter fullscreen mode Exit fullscreen mode

Example:

ping 192.168.121.101
Enter fullscreen mode Exit fullscreen mode

This traffic:

  • Does NOT go through NAT
  • Stays inside virbr0 bridge
  • Pure Layer 2 switching

πŸ”Ž Observe Host Again

brctl show
Enter fullscreen mode Exit fullscreen mode

Now you will see:

virbr0
   β”œβ”€β”€ vnet10 (alpine1)
   └── vnet11 (alpine2)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

VM β†’ VM

VM1 β†’ vnetX β†’ virbr0 β†’ vnetY β†’ VM2
Enter fullscreen mode Exit fullscreen mode

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)