Сетевая подсистема Linux содержит больше типов интерфейсов, чем физических карт в сервере. Контейнеры, виртуальные машины и сетевые службы подключаются к сети именно через виртуальные устройства, которые ядро создаёт по запросу и которые ведут себя как настоящие адаптеры. Разбираем, чем отличаются основные типы, как создать их вручную через утилиту ip, как проверить работу и в каких случаях каждый тип уместен.

Устройство интерфейса и как его рассматривать

Интерфейс в ядре это объект с именем, MAC-адресом, состоянием, размером кадра и принадлежностью к пространству имён. У виртуального устройства нет связи с железом, но набор свойств тот же, поэтому инструменты работают с ними одинаково.

ip -br link show
ip -d link show type bridge
ip addr show
ethtool -i eth0

Флаг -d выводит подробности, по которым видно тип устройства и его параметры: у моста виден список портов, у VLAN идентификатор и родительское устройство, у пары veth имя соседа. Поле driver в выводе ethtool для физического адаптера содержит имя модуля, а для виртуального название типа, и это самый быстрый способ понять, с чем имеешь дело.

Состояние интерфейса отражается двумя флагами. Первый показывает, включено ли устройство administratively, второй есть ли у него несущая. Виртуальные устройства без привязки к кабелю получают несущую сразу после включения, и это отличает их от физических.

Типы устройств и задачи, которые они решают

Набор типов шире, чем принято думать, и каждый закрывает свою задачу. Основные из них:

  1. dummy создаёт устройство без передачи данных, годится для адреса запасного узла и проверки конфигурации;
  2. bridge объединяет несколько интерфейсов в один сегмент второго уровня и служит основой сетей контейнеров;
  3. vlan добавляет метку и позволяет разделить трафик на одном физическом устройстве;
  4. macvlan даёт устройству собственный MAC-адрес на общей физической линии;
  5. ipvlan разделяет только адрес третьего уровня, сохраняя один MAC-адрес;
  6. veth работает парой и переносит пакеты из одного пространства имён в другое;
  7. tun и tap создаются программами для виртуальных машин и сетевых служб;
  8. bond объединяет несколько физических линий для резервирования и сложения скорости.
ip -d link show type dummy
ip -d link show type vlan
ip -d link show type veth
ls /sys/class/net/

Пара veth требует пояснения: устройства всегда создаются по двое, и пакет, вошедший в одно, выходит из другого. Именно этот механизм переносит трафик между сетевыми пространствами имён, и без него изолированный контейнер не смог бы обмениваться данными с хостом.

Отдельно стоит упомянуть dummy. Через него нельзя построить сеть, поскольку устройство отбрасывает всё отправленное и не имеет второй стороны. Его назначение другое: держать адрес, который нужен службам для привязки, пока основная сеть не настроена. Для имитации нескольких машин применяют сетевые пространства имён, а не набор устройств dummy.

Ручное создание устройств через утилиту ip

Команды выполняются от имени администратора и действуют до перезагрузки, что удобно для проверки.

# устройство-заглушка
sudo ip link add dummy0 type dummy
sudo ip link set dummy0 up
sudo ip addr add 10.99.0.1/32 dev dummy0

# мост и порты
sudo ip link add br0 type bridge stp_state 1 forward_delay 4
sudo ip link set eth1 master br0
sudo ip link set br0 up
sudo ip addr add 192.168.50.1/24 dev br0

# vlan поверх физического устройства
sudo ip link add link eth0 name eth0.100 type vlan id 100
sudo ip link set eth0.100 up
sudo ip addr add 192.168.100.2/24 dev eth0.100

Мост без портов работает, но трафик не переносит. Порт добавляется ключом master, удаление выполняется установкой значения nomaster. Включение протокола spanning tree предотвращает петли, если к мосту подключено несколько путей, а параметр forward_delay задаёт задержку перехода порта в состояние пересылки.

Устройство VLAN привязано к родительскому и перестанет работать, если родитель отключён. Имя обычно выбирают по схеме имя.номер, но это соглашение, а не требование: ядро принимает любое допустимое имя.

# пара veth
sudo ip link add veth0 type veth peer name veth1
sudo ip link set veth0 up
sudo ip link set veth1 up

