Добрый всем день!
Хочу поделиться удобным способом использования OpenVZ контейнеров. Объект этот очень лёгкий, можно поднимать экземпляр на каждый чих.
По умолчанию для контейнера используется «venet» сетевой интерфейс. Для администратора это выглядит, как просто присвоить контейнеру адрес, и это удобно. Но для того, чтоб контейнер был доступен из сети, следует использовать адреса из той же IP сети, к которой подключён физический сервер (HN). Сервер знает список запущенных на нём контейнеров и отвечает своим MAC-ом на ARP запросы с адресами контейнеров. Но всегда хочется больше удобства в работе, и поможет нам в этом динамическая маршрутизация.
Как именно рассмотрим на примерах, используя Quagga и OSPF.

Для того чтобы такая схема заработала, в сети уже должен работать протокол динамической маршрутизации (OSPF). Однако, если у вас много сетей соединённых более чем одним маршрутизатором, то, скорее всего, динамическая маршрутизация у вас уже настроена.
во-первых, необходимо установить на сервер Quagga:
тут всё просто, Quagga входит в стандартную поставку почти всех дистрибутивов,
здесь и далее команды для debian based:
#sudo apt-get install quagga

во-вторых, произвести минимальную настройку и запустить:
в файле /etc/quagga/daemons исправить строчки (с «no» на «yes»):
zebra=yes
ospfd=yes

создать файл /etc/quagga/zebra.conf
ip forwarding
line vty

создать файл /etc/quagga/ospfd.conf
router ospf
 redistribute kernel
 network 0.0.0.0/0 area 0.0.0.0
line vty

перезапустить:
#sudo service quagga restart


с такими настройками HN будет искать маршрутизаторы на всех интерфейсах и рассказывать им о всех своих запущеных контейнерах.
проверим, Quagga подключилась к сети и информация о контейнерах распространяется:
# vtysh -e "show ip ospf nei" 

    Neighbor ID Pri State           Dead Time Address         Interface            RXmtL RqstL DBsmL
198.51.100.11    128 Full/DR            2.548s 192.0.2.25   vmbr0:192.0.2.26      0     0     0
192.0.2.27         1 2-Way/DROther      2.761s 192.0.2.27   vmbr0:192.0.2.26      0     0     0
192.0.2.28         1 Full/Backup        2.761s 192.0.2.28   vmbr0:192.0.2.26      0     0     0

если список не пустой, то значит сеседние маршрутизаторы найдены.
Проверим, что информация о контейнерах распространяется кваггой:
# vzlist
      CTID      NPROC STATUS    IP_ADDR         HOSTNAME
       100         38 running   -               radius.local
       101         26 running   198.51.100.2    dns.local
       104         47 running   203.0.113.4     cacti.local
       105         56 running   203.0.113.5     host3.local
       152         22 running   203.0.113.52    host4.local
       249         96 running   203.0.113.149   zabbix.local

# vtysh -e "show ip ospf database external self-originate" | fgrep Link\ State\ ID
  Link State ID: 198.51.100.2 (External Network Number)
  Link State ID: 192.168.98.4 (External Network Number)
  Link State ID: 192.168.98.5 (External Network Number)
  Link State ID: 192.168.98.52 (External Network Number)
  Link State ID: 192.168.98.149 (External Network Number)

получаем два списка с IP адрессами, которые должны совпадать.

Так можно создавать контейнер с любым адресом, и он будет доступен отовсюду.
Теперь немного дополним конфигурацию Quagga:
благодаря этим строчкам, информация будет обновляться быстрее, но нужно соответствующим образом настроить также интерфейсы на маршрутизиторе.
файл /etc/quagga/ospfd.conf:
...
interface vmbr0
  ip ospf hello-interval 1
  ip ospf dead-interval 3
...

Информация о контейнерах с адресами из сети в которой находится сервер — не будет распространяться. Действительно, про эту сеть и так всем известно, зачем забивать таблицу маршрутизации лишними записями.
файл /etc/quagga/ospfd.conf:
...
ip prefix-list ifvmbr0 seq 100 permit 192.0.2.0/24 le 32
router ospf
  redistribute kernel route-map openvz
route-map openvz deny 100
  match ip address prefix-list ifvmbr0
route-map openvz permit 200
...



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

  1. Live Migration, можно без простоя и разрыва соединений переносить контейнеры между серверами в разных сетях и на разных площадках.
  2. Можно реализовать горячий резерв, когда «запасной» контейнер с таким же адресом находится на другом сервере и анонсируется с большей метрикой.
  3. Anycast, аналогично предыдущему пункту, контейнеры на разных серверах в разных точках присутствия, у контейнеров одинаковые адреса которые анонсируются с metric-type 1. Тогда трафик пойдёт на «ближайший» адрес (DHCP/RADIUS/IPTV/Proxy и т.д.)


P.S.
  • С Proxmox — тоже работает замечательно, только если собираете кластер на туннелях, то интерфейсы туннелей надо вывести из OSPF или поднять метрики, а то есть риск что по тунелям побежит пользовательский трафик.
  • Может возникнуть вопрос, что тут вообще нового, уже давно ставят Quagga на сервера, но преимущество в том, что демон не нужно устанавливать внутрь каждого контейнера, а только на хостовую машину, на которой могут работать многие десятки контейнеров.
  • Не рекомендую использовать для этих целей OSPF NSSA area, есть тонкости в том, как квага генерирует LSA7 для таких маршрутов, так что, скорее всего не заработает.

