Содержание
Использование сетевого стека хост-системы (type = veth)
Данная схема используется по умолчанию. При запуске контейнера с таким типом сети, на хост-машине создается специальный виртуальный интерфейс (в примере ниже, он называется veth-*). Этот виртуальный интерфейс фактически и использует контейнер для взаимодействия с внешней средой. Рассмотрим несколько типовых случаев.
Трансляция ip-адресов
NAT уместно использовать в случае, когда на хост-машине имеется один статический ip (например, 192.168.0.186 на интерфейсе eth0) и несколько контейнеров, которым нужен выход в сеть через данный интерфейс. Условно, это можно проиллюстрировать следующей схемой:
_____________________
__________________________________________________________ __| контейнер test_01 |
| хост-машина |/ | |
| _____________________ / | eth1 ip=10.0.0.10 |
| | |/| |_____________________|
| | veth-01 --+ | _____________________
| | | | | контейнер test_02 |
inet ---|------ eth0 ------- iptables -----+ none veth-02 --+-----| |
| ip=192.168.0.186 (nat) | | | | eth1 ip=10.0.0.20 |
| | veth-XX --+ | |_____________________|
| |_____________________|\| _____________________
| br0 \ | контейнер test_XX |
| ip=10.0.0.1 |\__| |
|__________________________________________________________| | eth1 ip=10.0.0.XX |
|_____________________|
Создадим сеть 10.0.0.0, в которой разместим виртуальные машины. Будем использовать пакет bridge-utils.
1. На хост-машине редактируем файл /etc/network/interfaces, дописывая блок настроек br0:
# Имеющиеся настройки lo и eth0 -- не трогаем
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.0.186
broadcast 192.168.0.191
netmask 255.255.255.240
gateway 192.168.0.190
# Создаем bridge br0
auto br0
iface br0 inet static
bridge_ports none
bridge_fd 0
address 10.0.0.1
netmask 255.255.255.0
Для того, чтобы изменения были приняты, выполняем:
/etc/init.d/networking stop && /etc/init.d/networking start
Внимание! В случае каких-либо ошибок, может пропасть сеть.
2. Правим файл /var/lib/lxc/test_01/config , дописывая блок настроек сети:
lxc.utsname = vm0 # имя хоста виртуальной машины lxc.network.type = veth # тип сети, veth если используется bridge lxc.network.flags = up # поднимать сетевой интерфейс при запуске системы lxc.network.name = eth1 # интерфейс внутри контейнера lxc.network.link = br0 # bridge, через который будет работать виртуальный интерфейс lxc.network.veth.pair = veth-01 # имя сетевого адаптера для этого контейнера на хостовой машине lxc.network.ipv4 = 10.0.0.10/24 # сетевой адрес хоста lxc.network.ipv4.gateway = 10.0.0.1 # шлюз lxc.network.hwaddr = 00:1E:2D:F7:E3:4E # мак-адрес хоста
3. Добавляем в таблицу nat правило:
iptables -t nat -A POSTROUTING -s 10.0.0.10/24 -j SNAT --to-source 192.168.0.186
4. Запускаем контейнер test_01. В результате, данный хост должен получить при старте ip=10.0.0.10 и через шлюз 10.0.0.1, и далее через 192.168.0.186 – выход в сеть. Пункты 2-4 выполняем по аналогии для всех контейнеров сети.
Статические ip-адреса
Этот вариант уместно использовать, когда у каждого контейнера должен быть постоянный выделенный ip (и, соответственно, возможность заходить из инета внутрь контейнера напрямую). Для настройки сети нужно создать bridge br0, который будет включать с одной стороны eth0 хост-машины, а с другой - виртуальные интерфейсы контейнеров:
_______________________
___________________________ __| контейнер test_01 |
| хост-машина |/ | |
| _____________________ / | eth1 ip=192.168.0.187 |
| | |/| |_______________________|
| | veth-01 --+ | _______________________
| | | | | контейнер test_02 |
inet ---|---+ eth0 veth-02 --+-----| |
| | | | | eth1 ip=192.168.0.188 |
| | veth-XX --+ | |_______________________|
| |_____________________|\| _______________________
| br0 \ | контейнер test_XX |
| ip=192.168.0.186 |\__| |
|___________________________| | eth1 ip=192.168.0.XXX |
|_______________________|
1. На хост-машине отредактируем файл /etc/network/interfaces, дописывая блок настроек br0:
# Настройки lo -- не трогаем
auto lo
iface lo inet loopback
# Имеющуюся конфигурацию eth0 -- удаляем или комментируем
# auto eth0
# iface eth0 inet static
# address 192.168.0.186
# broadcast 192.168.0.191
# netmask 255.255.255.240
# gateway 192.168.0.190
# Создаем bridge br0
auto br0
iface br0 inet static
bridge_ports eth0
bridge_fd 0
address 192.168.0.186
broadcast 192.168.0.191
netmask 255.255.255.240
gateway 192.168.0.190
Перегружаем сеть:
/etc/init.d/networking stop && /etc/init.d/networking start
2. Правим файл /var/lib/lxc/test_01/config , дописывая блок настроек сети:
lxc.utsname = vm0 # имя хоста виртуальной машины lxc.network.type = veth # тип сети, veth если используется bridge lxc.network.flags = up # поднимать сетевой интерфейс при запуске системы lxc.network.name = eth1 # интерфейс внутри контейнера lxc.network.link = br0 # bridge, через который будет работать виртуальный интерфейс lxc.network.veth.pair = veth-01 # имя сетевого адаптера для этого контейнера на хостовой машине lxc.network.ipv4 = 192.168.0.187/28 # сетевой адрес хоста lxc.network.hwaddr = 00:1E:2D:F7:E3:4E # мак-адрес хоста lxc.network.ipv4.gateway = 192.168.0.190 # шлюз
В результате будем иметь следующую картину (на хост-машине):
br0 Link encap:Ethernet HWaddr 00:16:3e:2f:f3:73
inet addr:192.168.0.186 Bcast:192.168.0.191 Mask:255.255.255.240
inet6 addr: fe80::216:3eff:fe2f:f373/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:437 errors:0 dropped:0 overruns:0 frame:0
TX packets:367 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:66408 (64.8 KiB) TX bytes:119528 (116.7 KiB)
eth0 Link encap:Ethernet HWaddr 00:16:3e:2f:f3:73
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:446 errors:0 dropped:0 overruns:0 frame:0
TX packets:368 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:66872 (65.3 KiB) TX bytes:119574 (116.7 KiB)
Interrupt:25
veth-01 Link encap:Ethernet HWaddr fe:de:ce:91:c1:81
inet6 addr: fe80::fcde:ceff:fe91:c181/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:60 errors:0 dropped:0 overruns:0 frame:0
TX packets:97 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3840 (3.7 KiB) TX bytes:6147 (6.0 KiB)
Результат вывода ifconfig внутри контейнера test_01:
eth1 Link encap:Ethernet HWaddr 00:1e:2d:f7:e3:4e
inet addr:192.168.0.187 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::21e:2dff:fef7:e34e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:51 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3913 (3.8 KiB) TX bytes:2742 (2.6 KiB)
Пункт 2 выполняем по аналогии для всех контейнеров сети.
Замечания:
- Контейнеры с такими параметрами смогут взаимодействовать с внешним миром напрямую, как отдельно стоящие машины.
- В идеале, вместо eth0 на хост-машине следует завести отдельный физический интерфейс для сетевого трафика контейнеров.
Использование DHCP
Сеть может быть настроена как статически в контейнерах, так и динамически и помощью DHCP-сервера, запущенного на хост-машине. Такой DHCP-сервер должен быть сконфигурирован для ответа на запросы на интерфейсе br0:
1. Устанавливаем и настраиваем DHCP-сервер
2. Файл /etc/network/interfaces, примет вид:
auto lo
iface lo inet loopback
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_fd 0
bridge_stp off
bridge_maxwait 2
3. В файле /var/lib/lxc/test_02/config , удаляем или комментируем все статические настройки сети:
lxc.utsname = vm0 # имя хоста виртуальной машины lxc.network.type = veth # тип сети, veth если используется bridge lxc.network.flags = up # поднимать сетевой интерфейс при запуске системы lxc.network.name = eth1 # интерфейс внутри контейнера lxc.network.link = br0 # bridge, через который будет работать виртуальный интерфейс