# macvlan и ipvlan
sudo ip link add mac0 link eth0 type macvlan mode bridge
sudo ip link add ipv0 link eth0 type ipvlan mode l2
sudo ip link set mac0 up

Режим bridge у macvlan позволяет устройствам общаться между собой напрямую, режим private изолирует их друг от друга даже в пределах одного родителя. У ipvlan режим l2 работает на втором уровне, режим l3 включает маршрутизацию между устройствами без широковещательного трафика.

Объединение физических линий настраивается созданием устройства bond и добавлением портов в него. Режим задаёт, как распределяется трафик и что происходит при отказе одной линии.

sudo ip link add bond0 type bond mode 802.3ad miimon 100
sudo ip link set eth1 down
sudo ip link set eth2 down
sudo ip link set eth1 master bond0
sudo ip link set eth2 master bond0
sudo ip link set bond0 up
cat /proc/net/bonding/bond0

Режим 802.3ad требует поддержки агрегации на стороне коммутатора и даёт сложение скорости, режим active-backup работает без настройки коммутатора и обеспечивает только резервирование. Параметр miimon задаёт период проверки состояния линии в миллисекундах, и без него отказ порта обнаруживается не сразу. Порт перед добавлением в объединение переводят в выключенное состояние, иначе команда завершится отказом.

Удаление выполняется одинаково для всех типов.

sudo ip link delete br0
sudo ip link delete eth0.100
sudo ip link delete veth0

Удаление моста не затрагивает порты, они возвращаются в обычное состояние, поэтому перед удалением стоит снять с них адреса, назначенные для работы в составе моста.

Пространства имён и связь контейнеров с сетью

Пространство имён содержит собственный набор интерфейсов, таблицу маршрутов и правила фильтрации. Устройство существует ровно в одном пространстве и переносится между ними одной командой.

sudo ip netns add ns1
sudo ip link add veth0 type veth peer name veth1
sudo ip link set veth1 netns ns1
sudo ip netns exec ns1 ip link set veth1 up
sudo ip netns exec ns1 ip addr add 10.200.0.2/24 dev veth1
sudo ip link set veth0 master br0
sudo ip link set veth0 up

Эта схема повторяет то, что делают среды управления контейнерами: одна сторона пары остаётся в хосте и подключается к мосту, вторая передаётся в пространство имён контейнера и получает адрес. Внешний доступ появляется после настройки трансляции адресов или маршрутизации на хосте.

sudo ip netns exec ns1 ip route show
sudo ip netns exec ns1 ping -c 2 10.200.0.1
sudo ip netns list
sudo ip netns del ns1

Для виртуальных машин и сетевых служб ядро создаёт устройства по запросу самой программы. Устройство tun работает с пакетами третьего уровня и применяется программами, которым нужен собственный сетевой интерфейс, устройство tap передаёт кадры второго уровня и подключается к виртуальному адаптеру машины.

sudo ip tuntap add dev tun0 mode tun user qemu
sudo ip tuntap add dev tap0 mode tap user qemu
sudo ip link set tap0 master br0
sudo ip link set tap0 up
ip -d link show dev tun0

Параметр user задаёт владельца устройства, чтобы процесс без прав администратора мог читать и писать пакеты. После завершения работы программы устройство исчезает, если было создано с флагом одноразового использования, либо остаётся и его удаляют общей командой ip link delete.

Проверка изнутри пространства показывает таблицу маршрутов и доступность шлюза. Отсутствие маршрута по умолчанию означает, что наружу трафик не пойдёт даже при рабочем мосте.

Постоянное сохранение конфигурации

Созданные вручную устройства исчезают после перезагрузки, поэтому рабочую схему переносят в конфигурацию сети. Способ зависит от системы управления.

# /etc/systemd/network/20-br0.netdev
[NetDev]
Name=br0
Kind=bridge

# /etc/systemd/network/25-br0.network
[Match]
Name=br0
[Network]
Address=192.168.50.1/24

# /etc/systemd/network/30-eth1.network
[Match]
Name=eth1
[Network]
Bridge=br0
sudo networkctl reload
networkctl status br0