Комментарии (13)


  1. click0
    30.07.2015 14:06

    В статье написана каша.

    Но для того, чтоб контейнер был доступен из сети, следует использовать адреса из той же IP сети, к которой подключён физический сервер (HN).


    Если корректно настроено proxy_arp, то маршрутизаторы прекрасно видят IP внутри виртуалок.
    При миграции с одной ноду на другую, траффик какое-то время будет ходить через старую ноду, а потом, когда MAC исчезнет из ARP-cache — через новую ноду.

    Использовать OSPF нужно только в очень специфичных случаях использования контейнеров.


    1. Ovsiannikov Автор
      30.07.2015 14:26

      > Если корректно настроено proxy_arp, то маршрутизаторы прекрасно видят IP внутри виртуалок.

      а если, адрес контейнера из другой подсети (не совпадающей с IP сетями на интерфейсах хоста),
      откуда маршрутизаторы узнают, что контейнер на этом сервере?
      статику на роутере прописывать?

      >При миграции с одной ноду на другую, траффик какое-то время будет ходить через старую ноду, а потом, когда MAC исчезнет из ARP-cache — через новую ноду.

      это если ноды в одном сегменте, а если в разных?


      1. click0
        30.07.2015 15:26

        а если, адрес контейнера из другой подсети (не совпадающей с IP сетями на интерфейсах хоста),
        откуда маршрутизаторы узнают, что контейнер на этом сервере?
        статику на роутере прописывать?

        Почитайте, что такое proxy_arp и как работать с MAC адресами.

        это если ноды в одном сегменте, а если в разных?

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

        У меня перед глазами работающие ноды, они прекрасно обходятся без OSPF.


        1. Ovsiannikov Автор
          30.07.2015 16:59

          Почитайте, что такое proxy_arp и как работать с MAC адресами.

          всегда думал что знаю… но вдруг?
          объясните, если сервер соеденён с маршрутизатором через сеть 192.168.1.0/24, на нём крутится контейнер с адресом 100.10.10.10,
          и вот компьютер с адресом 172.0.0.1, подключённый к другому интерфейсу маршрутизатора (или вообще из интернета), хочет обратится к контейнеру. В каком месте будет proxy_arp, если явного маршрута к 100.10.10.10 через 192.168.1.0 не прописано нигде?
          Ноды в кластеры используют multicast для обмена информацией.
          Если они не обмениваются мультикастом, тогда это ноды разных кластеров.

          ну и что? OpenVZ и без кластера работает.
          более того, живые люди хотят объдинять в кластер сервера из разных сегментов.
          Т.е. если такая хотелка есть, то описаный сценарий сильно упрощает жизнь.
          если же и так всё устраивает, то у меня тоже
          перед глазами работающие ноды, они прекрасно обходятся без OSPF.


          1. click0
            30.07.2015 19:02

            всегда думал что знаю… но вдруг?
            объясните, если сервер соеденён с маршрутизатором через сеть 192.168.1.0/24, на нём крутится контейнер с адресом 100.10.10.10,
            и вот компьютер с адресом 172.0.0.1, подключённый к другому интерфейсу маршрутизатора (или вообще из интернета), хочет обратится к контейнеру. В каком месте будет proxy_arp, если явного маршрута к 100.10.10.10 через 192.168.1.0 не прописано нигде?


            Наконец-то живой пример!
            Или статически на маршрутизаторе прописать маршрут:
            route add 100.10.10.10/32 <Ip сервера>

            Или добавить на маршрутизаторе второй IP-алиас из сети 100.10.10.0/24
            И тогда через бродкаст запросы будет получен MAC openvz- контейнера.


            1. Ovsiannikov Автор
              30.07.2015 19:34

              Не, ну тогда вообще динамическая маршрутизация не нужна :)
              Можно всё руками настраивать. У меня был перед глазами пример, когда в живой сети на 28 роутеров все маршруты везде прописывались вручную. Красиво так всё, рекурсивно. За 10-15 минут можно легко новую сетку добавить :)


              1. click0
                30.07.2015 23:15

                Еще есть RIPv1, он должен справится с маршрутизацией на 26 устройствах.

                А вообще, рисуйте схему и прикладывайте ее к статье, чтоб было видно практической применение маршрутизации контейнеров с Openvz в сети с 26-ю маршрутизаторами.


                1. zup
                  31.07.2015 00:25

                  26 16


  1. Ovsiannikov Автор
    30.07.2015 14:23

    > Если корректно настроено proxy_arp, то маршрутизаторы прекрасно видят IP внутри виртуалок.

    а если, адрес контейнера из другой подсети (не совпадающей с IP сетями на интерфейсах хоста),
    откуда маршрутизаторы узнают, что контейнер на этом сервере?
    статику на роутере прописывать?

    >При миграции с одной ноду на другую, траффик какое-то время будет ходить через старую ноду, а потом, когда MAC исчезнет из ARP-cache — через новую ноду.

    это если ноды в одном сегменте, а если в разных?


    1. Ovsiannikov Автор
      30.07.2015 14:27

      не туда


  1. CMHungry
    31.07.2015 15:54

    кошмар сетевика какой-то…
    OSPF в общей сети, причем без контроля редистрибьюции… и будет 40 нод виртуализации, каждая с кучей контейнеров.
    ладно бы в отдельной NSSA, с суммаризацией (а для этого надо, чтобы /32 были не external относительно маршрутизации).


    1. Ovsiannikov Автор
      31.07.2015 17:15

      а что вас так пугает?
      сказали админам: " пользуйтесь адресами из этих сеток как хотите" и если не доверяете (а я бы не доверял) — накрутите роутмапы на кваге, разрешающие только эти сети.
      или вас пугают таблицы маршрутизации не помещающиеся на один экран?


      1. CMHungry
        31.07.2015 17:40

        и большие таблицы (разбиение пары /24 на /32 — не самая хорошая идея для FIB), и большое количество LSA при большом количестве маршрутизаторов в ospf