Docker — не то, чем кажется

f90c6ad2bc0b781d163cb10b4517274a.png

Привет, Хабр! Меня зовут Матвей Мочалов, я — компьютерный инженер и один из авторов корпоративного блога cdnnow! Мы с вами познакомились в этом посте про историю DRM для видеоконтента. Сегодня я хочу поговорить с вами про Docker, а точнее про то, о чём многие забывают: различиях в нём для разных систем. Нам, как CDN-провайдеру Docker, все его 50 оттенков близки и знакомы. И, к счастью, наше взаимодействие с ним происходит из-под Linux, но, увы, не всем так везёт.

Как это часто бывает, с мультиплатформенностью и прочими «красивыми» словами в IT, всё не так однозначно. У всего своя цена, и под капотом один и тот же инструмент на разных системах, по сути своей может представлять из себя несколько разных вещей с различными принципами работы и производительностью. А обещания революции скрывают за собой эволюцию, либо вовсе регресс и топтание на месте.

Linux — дом, милый дом

17fcd689568efa265bd7b968dcf26d34.png

Для начала кратко повторим знакомое: что Docker из себя представляет под Linux. Но не произнося как заклинание одни и те же «понятные» всем термины, а посмотрев на суть технологии.

Говоря привычно и заученно, как на новогодней ёлке перед Дедом Морозом:

Docker — это «революционная» технология контейнеризации с открытым исходным кодом, которая появилась в 2013 году, сразу же обретя огромную популярность со взрывным ростом аудитории, конца и края которому не видно и по сей день. Вплоть до того, что Docker местами становится очередной затычкой для мультиплатформенных десктоп-приложений, а не только в бэкенде находит своё применение.

Говоря же по-русски, а не на наречии корпоративных ящеров:

Идея контейнеризации, изоляции и песочниц — не нова. И админу, и простому линуксоиду хорошо знакомо судорожное восстановление сломанной системы. Из-под Live-ISO образа, вводя заветную команду chroot (change root), обозначающую «смена корневой папки», для доступа к павшей смертью храбрых операционке.
Chroot в целях подобной некромантии и иных задач с нами уже очень давно —  аж с 7 версии Unix из далёкого 1979 года. А в BSD — с 1982. Благодаря такой матрёшке с виртуализацией доступа к корневой системе одной ОС из-под другой, решалась одна важная задача, которая выделяет контейнеризацию от виртуальных машин по сей день — использование общего ядра с основной ОС, а не виртуализация всей системы целиком.

С одной стороны, разные версии и типы ядер для нас недоступны в отличие от виртуалок, а с другой — процессы, запущенные из-под chroot, виртуально отвязаны от зависимостей и библиотек основной ОС. Что, как нетрудно догадаться, не только экономит нам производительность, но и избавляет от головной боли с конфликтами зависимостей для тестирования/развёртывания/разработки и всего остального, что нам будет угодно при взаимодействии с конкретным софтом.

Да, за громкими и красивыми словами про контейнеризацию и изолированность кроются в своей сути ловкие фокусы вокруг файловой системы UNIX-подобных систем и навешенная поверх этого в целях безопасности дополнительная изоляция процессов друг от друга и от основной ОС.
На этом фоне особенно забавно то, как Docker любят сравнивать с виртуальными машинами, как нечто революционное. Полностью игнорируя почти полвека истории предшествовавших технологий, на которых он буквально до сих пор работает.

Справедливости ради стоит отметить, что Docker помогла прийти к успешному успеху и экосистема инструментов. Она написана на Go, при этом отличается простотой написания своих модулей, не прибегая к садомазохизму на чистом Bash.

А также удобство использования этой экосистемы в целом: от централизованных репозиториев с уже готовыми под любые нужды контейнерами, до графического интерфейса для тех, у кого вид консоли с командной строкой вызывает приступы тревоги.
Небольшое уточнение: под капотом Podman и его страшного, но богатого собрата Docker, в их рантайме — runc, используется всё-таки не chroot, а сын маминой подруги в делах смены корневой директории — pivot_root. 

2cef594967087de4e08533d2c1b22819.png

Ну и какая, спросите вы, разница? Да, в общем-то, никакой, но есть нюанс — pivot_root  является более защищённым от эскалации привилегий в сравнении со своим старшим братом.
Даже man для chroot приводит нам пример, как с помощью банальной смены директории на предыдущую через «cd…» процесс может сбежать в основную ОС.

This call does not change the current working directory, so that

       after the call '.' can be outside the tree rooted at '/'.  In

       particular, the superuser can escape from a "chroot jail" by

       doing:

           mkdir foo; chroot foo; cd ..

       This call does not close open file descriptors, and such file

       descriptors may allow access to files outside the chroot tree.

Pivot_root же полностью изолирует запускаемый из-под него процесс и все его «дочки» от файловой системы основной ОС. Говоря по-человечески, «cd…» в лоб не сработает — придётся мудрить более заковыристые методы побега из «песочницы». Но тут мы уже забредаем в степь FireJail и прочих методов изоляции, и ограничения процессов в рамках системы с одним и тем же корнем, а это уже совершенно другая история. Однако, как вы уже и так знаете, Docker с Podman полюбились изобретателям велосипедов и в этих целях.  

Чужак в чужой стране

a3dfa2c7f23de14d6bde2c77db824fc5.png