В системах с NetworkManager профиль моста создаётся через nmcli, и порты описываются отдельными профилями с указанием slave-type bridge. Порядок важен: мост должен существовать до подключения портов, и система управления обычно решает эту задачу зависимостями.

Когда мост нужен и для виртуальных машин, и для контейнеров, удобнее создать два моста и связать их маршрутизацией на хосте, чем держать один сегмент с двумя подсетями: изоляция получается явной, а диагностика проще.

При переходе между способами управления стоит убрать дублирование. Если интерфейс описан и в сетевых файлах, и в профилях NetworkManager, результат зависит от порядка запуска, и диагностика усложняется. Один интерфейс должен описываться одним инструментом.

Имена устройств и порядок их появления

Имена интерфейсов назначаются по нескольким схемам. Предсказуемые имена вида enp3s0 формируются из расположения устройства на шине, классические eth0 выдаются по порядку обнаружения и зависят от порядка загрузки модулей.

udevadm info /sys/class/net/eth0 | grep -E 'ID_NET_NAME'
cat /sys/class/net/eth0/address
ls -l /sys/class/net/

Если имя важно для конфигурации, привязку делают по MAC-адресу, а не по имени. Это защищает от ситуации, когда после обновления ядра или добавления карты интерфейсы поменялись местами и сеть собралась неправильно.

Отдельная тонкость касается мостов. Устройство моста появляется сразу, а порты добавляются по мере готовности физических интерфейсов. При медленной инициализации карты служба, ожидающая готовности сети, может завершиться по времени ожидания. Лечится это указанием зависимости от конкретного устройства либо включением ожидания несущей.

Диагностика, производительность и выбор типа

Проверка моста выполняется через семейство команд bridge, которые показывают порты, таблицу пересылки и метки VLAN.

bridge link show
bridge fdb show br br0
bridge vlan show
ip -s -s link show dev br0

Таблица пересылки хранит соответствия MAC-адресов портам. Пустая таблица при активном обмене означает, что трафик не доходит до моста, и смотреть стоит состояние портов и настройку VLAN. Счётчики в выводе ip -s показывают пакеты и ошибки по каждому устройству, и рост ошибок на физическом порту объясняет потери на всех подключённых к мосту.

Для захвата пакетов подходит любая точка схемы: порт, сам мост или сторона пары veth внутри пространства имён.

sudo tcpdump -i br0 -nn -c 20
sudo ip netns exec ns1 tcpdump -i veth1 -nn

Фильтрация по VLAN позволяет разделить трафик на одном мосту, не создавая отдельных мостов на каждую сеть.

sudo bridge vlan add vid 100 dev eth1 pvid untagged
sudo bridge vlan add vid 200 dev eth1
bridge vlan show dev eth1

Флаг pvid задаёт метку, которая присваивается кадрам без метки, пришедшим на этот порт, флаг untagged указывает, что кадр уходит из порта без метки. Такой набор соответствует порту доступа в терминологии коммутаторов. Порт, пропускающий несколько меток без pvid, ведёт себя как транковый и используется для связи двух мостов на разных машинах.

Производительность виртуальных устройств ниже физических, поскольку каждый пакет проходит дополнительный путь в ядре. Снижают накладные расходы тремя способами: включают аппаратное ускорение контрольных сумм и сборки пакетов, используют многоочередные устройства с распределением по ядрам, избегают лишних промежуточных устройств там, где достаточно одного.

У macvlan есть известное ограничение: хост не обменивается пакетами с собственными дочерними устройствами того же родителя. Обход состоит в создании отдельного macvlan-устройства для самого хоста. У ipvlan такого ограничения нет, зато есть другое: все устройства разделяют один MAC-адрес, и коммутаторы с привязкой порта к адресу увидят только один из них.

Выбор типа определяется задачей. Для связи контейнеров на одной машине берут мост с парами veth. Для прямого присутствия контейнера в физической сети выбирают macvlan, если у среды нет фильтрации по MAC-адресам, иначе ipvlan. Для разделения трафика отделов или сервисов применяют VLAN. Для запасного адреса и привязки служб подходит dummy. Для резервирования линий bond, и его настройку стоит проверять отключением одной из линий, а не только чтением состояния.