В предыдущей статье я рассказал, как Docker использует виртуальные интерфейсы Linux и bridge-интерфейсы, чтобы установить связь между контейнерами по bridge-сетям. В этот раз я расскажу, как Docker использует технологию vxlan, чтобы создавать overlay-сети, которые используются в swarm-кластерах, а также где можно посмотреть и проинспектировать эту конфигурацию. Также я расскажу, как различные типы сетей решают разные задачи связи для контейнеров, которые запущены в swarm-кластерах.


Я предполагаю, что читатели уже знают, как разворачивать swarm-кластеры и запускать сервисы в Docker Swarm. Также в конце статьи я приведу несколько ссылок на полезные ресурсы, с помощью которых можно будет изучить предмет в деталях и вникнуть в контекст обсуждаемых здесь тем. Опять же, буду ждать ваших мнений в комментариях.


Оглавление



Docker Swarm и Overlay-сети


Overlay-сети используются в контексте кластеров (Docker Swarm), где виртуальная сеть, которую используют контейнеры, связывает несколько физических хостов, на которых запущен Docker. Когда вы запускаете контейнер на swarm-кластере (как часть сервиса), множество сетей присоединяется по умолчанию, и каждая из них соответствует разным требованиям связи.


Например, у меня есть 3 ноды docker swarm кластера:


docker node ls


Для начала я создам overlay-сеть под названием my-overlay-network:


docker network create


Затем запущу сервис с контейнером, на котором запущен простой веб-сервер, который смотрит портом 8080 во внешний мир. Этот сервис будет иметь 3 реплики, и я отмечу, что он связан только с одной сетью (my-overlay-network):


docker service create


Если затем вывести список всех интерфейсов, доступных любому запущенному контейнеру, то их будет 3. В то же время, если запустить контейнер на одном хосте, то можно ожидать только 1 интерфейс:


docker ps


Контейнер связан с my-overlay-network через eth2, что можно понять по IP-адресу. eth0 и eth1 связаны с другими сетями. Если запустить docker network ls, то можно увидеть 2 дополнительные сети, которые добавились: docker_gwbridge и ingress, а по адресам подсетей можно понять, что они привязаны к eth0 и eth1:


docker network ls


Overlay


Overlay-сеть создает подсеть, которую могут использовать контейнеры в разных хостах swarm-кластера. Контейнеры на разных физических хостах могут обмениваться данными по overlay-сети (если все они прикреплены к одной сети).


Например, для веб-приложения, которое мы запустили, можно увидеть по одному контейнеру на каждом хосте в swarm-кластере:


docker service ps webapp


Я могу получить overlay IP-адрес для каждого контейнера при помощи команды ifconfig eth2 (eth2 — это интерфейс, присоединенный к overlay-сети).


На swarm01:


docker ps


Потом с контейнера на swarm02 у меня должна быть возможность пингануть 10.10.10.5 (IP контейнера на swarm01):


docker ps


vxlan


Overlay-сеть использует технологию vxlan, которая инкапсулирует layer 2 фреймы в layer 4 пакеты (UDP/IP). При помощи этого действия Docker создает виртуальные сети поверх существующих связей между хостами, которые могут оказаться внутри одной подсети. Любые точки, которые являются частью этой виртуальной сети, выглядят друг для друга так, будто они связаны поверх свича и не заботятся об устройстве основной физической сети.


Чтобы увидеть этот процесс в действии, можно сделать захват трафика на хостах, которые являются частью overlay-сети. В последнем примере захват трафика на swarm01 или swarm02 выявит icmp-трафик между контейнерами, которые на них запущены (vxlan использует udp port 4789):


sudo tcpdump


В этом примере в пакетах можно видеть два слоя. Первый — это туннельный трафик udp vxlan между хостами по порту 4789, а внутри можно увидеть второй — icmp трафик с IP-адресами контейнера.


Шифрование


Захват трафика в этом примере показал, что если ты видишь трафик между хостами, то увидишь и трафик внутри контейнеров, проходящий по overlay-сети. Именно поэтому в Docker есть опция шифроования. Можно запустить автоматическое IPSec-шифрование vxlan-туннелей, просто добавив --opt encrypted при создании сети.


Если запустить такой же тест, но с использованием зашифрованной overlay-сети, то можно увидеть только зашифрованные пакеты между хостами:


docker network create


Инспектирование интерфейсов vxlan-туннелей


