Однажды я заглянул на Хабр, чтобы посмотреть как разработчики используют динги (dinghy) и вообще ускоряют работу докера на маке. На моё удивление по запросу динги я нашёл ровно ноль статей. Было бы нечестно не упомянуть, что тот же запрос вывел 4 комментария. С другой стороны этот факт не изменил картины в целом.

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

  • Производительность докера на osx
  • Запуск нескольких контейнеров, которые работают на порте 80

Под катом более подробное описание вышеперечисленных проблем, а так же способы их решения.

Проблема 1: низкая производительность докера на маке


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

Docker toolbox



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

В моём случае тулбокс оказался достаточно медленным. Данный инструмент хорошо подходит для запуска «статических» контейнеров. Когда же нужно интенсивно разрабатывать приложение, необходимо создавать mounted volumes (уже давно пытаюсь найти русский эквивалент, есть идеи?) вашей рабочей директории, то есть директории с кодом вашего приложения. И вот тут начинаются проблемы. Выяснив, что тулбокс не использует ни NFS ни rsync, я стал искать другие решения.

Преимущества:
— легко устанавливается и настраивается
Недостатки:
— медленный при разработке больших проектов

Docker for mac




В отличие от тулбокса, докер для мака не использует виртуал бокс. В качестве слоя виртуализации он использует HyperKit. Особенность — вы можете использовать только одну виртуальную машину. Впрочем, если необходимо, вы можете запустить докер для мака параллельно с тулбоксом.

К сожалению, докер для мака оказался ещё медленней. Никакого очевидного (и неочевидного) способа как ускорить сие приложение я не нашёл.

Преимущества:
— ещё легче устанавливается и настраивается
Недостатки:
— ужасно медленный

docker-osx-dev


Хорошее решение для ускорения работы на локальных машинах при работе с тулбоксом. Docker-osx-dev использует rsync, что значительно ускоряет отправку изменений в контейнер. Недостатком данного решения можно назвать «раздутый» размер контейнера, поскольку сами файлы копируются в контейнер.

Поэтому, используя данный подход, необходимо позаботиться о виртуальной машине с увеличенным объёмом памяти. Кэши, билды, логи — всё будет увеличивать объём памяти.
Другим недостатком я бы назвал процесс, висящий в терминале. Бэкграунд режим по умолчанию не поддерживается.

Преимущества:
— значительно ускоряет перенос файлов в контейнер
Недостатки:
— висящий процесс
— раздувает размер контейнера

Dinghy


Dinghy — это надстройка над докер машиной (docker-machine), которая включает в себя NFS и proxy (о котором мы поговорим чуть позже, cейчас нас интересует проблема производительности). А насколько мне известно, ничего быстрее NFS (в данном контексте) ещё не придумали.

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

cat ~/.dinghy/preferences.yml
:preferences:
  :proxy_disabled: false
  :fsevents_disabled: false
  :create:
    provider: virtualbox
    disk: 30000

Недостаток: поскольку вы явным образом импортируете переменные окружения (например export DOCKER_MACHINE_NAME=dinghy и пр.), то использование обычных докер машин параллельно с динги может принести много хлопот.

Преимущества:
— скорость работы
— никаких дополнительных процессов
Недостатки:
— возможно потребуются дополнительные конфиги (docker-compose.yml)
— конфликт DOCKER_MACHINE_NAME с обычной докер машиной

Проблема 2: приложения на 80 порту


После того, как мы ускорили работу своей рабочей среды, может появиться ещё одна проблема: необходимость иметь 2 и более контейнеров, работающие на 80 порту. Что за проблема, просто взять и заэкспойзить другой порт, — может сказать внимательный читатель. Действительно, зачастую данного решения бывает достаточно. Но иногда, конфигурация проектов достаточно сложна и запутана. В этих случаях необходимо иметь именно 80 порты.

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

169b86af85da        codekitchen/dinghy-http-proxy:2.5   "/app/docker-entry..."    4 hours ago         Up 4 hours          0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 19322/tcp, 0.0.0.0:19322->19322/udp   dinghy_http_proxy

Этот контейнер слушает на 80 порту и принимает все запросы на себя. Внутри этого контейнера имеется nginx сервер, который автоматически создаёт виртуальные сервера исходя из вашего docker-compose файла. Всё, что вам нужно, указать hostname в этом файле. Далее, при обращении на данный хост, динги найдёт нужную запись и перенаправит на нужный контейнер. Профит.

Заключение


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

