How to Establish Network Communication Between KVM VMs and Docker Containers on the Same Host


2 views

When running both KVM virtual machines and Docker containers on the same Debian host, establishing direct network communication between them presents unique challenges. The default networking configurations create isolated environments that don't automatically interoperate.

# Current bridge configuration
brctl show
bridge name         bridge id           STP enabled interfaces
br-f9f3ccd64037     8000.0242b3ebe3a0   no      
docker0             8000.024241f39b89   no      veth35454ac
virbr0              8000.525400566522   yes     virbr0-nic

This configuration allows VMs to access Docker containers through the host's network stack:

# To configure Docker to use the KVM default bridge
{
  "bridge": "virbr0",
  "iptables": false
}

With this setup, VMs can directly access containers via their internal IPs (e.g., 172.17.0.2).

When using macvtap in bridge mode, the host becomes invisible to VMs due to MAC address conflicts. The workaround is to:

# Create a separate bridge for Docker
sudo brctl addbr docker-bridge
sudo ip addr add 192.168.100.1/24 dev docker-bridge
sudo ip link set docker-bridge up

# Configure Docker to use this bridge
{
  "bip": "192.168.100.1/24",
  "fixed-cidr": "192.168.100.0/24",
  "bridge": "docker-bridge"
}

For a database container with port mapping:

# Run PostgreSQL container with host network
docker run --name db \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -p 5432:5432 \
  --network=host \
  postgres

VMs can now connect via the host's IP address on port 5432.

While unconventional, running Docker inside a KVM VM provides complete network isolation:

# Create a dedicated VM for Docker
virt-install \
  --name docker-vm \
  --ram 4096 \
  --disk path=/var/lib/libvirt/images/docker-vm.qcow2,size=20 \
  --vcpus 2 \
  --os-type linux \
  --os-variant debian9 \
  --network bridge=virbr0 \
  --graphics none \
  --console pty,target_type=serial \
  --import

1. For development environments, use Option 1 (NAT bridge) for simplicity
2. For production, consider dedicated network bridges with proper firewall rules
3. Document all network changes for future maintenance
4. Test connectivity between all components before deploying applications


When running both KVM virtual machines and Docker containers on the same Debian host, networking between them can be challenging. The default configurations create isolated networks:

# Current bridge configuration
brctl show
bridge name         bridge id           STP enabled interfaces
br-f9f3ccd64037     8000.0242b3ebe3a0   no      
docker0             8000.024241f39b89   no      veth35454ac
virbr0              8000.525400566522   yes     virbr0-nic

With the default NAT configuration (virbr0), VMs can access Docker containers through the host's network stack:

# From VM, access container by its IP
ping 172.17.0.2

# To make this persistent, add a route in the VM:
ip route add 172.17.0.0/16 via 192.168.122.1

When using macvtap in bridge mode, VMs get direct LAN access but lose host connectivity:

# Common issue with macvtap
ping 192.168.1.100 (host IP)
Destination Host Unreachable

The most elegant solution is to configure Docker to use libvirt's bridge:

# /etc/docker/daemon.json
{
  "bridge": "virbr0",
  "fixed-cidr": "192.168.122.0/24",
  "iptables": false
}

After modifying the config, restart Docker:

systemctl restart docker

For production environments, consider running Docker inside a dedicated VM:

# Create a dedicated VM for Docker
virt-install \
  --name docker-vm \
  --ram 4096 \
  --disk size=20 \
  --vcpus 2 \
  --network bridge=virbr0 \
  --graphics none \
  --os-type linux \
  --os-variant debian9
  • Verify iptables rules aren't blocking traffic
  • Check bridge memberships with brctl show
  • Test connectivity with tcpdump on both ends
  • Ensure IP forwarding is enabled: sysctl net.ipv4.ip_forward=1