Содержание

Использование сетевого стека хост-системы (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 выполняем по аналогии для всех контейнеров сети.
Замечания:


Использование 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, через который будет работать виртуальный интерфейс