Почему Docker на macOS намного хуже, чем на Linux?
Перевод: Eric Nograles — Why is Docker on macOS So Much Worse Than Linux?
Я часто слышу шутки от всех, у кого есть среда разработки Docker на Mac: это заставляет Mac звучать как реактивный самолет при взлете? Это Docker!
Однако их коллеги-разработчики на Linux не сразу могут понять, а в чем тут шутка так как ни разу не сталкивались с этой проблемой.
Почему Docker для Mac — это намного хуже, чем Docker для Linux? Мы рассмотрим причины в этом посте.
Контейнеры против Виртуальных машин
Во-первых, несколько слов об архитектуре контейнера и ее отличиях от стандартной виртуальной машины (Virtual Machine — VM).
Вообще говоря, оба они похожи в том, что вы запускаете «компьютеры внутри вашего компьютера». Разница в том, как это происходит.
(Источник: https://wiki.aquasec.com/display/containers/Docker+Architecture)
Контейнер: работа с диском
Как вы можете видеть выше, контейнеры используют вашу ОС и ее ядро и, следовательно, они «ближе к железу». Например, чтобы Контейнер мог читать/писать с жесткого диска ОС хоста, он должен:
- Смонтировать диск в контейнере (т.е. он имеет прямой доступ к диску в ОС хоста благодаря ядру)
- И далее работать так, как если бы он был непосредственно в ОС хоста
VM: работа с диском
Виртуальные машины запускают дополнительную операционную систему поверх вашей операционной системы, а также дополнительный уровень абстракции (называемый гипервизором) что бы «гостевая ОС» могла взаимодействовать с главной ОС. Например, чтобы виртуальная машина могла читать/писать с жесткого диска вашей ОС, она должна:
- Смонтировать диск в гостевой ОС
- Смонтировать диск в главной ОС на гипервизоре
- Теперь гипервизор должен синхронизировать все изменения между обоими
Docker для macOS
Хотя Docker может называться Docker для macOS, архитектурно он отличается от Docker для Linux.
(Источник: https://collabnix.com/how-docker-for-mac-works-under-the-hood/)
Как вы можете видеть выше, вместо прямого доступа к ОС хоста Docker для macOS должен запускать собственную виртуальную машину Linux (LinuxKit VM).
Docker может получить доступ только к ядру этой виртуальной машины, которое затем может выполнить описанные выше шаги для синхронизации дисков ваших Контейнеров и ОС хоста.
В то время как Docker для Linux по существу имеет прямую связь с ОС хоста (и, соответственно, с диском, сетью, графическим процессором и т. д.), Docker для macOS должен пройти несколько уровней абстракций для выполнения низкоуровневых задач.
Влияние на машину разработки
Типичная настройка разработки Docker обычно выглядит следующим образом:
Host OS
- Инструменты разработчика (IDE, текстовые редакторы, линтеры и т. д.)
- Редактирование исходного кода
Контейнер
- Код приложения и зависимости
- Какой-то механизм hot/live перезагрузки при изменении кода
- Копия или ссылка на исходный код ОС хоста
«Реактивный самолет взлетает», когда вы запускаете docker-compose на macOS? Ресурсы вашей ОС хоста усердно работают для синхронизации низкоуровневого ввода-вывода (в частности, диска и сети) между ОС хоста и контейнерами; это помимо запуска самих Контейнеров.
Вот почему вы видите, что процесс Hyperkit обычно потребляет большую часть вашего процессора даже в режиме ожидания. Вся эта синхронизирующая работа между этими слоями нетривиальна!
Опции для macOS
Это та часть, где многие посоветовали бы вам «просто разрабатывать на Linux». Хотя это правда, что Docker в Linux имеет такую архитектуру, как и предполагалось (и, следовательно, это лучший вариант), простое переключение неприемлемо для большинства людей.
Приведенные ниже параметры приблизят вас к опыту работы с Linux. По крайней мере, возможный «взлет реактивного самолета» может происходить только время от времени, а не все время.
Docker для Mac Edge Build (с Mutagen)
На данный момент у Docker есть одобреный подход к минимизации потребления ресурсов при изменении диска с помощью чего-то под названием Mutagen. Однако вам не придется беспокоиться о деталях, поскольку они упаковывают его как часть официальной сборки Docker для Mac Edge.
Инструкции
- Установите Docker for Mac Edge Build
- В пользовательском интерфейсе Docker перейдите в раздел Resources => File Sharing и укажите, какие папки вы хотите подключить к контейнерам Docker.
Плюсы
- Одобрен командой Docker
- Минимальная настройка — используйте файлы docker-compose и docker как обычно
- Значительно снижает CPU при hot/live перезагрузках
- Изменения файлов выполняются значительно быстрее
Минусы
- Все еще в состояние разработке
- Требует Docker Edge Build
docker-sync
Альтернатива, которая существует уже несколько лет, называется docker-sync.
docker-sync — это, по сути, контейнер, работающий параллельно с вашими собственными контейнерами, задача которого — эффективно информировать ваш контейнер об изменении файлов. По сути, это еще один уровень абстракции для ускорения процесса.
Инструкции
- Установите docker-sync
- Измените ваш docker-sync.yml согласно требуемым настройкам
Плюсы
- Работает на всех платформах Docker
- Значительно снижает CPU при hot/live перезагрузках
- Изменения файлов выполняются значительно быстрее
Минусы
- Требуются изменения конфигурации
- Потребляется больше ресурсов докера из-за дополнительных параллельных контейнеров
- Дополнительная оркестровка, необходимая для перемещения ваших контейнеров вверх и вниз
- Иногда возникают проблемы с синхронизацией; то есть контейнер не обновляется с изменениями ОС хоста, и его необходимо перезапустить
Заключение
Docker в основном создавался для Linux. Как оказалось, его полезность была портирована на macOS и Windows.
Поскольку обе операционные системы сильно отличаются от Linux по своей сути, виртуализация была единственным реальным способом заставить все работать. К сожалению, это приводит к неэффективности низкого уровня, которую мы в противном случае принимаем как должное.
Поскольку в будущем Mutagen будет входить в состав Docker для Mac, у разработчиков macOS есть надежда, что проблема «реактивного двигателя» начнет уменьшаться.
Тем не менее, в настоящее время лучший опыт разработчиков для Docker по-прежнему остается родным Linux.