Если у вас возник интерес по техническим деталям, оставляйте комментарии, постараюсь на всё ответить.

Спасибо за внимание.

Обновление от 18.09:
после обсуждения в комментариях с umputun удалил из недостатков докера для мака:
— только одна виртуальная машина, настраиваемся самим приложением

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


  1. umputun
    18.09.2017 20:11
    +1

    > «В качестве слоя виртуализации он использует HyperKit. Недостаток — вы можете использовать только одну виртуальную машину.»

    Что-то я не понимаю, в чем суть этой «проблемы». Почему это вообще рассматривается как проблема? В реальном, боевом использовании, тоже будет «всего один докер на хосте», зачем такая пляска с бубном нужна на рабочей машине чтоб поднять их несколько?

    По поводу «ужасно медленный» — это про что вообще? Про доступ к хостовой FS? Если он «ужасно медленный» то где результаты того, как он станет «прекрасно быстрым», где бенчмарки подтверждающие это?

    Проблема нескольких контейнеров на одном порту — это вовсе не проблема докера и решать ее надо на уровне прокси, который часть вашей системы, а не добавлением магической надстройки над docker-machine.


    1. jesprider Автор
      18.09.2017 20:37

      По поводу одной виртуальной машины — я считаю, что существует такой юзкейс, когда это может стать недостатком. То, что это проблема — я не писал. В любом случае — это особенность, которая в «плюсы» точно не попадает.

      Про «ужасно медленный». Никогда не слышал, чтобы замеряли производительность среды разработки. Мой фактор таков: если ждать загрузки страницы на локальной машине приходится по 15 секунд — это ужасно медленно (при том, что на вагранте, который использовали до этого, происходит за 3).

      Ну и про порт. Именно на уровне прокси это и решено. Надстройка главным образом добавляет NFS. В комплекте идёт прокси — зачем же изобретать свой велосипед, когда тут всё готово и динамически подстраивается под настройки контейнеров (это я про конфигурацию nginx внутри прокси контейнера).


      1. umputun
        18.09.2017 20:54

        > В любом случае — это особенность, которая в «плюсы» точно не попадает.

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

        > если ждать загрузки страницы на локальной машине приходится по 15 секунд — это ужасно медленно

        Опять непонятно, какую именно проблему предложенное решения адресует. Телепатически могу догадаться, что речь идет о volumes (исходя из разных упоминаний NFS).

        > В комплекте идёт прокси — зачем же изобретать свой велосипед,
        Если это используется как среда для локальной разработки, то я могу (с трудом, но могу) представить пользу от подобного. Но если это использование для чего-то более близкого к тому, как докер используют в реальной жизни, то решать «проблему» портов вот этим велосипедом на настощем, боевом сервере — это не самая лушая идея. Для этого есть много разного, готового и проверенного в бою, что умеет делать динамическое проксирование нормальным образом.


        1. jesprider Автор
          18.09.2017 21:20

          > Это особенность докера вообще
          По этому пункту вы правы.

          > что речь идет о volumes
          Да, речь идёт о mounted volumes, упоминалось в статье.

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

          Я уверен, что приведённое решение поставленных задач — не единственное и не идеальное. Но оно достаточно простое, подтвердило свою работоспособность и оказалось весьма быстрым, а значит имеет место на существование.


          1. SirEdvin
            18.09.2017 21:50

            вроде с волумами уже все должно быть хоророш.


          1. umputun
            18.09.2017 22:06

            я не вижу никакой проблемы с мounted volumes. Изменения появляются сразу, без всяких костылей с NFS и прочим.


            1. vlfesko
              18.09.2017 22:20

              В OS X использование mounted volumes в Docker for Mac крайне ресурсоемко — создание и изменение нескольких сотен файлов в такой директории загружает процессор на 100% на несколько секунд. Например, та же Magento 2 создает сотни симлинков на файлы или копирует сами файлы при первом рендеренге страницы в некоторых режимах, не суть. По сравнению с Docker Machine + docker-machine-nfs в результате общая производительность проекта меньше из-за того, что большая часть нагрузки на CPU идет из-за файловых операций. Вот такие грустные дела на маке с докером.


    1. stychos
      18.09.2017 21:57

      Кстати да, где сравнительные тесты? Так-то, у меня проблем с xhyve не наблюдалось, использовал его в качестве docker-machine задолго до выхода Docker for Mac.


      1. jesprider Автор
        18.09.2017 22:18

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


  1. ralder
    19.09.2017 12:24

    еще есть docker-sync