И тут назревает вопрос:, а каким образом это всё у нас работает под Windows, где никакого общего ядра нет. Система даже не Unix-подобная. Куда и в какое место тут делать, что chroot, что pivot_root?
А ни в какое, ведь за пределами Linux и FreeBSD теряется основное преимущество Docker, о котором обычно упоминают — отказ от использования VM. Вы просто не можете запустить его под виндой без виртуалки. И то, как Docker сам это делает, и как нам предлагает делать это Microsoft — это то ещё извращение.

Во-первых, с использованием VM теряется главная маркетинговая фишка, но по дефолту Docker хочет упростить нам жизнь и за нас решает, что лучше под виндой запускать виртуалку с Linux из-под Hyper-V. А мелкомягкие нам предлагают жизнь ещё больше упростить, предлагая использовать WSL2, который, правда, тоже под всей своей мишурой скрывает Hyper-V.

d9c6e06375fc14fb7ad62c929a710d3e.png

Что же в этом плохого? Абстракция. Чем больше у нас слоёв абстракции, тем меньше мы понимаем, что наши программы и инструменты вообще делают, и тем меньше мы имеем возможности по их контролю. Особенно, когда это решение, которое как Hyper-V и WSL2, в отличие от VirtualBox, VMware или православного KVM, намеренно сделано так, чтобы что-то в нём персонализировать под себя было затруднительно.

И зачем это всё, какой ценой?

a112e6f1a767bb5a1d57922d671cbdb7.png

Ценой всего.
То, что на корню, к счастью, делает всё это извращение неконкурентоспособным относительно запуска из-под нативной системы с Linux — производительность.
Windows сама по себе достаточно прожорливая, плюсом ко всему нам из-под неё нужно запустить виртуалку с Linux, и уже оттуда запустить Docker. Сказывается ли это на производительности? Интриги тут не будет —  конечно же, сказывается.

7d2be8642c4900619095a97844147b20.png

Прощай, немытый Microsoft — компания рабов, компания господ

0ecfa652f414351fcbcbe9bacb54def7.png

А как же дела у нас обстоят под MacOS? Там ведь и система UNIX-подобная, и ядро на FreeBSD основано, всё же должно быть лучше, чем на Microsoft, и, глядишь, даже лучше, чем у этих красноглазых, роящихся в thinkpad (ах), а не в прекрасных макбуках, Линуксоидов. Ведь так?
Да вот как бы не так! В MacOS даже нет не то, что pivot-root как концепции, но и chroot. Прогресс и инновации с отставанием на 45 лет.
Хотя реализация подобного функционала под MacOS полностью возможна, и у энтузиастов даже получилось создать свои, нативные для MacOS, контейнеры.

Если же кто-то попытается поискать информацию по нативному запуску того же Docker под MacOS, то он радостно для себя может обнаружить проект Docker-OSX. Аж из-под Linux можем MacOS запустить и с почти нативной производительностью! Да вот только Docker, как и во многих других случаях, здесь выступает в роли очень тяжеловесного установщика виртуалки KVM и всех конфигов для неё, а не сам по себе запускает MacOS.
Да, в очередной раз матрёшка из абстракций, но в этот раз не Docker из-под Виртуалки, а Виртуалка из-под Docker.

740b91c4963aad8eab309bfd75a2a766.png

Но не спешите радоваться: сам Docker снова окажется в роли внутренней части матрёшки.
Раз по умолчанию яблочные владыки из Купертино не предоставляют для своей ОС, то Docker, наверное, решили сами реализовать своё нативное решение? Хотя бы для x86 систем?
Конечно же, нет. Они написали свою виртуалку HyperKit, в которой запускают Linux, а на нём уже запускают Docker.

На машинах с Appli Silicon всё ещё веселее. В случае, если вам требуются образы под x86 системы.
Docker всё также запускается в виртуалке, но теперь с Линуксом для ARM, а до недавнего времени, чтобы запустить x86 образы, он запускал ещё одну Виртуалку из-под QEMU и, наконец-то, уже в ней непосредственно сам Docker-образ.
Но на радость яблочников, в октябре прошлого года из бета-теста вышла функция, добавляющая поддержку транслятора процессорных команд Rosetta 2. Которая хоть и является программным решением, а не аппаратным блоком, но относительно виртуалки внутри виртуалки, дала значительный прирост в производительности при запуске x86 Docker-образов.

41a3495f85f25d2e661a00fc81dfec87.png

И как теперь спать по ночам с этим знанием?

2dd05d8a8ea0eb63b22a2da3b438c3d6.png

История с Docker — это один из многочисленных примеров того, как IT-индустрия в погоне за мультиплатформенностью и повторением как мантры красиво звучащих слов, теряется в том, что, зачем и как она делает.
Docker не являлся революцией — это была закономерная эволюция технологии. Но, как мы выяснили, за пределами Linux и FreeBSD — это и не эволюция, а топтание на месте, причем почти на 50 лет назад ещё и с немаленькой ценой для производительности.

И тем не менее раз за пределы Linux докер выбрался, то спрос на него есть. Но кто так упорно продолжает колоться, плакать и всё равно жрать кактус, в обмен получая непроходимое болото абстракций и меньшую производительность?
Разработчики.
Docker удобен не только для бизнеса и развёртывания сервисов, но и для создания персональных сред разработки, тестировки и однокликовой установки self-host решений.

Мы в cdnnow! для этого предпочитаем всё-таки использовать Linux в качестве рабочей ОС, так как и на личном ноуте простота и большая производительность лишними не будут.
Однако с интересом почитаем в комментариях, что вас останавливает с переходом на Linux для использования Docker, удерживая дальше на Windows, либо MacOS.

© Habrahabr.ru