Все виглядає правильно. Порт комутатора налаштований як trunk. Віртуальна машина має інтерфейс з тегами. VLAN існує. Ви навіть бачите пакети на лінії. І все одно: трафік не йде. Не «повільно». Не «переривчасто». Просто мертвий, як ваше вікно змін.
У Ubuntu 24.04 причина того, що VLAN «не працюють» на Linux bridge, часто — один пропущений елемент: bridge VLAN filtering. Якщо vlan_filtering не ввімкнено на мосту, ваш ретельно налаштований trunk перетворюється на ввічливу пропозицію, яку ядро ігнорує. Виправлення просте; діагностика — там, де люди витрачають години.
Забутий прапорець: vlan_filtering і чому це важливо
Linux-місти можуть робити дві зовсім різні речі з VLAN:
- Міст без знання про VLAN: міст переадресовує кадри на основі навчання MAC і не підтримує членство портів по VLAN. Теги можуть проходити в деяких випадках, але ви не конфігуруєте VLAN на самому мості.
- Міст із підтримкою VLAN: міст поводиться як невеликий керований комутатор. Порти мають членство у VLAN, PVID (Port VLAN ID), опціональну поведінку без тегу та фільтрацію. Цей режим контролюється через
vlan_filtering.
У Ubuntu 24.04, особливо з Netplan + systemd-networkd, люди часто створюють міст, очікуючи «поведінки, як у комутатора». Вони визначають VLAN, створюють інтерфейс VM, ставлять теги й припускають, що міст буде пересилати трафік з тегами. Але міст не буде поводитися як комутатор з підтримкою VLAN, якщо ви не ввімкнете VLAN filtering. Ви можете мати цілком валідні визначення VLAN і водночас нічого не фільтрувати — бо ви просто не попросили ядро про це.
Ось основна поведінка, яку варто пам’ятати:
- Якщо
vlan_filtering=0, конфігураціяbridge vlanфактично ігнорується при прийнятті рішень про переадресацію. - Якщо
vlan_filtering=1, міст використовує свою VLAN-таблицю, щоб визначити, які VLAN дозволені на яких портах, і як невідмічені (untagged) кадри класифікуються (PVID).
Невеличкий жарт, бо ви цього заслуговуєте: VLAN filtering — як ремінь безпеки: ніхто не помічає його, поки не вистрелить через лобове скло.
Як виглядає «VLAN не працюють» насправді
Типові симптоми:
- VM на тегованому VLAN може робити ARP, але не отримує відповіді.
- З VM до VM на тому ж хості працює, але VM до шлюзу — ні.
- Нетегований трафік працює на мосту, але тегований трафік зникає.
- tcpdump показує VLAN-теги на інтерфейсі VM, але не на фізичному NIC (або навпаки).
Як Linux-місти насправді працюють з VLAN (не так, як нам хочеться)
Linux-міст — це datapath в ядрі (не лише userspace-концепція), з параметрами, що визначають, як кадри класифікуються і переадресовуються. Підтримка VLAN-aware bridging реалізована на шарі мосту: міст підтримує членство VLAN для кожного порту і для кожного VLAN, а також прапорці як «untagged» і «PVID».
Рухомі частини, які потрібно тримати в голові
- Пристрій мосту (наприклад,
br0): там увімкнено VLAN filtering і там живе VLAN-таблиця. - Порти мосту (наприклад,
eno1,vnet12): кожен порт може бути членом багатьох VLAN і мати PVID. - PVID: VLAN, якому відповідають вхідні невідмічені кадри на порту. Це ваш «native VLAN» (але не зловживайте цим терміном поруч із мережевими інженерами, якщо любите зітхання).
- Прапорець egress untagged: чи виходять кадри для цього VLAN без тегу.
- VLAN-підінтерфейси (наприклад,
br0.20абоeno1.20): окремий спосіб робити VLAN, часто використовують, коли потрібно L3 на VLAN. Це може співіснувати з VLAN-aware bridging, але бездумне змішування шаблонів — якраз шлях до призраків у діагностиці.
Чому Ubuntu 24.04 вводить людей в оману
Ubuntu 24.04 за замовчуванням багато серверів переводить на Netplan з systemd-networkd. Це добре. Це детерміноване. Це також безкомпромісне: якщо ви явно не попросите поведінку, що знає про VLAN, ви її не отримаєте. Старі how-to з ери «ifupdown» часто припускають інші значення за замовчуванням, і багато стеків віртуалізації «ховають» складність, поки ви не вийдете за межі щасливого шляху.
Також: у Linux є принаймні три способи побудувати ту ж топологію мережі. Виберіть один і дотримуйтеся його:
- VLAN-aware Linux bridge (рекомендовано для KVM-бриджування і розміщення VM з кількома VLAN).
- Окремі VLAN-інтерфейси + окремі мости для кожного VLAN (нудно, але ефективно; погано масштабується, але легко відлагоджується).
- OVS (Open vSwitch) (потужніше; більше компонентів; варте уваги, якщо потрібні функції OVS).
Швидкий план діагностики (перевірте 1, 2, 3)
Якщо VLAN «не працюють», ви хочете знайти вузьке місце швидко. Не кидайтеся одразу в YAML Netplan. Спочатку доведіть, що думає ядро.
1) Чи міст знає про VLAN?
Перевірте vlan_filtering і VLAN-таблицю. Якщо фільтрація вимкнена, зупиніться і виправте це спочатку.
2) Чи дозволяє міст VLAN на правильних портах?
VLAN має бути присутній на обох:
- фізичному uplink-порту (trunk до вашого комутатора), та
- порті vnet віртуальної машини (або контейнерному veth), або на нижчому bond/bridge.
3) Чи правильна поведінка untagged vs tagged?
Більшість відмов тут — це «неузгодженість PVID» або «припущення native VLAN». Підтвердіть:
- Який VLAN призначається невідміченим вхідним кадрам?
- Чи ненавмисно ми знімаємо теги на виході?
4) Потім перевірте зовнішній комутатор
Тільки після того, як ви довели, що Linux налаштований правильно, варто сперечатися з мережею (або зі своїм минулим «я»). Перевірте, чи дозволені VLAN на trunk і які очікування щодо native VLAN.
Практичні завдання: команди, очікуваний вивід, і рішення
Це ті завдання, які я насправді виконую в продакшені, коли хтось каже «VLAN не працюють». Кожне містить команду, приклад виводу, що це означає, і яке рішення прийняти.
Завдання 1: Визначити міст і його порти
cr0x@server:~$ bridge link
2: eno1 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> master br0
5: vnet12 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> master br0
6: vnet13 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> master br0
Що це означає: Порти eno1, vnet12, vnet13 підпорядковані br0.
Рішення: Якщо очікуваний фізичний NIC не перелічено, ваш міст не підключений до зовнішнього світу. Виправте це перед тим, як шукати проблеми з VLAN.
Завдання 2: Перевірити, чи увімкнено VLAN filtering (суть)
cr0x@server:~$ ip -d link show br0
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:ab:cd:ef brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
bridge forward_delay 1500 hello_time 200 max_age 2000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q
Що це означає: vlan_filtering 0 означає, що міст не «знає» про VLAN. Ваша таблиця bridge vlan не буде застосована при переадресації.
Рішення: Якщо ви намагаєтеся пропускати VLAN через br0, майже напевно вам потрібне vlan_filtering 1. Увімкніть його (тимчасово через ip, назавжди через Netplan/systemd-networkd).
Завдання 3: Показати поточну таблицю членства VLAN
cr0x@server:~$ bridge vlan show
port vlan-id
eno1 1 PVID Egress Untagged
vnet12 1 PVID Egress Untagged
vnet13 1 PVID Egress Untagged
Що це означає: На всіх портах присутній лише VLAN 1 як PVID, і він egress-uje без тегу. Немає VLAN 20/30.
Рішення: Додайте VLAN на відповідні порти або перевірте, чи застосовано вашу конфігурацію. Якщо VLAN filtering вимкнено, спочатку виправте це — ця таблиця може бути неважливою для поведінки переадресації.
Завдання 4: Підтвердити, що інтерфейс VM бачить VLAN-теги
cr0x@server:~$ tcpdump -eni vnet12 -c 5 vlan
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vnet12, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:00:01.100000 52:54:00:11:22:33 > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), vlan 20, p 0, ethertype ARP (0x0806), Request who-has 10.20.0.1 tell 10.20.0.50, length 46
12:00:01.200000 52:54:00:11:22:33 > 33:33:00:00:00:02, ethertype 802.1Q (0x8100), vlan 20, p 0, ethertype IPv6 (0x86dd), length 86
Що це означає: VM відправляє теги (VLAN 20) до хоста.
Рішення: Якщо теги є на vnet, VM ймовірно налаштовано правильно. Тепер переконайтеся, що міст переадресовує VLAN 20 і uplink дозволяє його.
Завдання 5: Підтвердити, що фізичний uplink бачить ті ж теги VLAN
cr0x@server:~$ tcpdump -eni eno1 -c 5 vlan 20
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eno1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:00:01.300000 52:54:00:ab:cd:ef > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), vlan 20, p 0, ethertype ARP (0x0806), Request who-has 10.20.0.1 tell 10.20.0.50, length 46
Що це означає: Теги доходять до NIC. Це вказує, що причина не в Linux, а в комутаторі, upstream-фільтрі або на шляху повернення.
Рішення: Якщо ви бачите теги на vnet, але не на eno1, Linux знімає/обрізає їх (VLAN-таблиця/ PVID/untagged прапорці). Спочатку виправте конфіг мосту Linux.
Завдання 6: Тимчасово увімкнути VLAN filtering, щоб підтвердити гіпотезу
cr0x@server:~$ sudo ip link set dev br0 type bridge vlan_filtering 1
cr0x@server:~$ ip -d link show br0 | sed -n '1,3p'
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:ab:cd:ef brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
bridge forward_delay 1500 hello_time 200 max_age 2000 stp_state 0 priority 32768 vlan_filtering 1 vlan_protocol 802.1Q
Що це означає: Міст тепер знає про VLAN.
Рішення: Якщо VLAN раптом запрацювали, ви знайшли відсутній прапорець. Тепер зробіть це стійким у Netplan/systemd-networkd. Не лишайте це як одноразове runtime-виправлення.
Завдання 7: Додати VLAN 20 на uplink і порт VM (runtime)
cr0x@server:~$ sudo bridge vlan add dev eno1 vid 20
cr0x@server:~$ sudo bridge vlan add dev vnet12 vid 20
cr0x@server:~$ bridge vlan show | egrep 'eno1|vnet12'
eno1 1 PVID Egress Untagged
eno1 20
vnet12 1 PVID Egress Untagged
vnet12 20
Що це означає: VLAN 20 тепер дозволений на обох портах.
Рішення: Якщо трафік працює зараз, перенесіть ці налаштування в декларативну конфігурацію. Runtime-команди — для діагностики, не для постійного використання.
Завдання 8: Перевірити PVID і поведінку untagged на uplink
cr0x@server:~$ bridge vlan show dev eno1
port vlan-id
eno1 1 PVID Egress Untagged
eno1 20
Що це означає: Невідмічені кадри, що входять на eno1, будуть трактуватися як VLAN 1, і VLAN 1 виходитиме без тегу. VLAN 20 виходитиме з тегом.
Рішення: Якщо ваш комутатор очікує інший native VLAN, налаштуйте PVID (і, можливо, видаліть VLAN 1). Невідповідні PVID створюють «працює для деяких хостів» загадки.
Завдання 9: Перевірити непередбачені VLAN-підінтерфейси, що ускладнюють міст
cr0x@server:~$ ip -o link show | grep -E '\.([0-9]+):'
10: eno1.20@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
11: br0.30@br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
Що це означає: У вас є VLAN-підінтерфейси поверх NIC і/або мосту. Це не помилка, але знак, що ви могли змішувати шаблони дизайну.
Рішення: Вирішіть, чи ви робите VLAN-aware bridging (переважно для VM trunk), чи VLAN-підінтерфейси + пер-VLAN мости. Змішування без схеми приводить до фольклору у відлагодженні.
Завдання 10: Підтвердити, який renderer і бекенд використовуються
cr0x@server:~$ networkctl status -a | sed -n '1,14p'
● State: routable
Online state: online
Address state: routable
IPv4 address state: routable
IPv6 address state: degraded
Carrier bound to: config
DNS: 10.0.0.53
Network:
Link 2 (eno1)
Link 7 (br0)
Що це означає: systemd-networkd керує лінками (поширено на серверах Ubuntu). Якщо ви очікували NetworkManager, то ви дебагуєте не той стек.
Рішення: Дотримуйтеся одного control plane. Якщо Netplan рендерить у networkd, використовуйте Netplan (або нативні networkd-файли) послідовно.
Завдання 11: Перевірити генерацію netplan і зловити помилки YAML
cr0x@server:~$ sudo netplan generate
cr0x@server:~$ sudo netplan try
Do you want to keep these settings?
Press ENTER before the timeout to accept the new configuration
Changes will revert in 120 seconds
Що це означає: generate пройшов (без синтаксичних помилок). try застосовує тимчасово і дає вам опцію відкату.
Рішення: Використовуйте netplan try у віддалених сесіях. Якщо помилки з VLAN вбивають вашу зв’язність, це дає вам повернути сервер без походу до консолі.
Завдання 12: Переглянути стан моста в ядрі і FDB
cr0x@server:~$ bridge fdb show br br0 | head
52:54:00:11:22:33 dev vnet12 master br0 permanent
0a:1b:2c:3d:4e:5f dev eno1 master br0
33:33:00:00:00:16 dev vnet12 master br0 permanent
Що це означає: Міст навчає MAC-и і має деякі постійні записи. Це доводить, що L2-переадресація працює на базовому рівні.
Рішення: Якщо FDB порожня, хоча інтерфейси UP і є трафік, можливо, це пов’язано з offload-ами, неправильною прив’язкою (VM не на тому мосту) або трафік ніколи не доходить до мосту.
Завдання 13: Перевірити лічильники на предмет відкидань, пов’язаних із VLAN
cr0x@server:~$ ip -s link show eno1 | sed -n '1,12p'
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
987654321 1234567 0 120 0 45678
TX: bytes packets errors dropped carrier collsns
876543210 1122334 0 0 0 0
Що це означає: Ненульове поле dropped на RX може вказувати на черги, драйвер, offload або політику. Це підказка, а не вирок.
Рішення: Якщо drops зростають під час тестів VLAN, розгляньте налаштування offload або невідповідність MTU (особливо з VLAN + оверлеєм). Виміряйте перед оптимізацією.
Завдання 14: Перевірити MTU наскрізь (VLAN додає накладні витрати)
cr0x@server:~$ ip link show br0 | head -n 2
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:ab:cd:ef brd ff:ff:ff:ff:ff:ff
Що це означає: MTU мосту — 1500. Якщо ваша фізична мережа 1500 і ви також запускаєте VXLAN/Geneve зверху, пакети будуть фрагментуватися або відкидатися.
Рішення: Якщо ви використовуєте оверлеї, підніміть MTU на підлягаючому шарі відповідно (і забезпечте узгодженість), або прийміть нижчий MTU для оверлею і налаштуйте його свідомо.
Завдання 15: Підтвердити очікування комутатора щодо тегованого/нетегованого трафіку
cr0x@server:~$ sudo arping -I br0 -c 3 10.0.0.1
ARPING 10.0.0.1 from 10.0.0.10 br0
Unicast reply from 10.0.0.1 [00:11:22:33:44:55] 1.233ms
Unicast reply from 10.0.0.1 [00:11:22:33:44:55] 1.104ms
Unicast reply from 10.0.0.1 [00:11:22:33:44:55] 1.098ms
Sent 3 probes (1 broadcast(s))
Received 3 response(s)
Що це означає: З’єднання без тегів/native VLAN працює на br0.
Рішення: Якщо без тегів працює, а VLAN 20 — ні, зосередьтеся на членстві VLAN/PVID/тегуванні між портами мосту та списком дозволених VLAN на комутаторі тринку.
Netplan в Ubuntu 24.04: шаблон мосту з підтримкою VLAN, що працює
Є два розумні шаблони для хостів з кількома VLAN для VM. Вибирайте залежно від операційних пріоритетів.
Шаблон A (рекомендовано): VLAN-aware міст як trunk для VM
Ви створюєте один міст (br0) з фізичним uplink як порт. Увімкнюєте VLAN filtering. Визначаєте, які VLAN дозволені на яких портах. VM можуть бути підключені й або мати теги всередині VM, або ви налаштовуєте VLAN для кожної VM у гіпервізорі (libvirt/virt-manager тощо).
Приклад Netplan (схематично; точні ключі можуть відрізнятися в залежності від середовища):
cr0x@server:~$ sudo cat /etc/netplan/01-br0.yaml
network:
version: 2
renderer: networkd
ethernets:
eno1:
dhcp4: false
bridges:
br0:
interfaces: [eno1]
dhcp4: false
addresses: [10.0.0.10/24]
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses: [10.0.0.53]
parameters:
stp: false
# The critical part: VLAN-aware bridge behavior is not magic.
# Netplan renders this into the appropriate backend config.
# If your environment doesn't apply it, validate with `ip -d link show br0`.
Перевірка реальності: Абстракція Netplan корисна, поки це не так. Єдина істина — те, що показує ядро (ip -d link, bridge vlan show).
Якщо Netplan не може надійно встановити VLAN filtering у вашому середовищі, припустимо перейти до нативної конфігурації systemd-networkd. У продакшні цінують нудну правильність.
Шаблон B: підінтерфейси по VLAN і окремі мости для VLAN
Це виглядає так:
eno1.20приєднано доbr20eno1.30приєднано доbr30
Це гучніше, але зручне для відлагодження: якщо VLAN 20 ламається, ви дивитеся на eno1.20 і br20 і зупиняєтесь там. Це те, що роблять, коли хочуть простішу ментальну модель і не проти розростання конфігурацій.
Параметри systemd-networkd, які вам справді потрібні
Мережі серверів Ubuntu 24.04 часто в управлінні systemd-networkd. Там VLAN-aware bridging зазвичай зводиться до:
- Створений міст і приєднані порти
VLANFiltering=yes(або еквівалент) застосовано до мосту- Членство VLAN налаштовано для кожного порту (іноді через записи bridge VLAN)
Замість гадань, перевірте, що застосовано:
cr0x@server:~$ networkctl status br0 | sed -n '1,40p'
● 7: br0
Link File: /run/systemd/network/10-netplan-br0.network
Network File: /run/systemd/network/10-netplan-br0.network
Type: bridge
State: routable (configured)
Online state: online
Що це означає: Netplan згенерував runtime unit-и networkd. Тепер ви знаєте, де шукати, якщо потрібно перевірити згенеровану конфігурацію.
cr0x@server:~$ sudo sed -n '1,120p' /run/systemd/network/10-netplan-br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
STP=false
Що це означає: Цей згенерований файл може не включати VLAN filtering, залежно від того, як Netplan це виразив (або не виразив).
Рішення: Якщо runtime-конфіг не встановлює VLAN filtering, або виправте YAML Netplan, або перейдіть на нативні networkd-файли, де ви явно контролюєте це.
Другий жарт (останній): Міст без VLAN filtering — як запит на зміну без плану відкату: технічно дозволено, емоційно безвідповідально.
Поширені помилки: симптом → корінь проблеми → виправлення
Це розділ, який вам стане в нагоді о 02:00, коли ви приглядаєтесь до tcpdump.
1) Тегований VLAN-трафік ніколи не виходить з хоста
Симптом: VLAN теги з’являються на vnetX, але не на eno1.
Корінь проблеми: Bridge VLAN filtering увімкнено, але VLAN не дозволений на uplink-порту; або VLAN filtering вимкнено, тож ваша конфігурація VLAN не застосовується; або egress untagged встановлено неправильно.
Виправлення: Увімкніть VLAN filtering на мосту і додайте членство VLAN на обох портах:
cr0x@server:~$ sudo ip link set dev br0 type bridge vlan_filtering 1
cr0x@server:~$ sudo bridge vlan add dev eno1 vid 20
cr0x@server:~$ sudo bridge vlan add dev vnet12 vid 20
2) Невідмічений трафік працює, теговані VLAN — ні
Симптом: Управління хостом на native VLAN працює. VM на VLAN 20 не може дістатися до шлюзу.
Корінь проблеми: На комутаторі в списку дозволених VLAN відсутній потрібний VLAN; або Linux-міст не дозволяє VLAN 20 на uplink; або гіпервізор знімає теги.
Виправлення: Спочатку перевірте членство VLAN на Linux-портах через bridge vlan show, потім перевірте trunk на комутаторі.
3) Деякі VM говорять у VLAN 20, інші — ні
Симптом: VM-A працює на VLAN 20, VM-B — ні, на одному хості.
Корінь проблеми: У зламаної VM порт vnet не має членства VLAN; або має інший режим тегування (теговані в гості проти нетеговані і теговані гіпервізором).
Виправлення: Порівняйте bridge vlan show dev vnetX для обох і стандартизуйте підхід.
4) ARP працює, але IP-трафік ні
Симптом: Ви бачите ARP-відповіді, але ping-и таймаутяться.
Корінь проблеми: MTU/фрагментація (особливо з оверлеями), політика безпеки upstream або асиметрична маршрутизація. VLAN конфігурація може бути в порядку.
Виправлення: Перевірте узгодженість MTU, потім маршрутизацію і фаєрвол. VLAN — не єдине, що може зіпсувати вечір.
5) Трафік працює до перезавантаження
Симптом: runtime bridge vlan add виправив проблему, але після reboot все ламається.
Корінь проблеми: Ви не зробили VLAN filtering і таблицю VLAN стійкими; Netplan/networkd конфіг не містить критичних рядків.
Виправлення: Задайте налаштування в Netplan або нативних networkd-файлах. Підтвердіть після перезавантаження через ip -d link show br0 і bridge vlan show.
6) «Але міст увімкнений» (класична відволікаюча деталь)
Симптом: Всі лінки показують UP, але VLAN-переадресація не відбувається.
Корінь проблеми: VLAN filtering вимкнено або членство VLAN відсутнє. Стан лінку — не те саме, що політика.
Виправлення: Перестаньте довіряти тільки «UP». Починайте довіряти таблиці VLAN і знімкам трафіку.
Три корпоративні історії з практики
Інцидент через хибне припущення: «Linux-міст — це ж комутатор, правда?»
Середня компанія експлуатувала кластер віртуалізації на Ubuntu. Вони перейшли з старого образу хоста з ручними скриптами налаштування мереж. Новий образ стандартизували на Ubuntu 24.04 і Netplan. План був простий: один міст на хост, trunk для кількох VLAN і гнучкий мережевий доступ VM.
Перший вікно обслуговування пройшло гладко — поки нові VM на тегованому «app VLAN» не перестали досягати шлюзу. Команда зробила звичний танець: перевірили trunk на комутаторі, перезавантажили ToR-порт, перепідключили NIC VM і пробували різні моделі virtio. Хтось навіть копався в STP, бо це здавалося логічним.
Хибне припущення було простим: вони вірили, що визначення членства VLAN десь у їхньому інструменті автоматично змусить Linux-міст поводитися як VLAN-aware комутатор. Не змусило. Міст переадресовував невідмічені кадри нормально, тож усі дивилися на мережу. Тим часом хост спокійно ігнорував їхні VLAN-настанови, бо vlan_filtering був вимкнений.
Виправлення зайняло хвилини: увімкнути VLAN filtering і додати членство VLAN для uplink та портів VM. Справжня робота була соціальною: оновити документацію збірки і тести прийняття, щоб цього не повторилося.
Після того вони написали невеликий preflight-чек: на кожному хості виконувати ip -d link show br0, провалювати збірку якщо vlan_filtering 0, і вимагати відомий список VLAN у bridge vlan show. Ніхто не любить риштувань, поки вони не рятують від збою.
Оптимізація, що дала зворотний ефект: «Давайте віддамо все на offload»
Інша організація хотіла збільшити пропускну здатність VM-мережі. Вони мали кілька VLAN, які мостилися на 25G NIC, і бачили періодичні втрати при сплесках. Вони вирішили увімкнути всі доступні offload-функції і настроїти черги агресивно.
Спочатку все виглядало краще: CPU опустився, пропускна здатність виросла в синтетичних тестах, графіки стали приємніші. Потім почались проблеми: випадкові втрати пакетів лише на одному VLAN і лише для певних патернів трафіку. ARP був у порядку. TCP зависав і відновлювався. UDP-моніторинг пропускав інтервали. Це була найгірша хвороба: періодична і правдоподібно «зовнішня».
Провал стався через змішання поведінки драйвера і того, як інтерпретувалися знімки трафіку. З деякими offload-ами видимість пакетів змінювалася: tcpdump не завжди показував повну правду про те, де теги, і команда кілька днів ганялась за привидами VLAN. Вони також виявили, що сплески спричиняє шаблон деплою додатка, а не мережа, тож вони спочатку налаштували не те.
Кінцеве рішення не було «вимкнути всі offload-и назавжди». Воно було прозаїчніше: створити повторюваний тест трафіку, міняти по одному параметру, валідувати з апаратними лічильниками і тримати діагностику VLAN окремо від оптимізації продуктивності. Коли вони вибірково повернули offload-и і перевірили MTU та тегування наскрізь, стабільність повернулась.
Урок: робота з продуктивністю змінює спостережуваність. Якщо ви не можете виміряти — не довіряйте. Особливо біля VLAN і bridge.
Нудна, але правильна практика, що врятувала день: «Приймайте ядро як тест прийняття»
Фінансова організація з жорстким контролем змін йшла повільно, і їхня мережа була консервативною. Вони також дотримувались звички, яку я хотів би бачити частіше: після застосування мережевої конфігурації вони завжди перевіряли live-стан ядра по чек-листу.
Під час оновлення новий шаблон додав тонку зміну в Netplan. YAML виглядав «еквівалентно» старому, але більше не встановлював міст як VLAN-aware. Перший хост після оновлення не пройшов перевірки прийняття.
Бо вони записали, як виглядає «правильно» — vlan_filtering 1, очікувані VLAN ID на очікуваних портах і швидкий tagged ping-тест — вони виявили проблему до того, як якась робоче навантаження перейшла в production. Жодних інцидентів. Нема дзвінків о півночі. Лише крок розгортання не пройшов і тикет на виправлення шаблону.
Вони не отримали очок за креативність. Вони виграли за рахунок нудної правильності.
Факти й контекст (чому це все ще плутає у 2025)
Кілька коротких конкретних фактів і історії, що пояснюють, чому люди продовжують наступати на ті самі граблі:
- 802.1Q VLAN tagging додає 4-байтний заголовок до Ethernet-кадрів, вставляючи VLAN ID і біт пріоритету.
- Linux bridging присутній в ядрі десятиліттями, і це ближче до datapath комутатора, ніж багато хто усвідомлює — доки не з’явиться політика VLAN.
- Підтримка VLAN-aware bridge розвивалась з часом; ранні налаштування часто використовували VLAN-підінтерфейси, бо їх легше було опанувати.
- Концепт «native VLAN» — це в основному поведінка портів комутатора; в Linux-містах аналог — це PVID і прапорці untagged egress.
- Netplan — це renderer, а не стек мережі. Він генерує конфіг для systemd-networkd або NetworkManager, отже «я змінив YAML» ≠ «ядро змінило поведінку».
- systemd-networkd строгий і детермінований, що добре для серверів. Але це означає, що один пропущений булевий прапорець може тихо відключити весь набір функцій.
- tcpdump може давати спотворену картину через offload-и (TSO/GSO/GRO і VLAN-offload), тому знімки треба підтверджувати станом мосту і лічильниками.
- Таблиці VLAN мосту — per-port; недостатньо «увімкнути VLAN 20 на мосту». І uplink, і порт VM повинні дозволяти його.
- Пер-VLAN мости — старий підхід, що й досі перемагає в простоті експлуатації; це розгорнуто, але його складно неправильно інтерпретувати під час інциденту.
Контрольні списки / покроковий план
Покроково: виправити зламаний trunked VLAN-міст в Ubuntu 24.04
- Підтвердити топологію: знайти ім’я мосту (
br0) і фізичний uplink (eno1). - Перевірити VLAN filtering:
ip -d link show br0; якщоvlan_filtering 0, це ваше перше виправлення. - Увімкнути тимчасово:
ip link set dev br0 type bridge vlan_filtering 1. - Переглянути VLAN-таблицю:
bridge vlan show. Підтвердити, що очікувані VLAN присутні. - Дозволити VLAN на uplink і портах VM:
bridge vlan add dev eno1 vid 20іbridge vlan add dev vnet12 vid 20. - Перевірити PVID і untagged: переконайтесь, що ваша «native» поведінка співпадає з налаштуваннями комутатора.
- Доведіть це з capture: теги мають з’являтись на vnet і фізичному NIC, де потрібно.
- Зробіть стійким: зафіксуйте в Netplan або нативних networkd-файлах; уникайте runtime-only виправлень.
- Тест перезавантаження: перевірте знову після reboot; не довіряйте конфігурації, поки вона не переживе один reboot.
- Документуйте очікуваний стан: збережіть вивід
ip -d link show br0іbridge vlan showяк «known-good».
Операційний чек: як виглядає «добре»
ip -d link show br0показуєvlan_filtering 1.bridge vlan showперелічує очікувані VLAN ID наeno1і на кожному відповідному порту VM.- PVID навмисний, а не встановлений випадково.
- Untagged egress встановлено лише там, де ви маєте на увазі.
- tcpdump підтверджує, що теги проходять хост правильно.
- Перезавантаження не змінює поведінку.
FAQ
1) Який цей «один прапорець мосту, який більшість забуває»?
vlan_filtering на пристрої мосту. Без нього правила переадресації з урахуванням VLAN не застосовуються так, як очікують при побудові trunk через Linux-міст.
2) Як перевірити, чи увімкнено VLAN filtering?
Запустіть:
cr0x@server:~$ ip -d link show br0 | grep -o 'vlan_filtering [01]'
vlan_filtering 0
Якщо виведе vlan_filtering 0, ваш міст не знає про VLAN.
3) Якщо VLAN filtering вимкнено, чи теги VLAN завжди відкидаються?
Не завжди; саме це і вводить в оману. Теги іноді можуть, здаватися, проходити, залежно від топології і очікувань. Але якщо ви покладаєтесь на політику per-port і поведінку trunk, вам потрібен VLAN-aware режим. Інакше ви дебагуєте непередбачувану поведінку.
4) Чи потрібно налаштовувати VLAN на обох uplink і порті VM?
Так, для VLAN-aware bridging. VLAN має бути дозволений на вході/виході портів, що його несуть. Фізичний trunk і порт vnet VM обидва мають мати членство для цього VLAN.
5) У чому різниця між PVID і «untagged»?
PVID класифікує вхідні невідмічені кадри у VLAN. «Egress untagged» вирішує, чи виходять кадри для цього VLAN без 802.1Q тега. VLAN може бути присутній без того, щоб бути PVID.
6) Тегувати в VM чи тегувати на хості?
Виберіть один підхід для середовища і стандартизуйте:
- Тегувати всередині VM, якщо VM — маршрутизатор/фаєрвол або потребує кількох VLAN.
- Тегувати на хості/гіпервізорі, якщо VM має бути «один VLAN, простий NIC».
Випадкове змішування обох підходів — чудовий спосіб отримати «залежить від випадку» відмови.
7) Чому tcpdump не показує VLAN-теги, у які я впевнений?
Offload-и можуть змінювати те, що ви бачите в дампі. Обробка VLAN може бути віддана апаратурі, а GRO/GSO можуть зливати пакети. Використовуйте стан мосту (bridge vlan show) і зіставляйте з кількома точками захоплення.
8) Чи краще Open vSwitch?
Іноді. Якщо вам потрібні розширені політики, інтеграція тунелювання або краща спостережливість на шарі віртуального комутатора — OVS вартий уваги. Якщо ваша задача — «надійно передати trunk VLAN до VM», in-kernel Linux bridge з VLAN filtering зазвичай простіший і легше відлагоджується.
9) Чи виправить це перезавантаження або рестарт мережевих сервісів?
Перезавантаження не виправить відсутню конфігурацію; воно лише покаже, що ви забули. Використовуйте перезавантаження для перевірки стійкості, а не як інструмент ремонту.
10) Який хороший acceptance test після змін?
Принаймні:
ip -d link show br0і перевіритиvlan_filtering 1bridge vlan showі перевірити наявність VLAN на відповідних портах- Пакетний захват або tagged connectivity тест із VM
- Перезавантаження і повторення перевірок
Висновок: практичні наступні кроки
Коли VLAN «не працюють» на мостах Ubuntu 24.04, найшвидший шлях — припинити гадати і опитати ядро. Перевірте vlan_filtering. Перевірте таблицю VLAN мосту. Підтвердіть, що VLAN існує і на uplink, і на порту VM. Лише після цього починайте сперечатися про конфіг комутатора.
Ось план, придатний для вікна змін:
- Запустіть
ip -d link show br0і виправтеvlan_filteringспочатку. - Запустіть
bridge vlan showі переконайтеся, що членство VLAN правильне по портах. - Доведіть переадресацію двоточковим tcpdump (vnet + фізичний NIC).
- Зробіть це стійким у вашому control plane (Netplan або нативний networkd) і перевірте після reboot.
Одна перефразована ідея від Werner Vogels (інженерія, орієнтована на надійність): все рано чи пізно ламається; проектуйте так, щоб відмови були очікуваними і відновлюваними
(ідея перефразована).