Proxmox VE Network: VLANs on Linux Bridges - 夜莺博客

Proxmox VE Network: VLANs on Linux Bridges

Proxmox VE builds its virtual networking on the Linux network stack: a bridge (vmbrX) acts as a virtual switch that guests and physical NICs plug into. Getting VLANs right on that bridge is the difference between a hypervisor that plays nicely with your physical switch trunks and one that leaks or drops traffic. Proxmox supports two models: per-VLAN sub-interfaces (vmbr0.100 style) for simple cases, and VLAN-aware bridges where one bridge carries every VLAN and each VM gets a tag - the model Proxmox recommends for anything beyond a handful of networks. This guide explains both, with /etc/network/interfaces examples, VM-level tagging, the bond-on-trunk pattern, verification commands, and the safe way to apply changes on a live node.

How Proxmox Bridges and VLANs Work

A Linux bridge is a virtual switch. The physical NIC is a bridge port, VMs connect to the bridge as tap devices, and traffic to the physical network flows through the uplink NIC. Proxmox does not invent a datapath of its own: everything you configure in the GUI or in /etc/network/interfaces ends up as an ip link bridge, a VLAN device, or a bond in the kernel. That is why the same rules that apply to a plain Debian server apply here, and why ip and bridge commands are the fastest way to see what is really configured.

Two VLAN strategies exist, and mixing them up is the most common source of confusion on Proxmox hosts:

  • VLAN sub-interfaces - create vmbr0.100 for VLAN 100 and connect a VM to that interface. The hypervisor tags all traffic on it. That is one bridge (or sub-interface) per VLAN, easy to reason about, but the hypervisor becomes a visible participant in every VLAN it carries and the configuration grows linearly with the number of networks.
  • VLAN-aware bridge - enable bridge-vlan-aware on vmbr0; every VM gets a vlan tag and the kernel handles 802.1Q tagging per VM on one shared bridge. Proxmox recommends this model because a single bridge serves every VLAN and guests are isolated by tag instead of by interface.

The two approaches are mutually exclusive on the same port. A VLAN-aware vmbr0 must not also have vmbr0.100 sub-interfaces stacked on top of it, and a bridge with sub-interfaces should not be made VLAN-aware. Decide per bridge, then keep it consistent.

VLAN-Aware Bridge Configuration

Edit /etc/network/interfaces (or use the GUI, which stages changes in /etc/network/interfaces.new and applies them when you click Apply Configuration):

auto vmbr0
iface vmbr0 inet manual
    bridge-ports eno1
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware yes
    bridge-vids 2-4094

The four bridge options do most of the work. bridge-ports eno1 makes the physical NIC a port of the bridge. bridge-stp off disables Spanning Tree Protocol, which a Proxmox host with a single uplink and no loops does not need; leaving it on costs thirty seconds of forwarding delay on every change. bridge-fd 0 sets the forwarding delay to zero for the same reason. bridge-vlan-aware yes turns the bridge into an 802.1Q-aware switch, and bridge-vids 2-4094 declares the VLAN IDs the bridge accepts from the uplink. Shrinking that range is a legitimate hardening step: bridge-vids 2-4094 is convenient, but bridge-vids 10 20 30 is safer if the host only ever carries three networks.

The VLAN range matters because a VLAN-aware bridge only forwards a tag that appears in bridge-vids. A frequent symptom is a VM that has a VLAN tag configured, the switch trunk configured correctly, and still no connectivity, purely because the bridge did not declare that VID.

Tagging a VM on a VLAN-Aware Bridge

With a VLAN-aware bridge in place, the VM side is a single field. In the GUI, select the VM, go to Hardware > Network Device, attach it to vmbr0, and set the VLAN Tag field to 100. Behind the scenes that writes a line into the VM configuration file:

net0: virtio=AA:BB:CC:DD:EE:FF,bridge=vmbr0,tag=100

No bridge, no sub-interface, and no interface on the host is created for that VM. The tag lives in the tap device the VM uses, so the kernel pushes the 802.1Q header on egress and strips it on ingress. Two VMs on the same bridge with tags 100 and 200 are isolated from each other exactly as if they were on two separate physical switches. If the VM must be in the untagged native VLAN, leave the tag field empty and the frames go out untagged.

Classic VLAN Sub-Interface Configuration

The older model creates one bridge per VLAN, tagging on the hypervisor side:

auto vmbr0
iface vmbr0 inet manual
    bridge-ports eno1
    bridge-stp off
    bridge-fd 0

auto vmbr0.100
iface vmbr0.100 inet manual
    vlan-raw-device vmbr0

VMs attached to vmbr0.100 are then in VLAN 100; the tap devices of those VMs are bridged onto the VLAN sub-interface, and the kernel inserts the tag on the way out of vmbr0.100. Add a management address on vmbr0.100 if the hypervisor itself must be reachable in that VLAN:

auto vmbr0.100
iface vmbr0.100 inet static
    address 10.100.0.10/24
    gateway 10.100.0.1
    vlan-raw-device vmbr0

Because each VLAN needs its own stanza, this model scales poorly past a handful of networks. It remains useful when only one or two VLANs are needed, when the switch side is a simple access port rather than a trunk, or when an appliance expects to see a plain interface rather than a tagged bridge.

Bond + VLAN for Redundant Trunks

For two NICs to a switch (or two switches with LACP), bond first and build the VLAN-aware bridge on top. The bond is the trunk, the bridge is the switch, and VLAN tags are applied per VM:

auto bond0
iface bond0 inet manual
    bond-slaves eno1 eno2
    bond-mode 802.3ad
    bond-miimon 100
    bond-xmit-hash-policy layer3+4