Как и bridge-сети, Docker создает bridge-интерфейс для каждой overlay-сети, который соединяет виртуальные туннельные интерфейсы, выполняющие vxlan туннельную связь между хостами. Впрочем, эти туннельные интерфейсы (bridge и vxlan) создаются не напрямую на туннельном хосте. Они находятся в разных контейнерах, которые Docker запускает для каждой создаваемой overlay-сети.


Чтобы действительно проинспектировать эти интерфейсы, надо использовать nsenter для запуска команд внутри сети контейнера, который управляет туннелями и виртуальными интерфейсами. Эту команду надо запустить на хостах с контейнерами, которые участвуют в overlay-сети.


Также надо отредактировать /etc/systemd/system/multi-user.target.wants/docker.service на хосте и закомментировать MountFlags=slave по инструкции из этого обсуждения.


sudo ls -l


Наконец, если запустить захват трафика на veth-интерфейсе, то мы увидим трафик, который покидает контейнер, но до того, как он будет направлен в vxlan туннель (упомянутый выше пинг все еще работает):


sudo nsenter


ingress


Вторая сеть, к которой были присоединены контейнеры, — это сеть ingress. Это overlay-сеть, но она устанавливается по умолчанию сразу после запуска swarm-кластера. Эта сеть отвечает за связи, которые устанавливаются с контейнерами со стороны внешнего мира. Также именно в ней происходит балансировка нагрузки, которую предоставляет swarm-кластер.


Балансировку нагрузки выполняет IPVS в контейнере, который Docker swarm запускает по умолчанию. Можно увидеть, что этот контейнер прикреплен к ingress-сети (я использовал тот же веб-сервис, что и раньше: он раскрывает порт 8080, который прикрепляется к порту 80 в контейнерах):


docker service create


Для начала, взглянем на хост — на любой хост, который участвует в swarm-кластере:


sudo iptables


Здесь мы видим правило, по которому трафик, предназначенный для порта 8080, перенаправляется по адресу 172.19.0.2. Этот адрес принадлежит контейнеру ingress-sbox, если проинспектировать его интерфейсы, то мы получим слещующее:


sudo ls -l


Docker использует mangle-правила iptables, чтобы назначить определенный номер пакетам для порта 8080. IPVS будет использовать этот номер, чтобы балансировать нагрузку в подходящие контейнеры:


sudo nsenter


Как Docker swarm использует iptables и IPVS для балансировки нагрузки контейнеров, можно более детально изучить по видеоролику Deep Dive into Docker 1.12 Networking.


Docker_gwbridge


Наконец, поговорим о сети docker_gwbridge. Это bridge-сеть с соответствующим интерфейсом под названием docker_gwbridge, который создается на каждом хосте swarm-кластера. Сеть docker_gwbridge соединяет трафик из контейнеров swarm-кластера с внешним миром. Например, такой трафик получится, если мы направим запрос в Google.


Не буду вдаваться в подробности, поскольку bridge-сети я уже в деталях рассмотрел в предыдущей статье.


Заключение


Контейнер, запущенный на swarm-кластере, по умолчанию может быть соединён с тремя и более сетями. Первая сеть, docker_gwbridge, позволяет контейнерам поддерживать связь с внешним миром. Сеть ingress нужна только для того, чтобы устанавливать входящие соединения из внешнего мира. И, наконец, сети overlay: их создает сам пользователь и их можно прикрепить к контейнерам. Эти сети служат общей подсетью для контейнеров единой сети, в которой они могут обмениваться данными напрямую (даже если они запущены на разных физических хостах).


Также существуют пространства разных сетей, которые создаются по умолчанию на swarm-кластере. Эти пространства помогают управлять vxlan-туннелями для overlay-сетей и правилами балансировки нагрузки для входящих связей.


Ссылки/ресурсы


Поделиться с друзьями
-->

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


  1. ILYHA
    24.07.2017 22:25

    А можно вопрос по теме:
    Если появилась необходимость в одном из запущенных контейнеров в swarm-кластере, запускать другие контейнеры.
    Как это правильно организовать с тем учетом, чтобы у запущенных контейнеров «второго порядка» был доступ в overlay сеть «родительского» контейнера.


    1. r-moiseev
      24.07.2017 23:01

      По идее, если вы примонтируете docker.sock к контейнеру запущенному на менеджере, то получите возможность управлять всем кластером из контейнера. В том числе и запускать сервисы.


  1. nickustinov
    25.07.2017 09:12
    +1

    Иногда Swarm mode бывает не совсем удобен, да и не очень стабилен он пока. Нашел бесплатное простое решение для развертывания сети между докерами на разных физических хостах — Waves Net называется (https://www.weave.works/oss/net/) — поднимает виртуальные сети одной командой, умеет шифровать и обеспечивает discovery. Может сгодится кому :)


    1. r-moiseev
      25.07.2017 10:31

      Все таки Swarm это не только сети. Есть баллансировщик из коробки, есть готовый к бою haproxy, ну и деплой напрямую из compose.

      Из альтернатив я бы тут выделил Kubernetes. Однако он сложнее в понимании и на данным момент не сильно функциональнее сварма


      1. shuron
        25.07.2017 12:11

        и на данным момент не сильно функциональнее сварма

        Kubernetes немного дальше в например с той же интеграцией стораджа…
        Ну и сама API не завязана на докер, это конечно как плюсы и минус можно видеть. Минус в сложности, так как ко всему есть абстракции, их надо один раз понять. Но зато, поняв их, вы становитесь независимы от сущностей облака или железа на которм бежит k8n. Как-бы принцип Контеэнров но в более широком смысле.
        Со swarm пока больше возни в этом плане, но похоже с LinuxKit они тоже как-то по своему решают вопрос с абстракциями — IMHO пока слишком омбизиозный ( не совсем мне понятный) подход. Я бы сказал с k8n на данный момент не ошибится, он просто популярнее и активнее поддерживается (включая крупных игроков).
        Но если есть/желание и возможность то и swarm надо иногда щупать


        1. o_serega
          25.07.2017 12:39

          k8n


          Все же — k8s)


          1. shuron
            25.07.2017 13:09

            да. ;)


        1. r-moiseev
          25.07.2017 12:56

          Не совсем понятно зачем быть не зависимым от докера. Он все равно под капотом. Лично мне приятнее использовать нативные инструменты.

          Касаемо стораджа. Я раньше тоже послушав как все прекрасно полез изучать. Оказалось не совсем. Вам в любом случае придется поднять ceph/glusterfs/поставьте своё руками. Так что магии нет. Апи возможно удобнее, но это кому как.


          1. shuron
            25.07.2017 13:16

            Не совсем понятно зачем быть не зависимым от докера. Он все равно под капотом. Лично мне приятнее использовать нативные инструменты.

            Ну я же говорю это зависит от… Я к примеру тоже люблю.
            С k8s вы не заморачиваетесь с тем где это все бежит. При случае можно и сменить все под k8s. Для больших и очень больших проектов это становится очень важно и не только по соображениям то-го что мы тоеоритически можем поменять облако, а скорее в более общем плане, как создание, абстркций — которые становятся технологически независимым стандартом.
            В маленьком проекте может гораздо выжнее совсем другие вещи, как мотивация, одного девелопера ;)
            Вот я в все пили свой частный проектик по ночам и там смотрю тоже на swarm но еще не решился.


            1. r-moiseev
              25.07.2017 13:22

              Независимость от инфраструктуры это фиш а докера в целом или я чего то не понимаю? Сварки все равно где и какие у него годы. Переключение не стоит почти ничего


              1. shuron
                25.07.2017 13:58

                Нет докер абстрагирует только процесс на ядре линукс (с разными плюшками конечно) на одной машине.
                Сворм добавляет новую абстракцию, мы абстрагируемся от конкретной машины и деплоим в кластер тут у нас конечно и k8s он тоже это делает. Делают они это по разному и по своему интересно и поэтому мне оба интересны хоть и знаком поверхностно.
                Но в k8s все немного шире. Особенно со стораджем (где конечно до сих пор не все гладко), но достаточно посмотреть список все-го того что можно подключить и как хорошо ИМХО это подлючение абстрагированно от деталей самих технологий.
                https://kubernetes.io/docs/concepts/storage/persistent-volumes/


                Или такая штука как igress которая если я правильно помню гораздо шире того, что предлагает sworm, где к сервису просто порт открывается и мэпится виртуально через кластер.
                В k8s igress позволяет в большей степени не думать о нодах, сети (на до кибернетовском уровне) а перед sworm если не путаю надо сначало заглушку поставить если не хотите сервисы из кластера делать доступными по портам, не говоря уже о балансировке по путям, TLS и т.д.
                И так во многом.


                1. r-moiseev
                  25.07.2017 15:15

                  достаточно посмотреть список все-го того что можно подключить


                  Но у докера же volume драйверы. И драйверов явно не меньше, хоть и third party да, но это работает прозрачно, и переключение с одного стораджа на другой бесплатно.

                  В k8s igress позволяет в большей степени не думать о нодах, сети (на до кибернетовском уровне) а перед sworm если не путаю надо сначало заглушку поставить если не хотите сервисы из кластера делать доступными по портам

                  Load balancing идет из коробки, о нодах можно не думать. Dockre-Flow haproxy в коробку не входит, но он есть и прекрасно работает со свармом. Вариантов роутинга там достаточно

                  В целом Swarm еще пол года назад сильно уступал kubernetes, но развивается он очень быстро.

                  Плюс по поводу Kubrnetes у меня большие опасения. Это вендор лок, на этом самом Kubernetes. Swarm использует механизмы которые есть в докере. Что будет если Swarm победит? Вы привязаны к legacy технологии.


                  1. shuron
                    25.07.2017 20:23

                    Но у докера же volume драйверы.

                    ими можно уже на уровне кластера управлять? а не на конкретной машине?


                    Load balancing идет из коробки

                    Вообщето это обширная тема. Из коробки там по портам. Если просто называть сущности.то никуда не придем ;)
                    LB есть и там и там
                    Scheduling есть и там и там
                    Persintance есть и там и там..


                    Dockre-Flow haproxy

                    Сторонние инструменты можно и с k8s использовать… Не аргумент. Да и костыль это например если интегрировать в ресурсе предостовлямые клауд-провайдерарами а k8s какраз под них заточен. и модули написаные под него абстрагируйту такие вещи. Это фишка дизйна…
                    Сворм похоже и не стремится туда..


                    Плюс по поводу Kubrnetes у меня большие опасения. Это вендор лок, на этом самом Kubernetes. Swarm использует механизмы которые есть в докере. Что будет если Swarm победит? Вы привязаны к legacy технологии.

                    Тут какраз все упорекают докер что это вендор лок ;)
                    k8s какраз и сторит все абстракцие которы могут быть реализованны где угодно и на чем угодно, вы многие компоненты можете выкинутЭи заменить, включая сам докер. А сворм это какраз больше на легаси похоже, потому что пытается быть минималистичным (что хорошо).


                    k8s преподносит себя как платформа, вот линукс с башем — тоже же вендор лок своебразный.


                    Что будет если Swarm победит?

                    swarm пока проигрывет очень в плане распространенности и поддержке, да и сырости.


  1. r-moiseev
    25.07.2017 21:09

    ими можно уже на уровне кластера управлять? а не на конкретной машине?

    Если это не локальный вольюм, а, какой то облачный драйвер, конечно он без проблем примонтируется к контейнеру, на какой бы ноде он не находился. А в kubernetes не так? Локальный вольюм по умолчанию расшарен на все ноды? Насколько я помню Kubernetes предлагает для этого использовать NFS, но NFS есть и в докере из коробки.

    swarm пока проигрывет очень в плане распространенности и поддержке, да и сырости.

    Я вот замечаю что его больше и больше внедряют в продакшн.

    Я ставлю на Swarm, так как докер уже стал де факто стандартом. А если посмотреть на последние релизы то станет очевидно, что Swarm становится режимом по умолчанию (но еще не стал) даже для одиночных серверов. Ибо все новые плюшки, типа compose v3 с деплоем реализуются только под swarm mode.

    PS Вы постоянно подчеркиваете что Kubernetes это абстракция. А много ли контейнерных движков вы знаете, что нужна абстракция?


    1. shuron
      31.07.2017 14:32

      Я вот замечаю что его больше и больше внедряют в продакшн.
      k8s гораздо распространненей сворма. А гугл его как продукт в своейм облаке предлагает… из коробки.

      А в kubernetes не так?
      не так.

      PS Вы постоянно подчеркиваете что Kubernetes это абстракция. А много ли контейнерных движков вы знаете, что нужна абстракция?
      Абстракция от того где это все будет бежать полезна без того что-бы без того что-бы стравнивать движки...

      Ну и как-бы ваша аргументаци о том что вы любите и что вам нравится…
      Любите заниматься вопросами настройки кластера? — какие проблемы… Я вовсе не сказал что докер сворм плохой.