auto vmbr1
iface vmbr1 inet manual
    bridge-ports bond0
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware yes
    bridge-vids 2-4094

bond-mode 802.3ad is LACP, and it requires the switch ports to be configured as an LACP port-channel; without a matching LACP configuration on the switch, the bond members stay down and OVS-style fallback does not happen. bond-miimon 100 polls the link every 100 ms to detect a dead member. bond-xmit-hash-policy layer3+4 hashes on IP addresses and ports, which spreads traffic across members far more evenly than the default layer 2 policy when a few large flows dominate. For the differences between LACP and active-backup, and for the hash policies, see the bonding guides linked at the end of this article.

Proxmox also expects the ordering to be bond, then bridge, then the VM tap devices. If you change the bond mode after the bridge exists, bring the bridge down first or a stale bridge fdb entry can keep pointing at the wrong slave.

Applying Changes Safely

Proxmox writes GUI changes to interfaces.new first and applies them on click. If you edit the file directly, use ifupdown2's live reload - a bad network change on a remote host can otherwise render the node unreachable:

# apt install ifupdown2
# ifreload -a

ifreload -a computes the difference between the running state and the file and applies only what changed, without tearing down interfaces that are unaffected. That is the reason ifupdown2 is strongly preferred over ifupdown on Proxmox: the classic ifdown/ifup pair drops the interface entirely, which on a remote node kills your SSH session before the new configuration is up. Two extra precautions are worth taking when touching the uplink:

  • Keep a second management path available (a second NIC, IPMI/iDRAC console, or the Proxmox host console) so you can recover a broken configuration without a physical visit.
  • Run ifreload -a -v first in a maintenance window to see what it intends to do, and keep a copy of the working file as /etc/network/interfaces.bak.

Native VLAN and Management Access

The Proxmox management address usually lives on the untagged native VLAN of the uplink, which is why the standard configuration puts address directly on vmbr0 rather than on a tagged sub-interface:

auto vmbr0
iface vmbr0 inet static
    address 192.168.1.10/24
    gateway 192.168.1.1
    bridge-ports eno1
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware yes
    bridge-vids 2-4094

Making the bridge VLAN-aware does not change how the untagged management traffic behaves: frames without a tag are switched as before, and the host address on vmbr0 still answers on the native VLAN. Guest traffic with a tag is switched independently. This is the arrangement to aim for, because it keeps management reachable even if a tagged VM network is misconfigured.

If management must live in a tagged VLAN instead, put the address on a sub-interface and leave vmbr0 without an address, but be aware that you then depend on the tag being correct to reach the node at all. On a VLAN-aware bridge you can also address a specific VLAN directly from the Proxmox GUI by creating a Linux VLAN on the bridge, which writes a vmbr0.100 stanza for you. Use that only for host management in a tagged VLAN, never for guest traffic on the same VLAN-aware bridge.

Migrating from Sub-Interfaces to a VLAN-Aware Bridge

Hosts that started small often carry a dozen vmbr0.NNN stanzas and want to consolidate. The migration is mechanical but must be done in the right order to avoid locking yourself out:

  • Shut down or live-migrate the VMs that use the per-VLAN bridges, or note their current tags, because moving a VM from vmbr0.100 to a tagged vmbr0 changes its configuration file.
  • Confirm the switch port is already a trunk that carries every VLAN you intend to consolidate. A sub-interface model works against an access port too; a VLAN-aware bridge does not.
  • Add bridge-vlan-aware yes and bridge-vids to the uplink bridge, remove the vmbr0.NNN stanzas, and set tag=NNN on each VM's netX line.
  • Reload with ifreload -a and verify with bridge vlan show that the handled VIDs now appear on the uplink port rather than on separate bridges.

The payoff is a configuration that stops growing with the number of VLANs. Adding a new network becomes a single tag= value on a VM instead of a new bridge, a new stanza, and a reload of the uplink.

Verifying the Configuration

After a reload, confirm that the kernel sees what the file claims:

# ip -d link show vmbr0
# bridge vlan show
# networkctl status vmbr0

ip -d link show vmbr0 prints the bridge details, including the VLAN-aware flag. bridge vlan show is the authoritative view of which VLANs exist on which port and is the fastest way to prove a tag is actually present. networkctl status vmbr0 summarizes the interface state, address and carrier. Two more checks are useful when guests cannot reach the network:

# bridge link show
# bridge fdb show | grep -i aa:bb:cc

bridge link show lists the ports of every bridge and their state; a VM tap device that is not listed means the VM is not attached to that bridge. bridge fdb show reveals whether the VM's MAC has been learned, which distinguishes a tagging problem from a VM that never sent a frame.

Common Mistakes

  • VLAN-aware bridge plus sub-interfaces. Stacking vmbr0.100 on a VLAN-aware vmbr0 double-tags traffic or silently fails. Pick one model per bridge.
  • VID missing from bridge-vids. The bridge drops tags it did not declare. Widen the range or list the tag explicitly.
  • Switch side is an access port. If the uplink is not a trunk, tagged frames arrive at a port that strips or drops them. The Proxmox side cannot fix a missing trunk.
  • Bond without LACP on the switch. An 802.3ad bond whose switch ports are not in a port-channel never converges.
  • Applying an untested uplink change over SSH. Use ifreload -a and keep an out-of-band path.

Related Guides

Proxmox VLANs sit on top of generic Linux primitives, so the surrounding topics are worth reading next: Proxmox VE networking with a VLAN-aware bridge and LACP, Linux VLAN tagging with ip link and 802.1Q sub-interfaces, Linux bonding modes: LACP and active-backup, and Open vSwitch bridges and VLANs for the OVS alternative to a Linux bridge.

原文链接:https://pve.proxmox.com/wiki/Network_Configuration