суббота, 18 апреля 2015 г.

Docker vs virtual machine

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

Экономичность

Файловая система в Docker устроена таким образом, что позволяет хранить повторяющиеся слои образа всего один раз. Допустим у нас есть 3 разных образа:
1. На базе debian поднят nginx, а сверху крутится web-site1
2. На базе debian поднят nginx, а сверху крутится web-site2
3. На базе debian поднят mysql

При должной организации образов, у всех троих будет общий слой debian, который будет храниться всего в 1 экземпляре, у первых двух общим будет слой nginx, который тоже будет храниться всего один раз. И когда допустим у нас в репозитории обновится web-site1, то на сервер придется скачать не весь образ 1, а лишь самый верхний слой с web-site1, который был изменен.

Конечно, никто нам не мешает собрать образ таким способом, что все слои будут разными и ни один из них не будет переиспользован. Но наличие стандартных образов в репозитории, большое количество статей и мануалов, который акцентируют на этом внимание - делают такое маловероятным.

Я упомянул про наличие стандартных образов - это тоже неплохая помощь в деле уменьшения размера, в репозитории docker можно найти минимизированные образы почти для всех линукс дистрибутивов и для большого кол-ва софта, вот несколько примеров, которые присутствуют сейчас у меня на машине:
debian     jessie  122.6 MB
ubuntu    14.04  192.7 MB
postgres 9.4       214.2 MB
Конечно же можно таким же образом уменьшить и размер виртуальной машины, но найти такие образы довольно проблематично, а создавать самому - долго. А тут только руку протяни и получишь готовые.

Было бы несправедливо не упомянуть, что нечто подобное есть н-р и у VMware, которая позволяет на основании некоторой базовой vm, сделать несколько машин, но реализовано это из рук вон плохо и неудобно, зачастую создавая больше проблем, чем пользы.

Оперативная память и CPU так же экономится. Не так сильно, как диск, но все же. Происходит это за счет того, что при контейнерной виртуализации на каждый контейнер приходится всего 1-2 (реже больше) процесса - это не какие-то системные процессы, а ровно те, которые обеспечивают нам функциональность приложения засунутого в контейнер. А например загруженная дефолтная убунта сколько сьест сразу после загрузки, мегабайт 500? Опять же можно поколдовать, поставить серверный вариант дистрибутива и т.д. и т.п., но это опять же время, много времени.

Повторяемость конфигурации

Все образы Docker - строятся на базе так называемого Dockerfile, в котором целиком и полностью описан порядок действий по созданию образа. Используемый там язык - состоит от силы из двух десятков команд, которые подробно описаны у них в документации, так что разобраться труда не составит. Несмотря на простоту - он покрывает 99% возникающих юзкейсов, а для оставшегося 1% не сложно придумать обходные пути. В этом файле описано все, что нужно для использования и администрирования - все устанавливаемые пакеты, зависимости от других образов, какие порты нужно открыть, куда какие конфигурационные файлы кладутся, где лежат изменяемые данные и т.п. Имея этот файл размером в несколько килобайт (а прилагается он почти всегда), можно в любой точке планеты поднять контейнер, который один в один будет таким же как у автора.

Т.е. прощай различия между продакшеном и тестовой конфигурацией, не нужно больше качать 100 гигабайтную лабу у тестеров с какими-то особенностями конфигурации, где воспроизводится баг. Достаточно выложить небольшой файл и все кому нужно получили точно такую же машину как и у тебя - ну не счастье ли?

В стане виртуальных машин - дела значительно хуже. В большинстве случаев какой-нибудь Вася-программист поднимает и ручками настраивает себе машину для разработки, про внутренности которой потом никто ничего не знает, да и сам Вася забывает со временем, что и как он настроил. А тестировщику Пете приходится точно так же поднимать машину и по своему разумению настраивать под свои нужды, она по идее должна быть такой же как у Васи, но брать у Васи нельзя - он там каких-то дебажных версий библиотек напихал, потом забыл почистить, там давно не работает та часть функциональности, которую пилит сосед Васи - плохо там все. И админ Миша, не желая зависеть от той непредсказуемости, которая творится на машинах безалаберных Васи и Пети - поднимает и опять же с нуля настраивает свою собственную версию.

Более продвинутые используют всякие Vagrant, Ansible и т.п. Получается на порядок лучше, только к сожалению пользуется этим довольно ограниченное кол-во людей. Я уж не знаю почему, но среди знакомых таких почти нет. То ли сложность отпугивает, то ли времени нет остановиться и заточить уже топор, а может это банальная лень. Еще у подобных инструментов, есть такой же недостаток, как и у Docker - работают они нормально только с Linux, на Windows пытаются замахнуться, даже какой-то прогресс уже есть, но насколько я знаю, что-либо нормальное кроссплатформенное пока ни у кого не вышло.

Удобство работы

Архитектура Docker, подразумевает, что все изменяемые файлы контейнера - логи, данные bd и т.п. - маунтятся на хостовую файловую систему. Т.е. в любой момент времени, даже при выключенном контейнере - вот они у тебя под рукой - можно посмотреть логи, остановить контейнер и забекапить bd. Понятно где что лежит, ничего не нужно искать, придумывать. Удобно? Безусловно!

С виртуальными машинами - действуют кто во что горазд: изобретают всякие расшаренные папки, предоставляют доступ по сети через nfs/samba, поднимают ssh и т.п. Для бекапа какого-нибудь файлика - будь добр зайди на запущенную машину, сначала найди его, потом вспомни и выключи всех кто с этим файлом взаимодействует и только потом бекапь. И что самое плохое, для каждого приложения заранее не понятно где будет этот файл лежать и как отыскать и остановить тех, кто его использует.

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

Готовые решения

Одной из самых удачных находок Docker - было организация репозитория с готовыми образами. Там есть кажется абсолютно все и что особенно радует, почти всегда к продукту приложена инструкция по развертыванию с примерами и описаниями особенностей запуска. Удобно - не то слово. Вместо того, что бы читать многостраничный мануал по установке и настройке продукта - запускаем 1-2 команды и вуаля - все заработало, поигрались - снесли и следов в хостовой системе никаких не осталось. Зачастую для каждого продукта существует множество вариантов - хочешь вот тебе минимальная установка, хочешь - вот оно же в связке с чем-то еще. Ничего не устроило, тоже не беда - открываем Dockerfile, правим несколько строк и вот заточенное под тебя решение готово. Как-то так получилось, что сейчас любой более менее известный продукт либо сам выкладывает себя в репозиторий Docker, либо это делает кто-то из пользователей - тенденция не может не радовать. Мне кажется, что вскоре способ распространения продуктов через докер - будет основным.

Готовых виртуалок же - на порядки меньше, это скорее исключение, чем правило. Делают такие виртуалки, как правило, только тогда, когда установка продукта совсем уж нереально сложна и запутана. Сценарии для разнообразных систем configuration management (chef, puttet, salt, ansible, etc) делают чаще чем готовые вируалки, но все равно не достаточно часто, да и зачастую нет такого места, куда можно прийти и все сценарии скачать. Плюс один продукт имеет готовый сценарий только под chef, другой только под puttet - как это все вместе дружить - не понятно.

Конечно же без недостатков не обошлось

Один из самых больных - это сеть. Ее настраивать сложно, муторно, а некоторые некоторые конфигурации, которые возможны для виртуальных машинах, в docker повторить не удастся. Но команда докера осознает эту проблему, не так давно они, насколько я помню, купили стартап, который занимался сетями под докер. Так что есть шанс, что тут они скоро все улучшат.

Еще одна большая проблема - мониторинг и оркестрация (управление набором контейнеров на одной машине, а чаще - кластером из контейнеров). Конечно есть варианты и довольно много, например тот же kubernetes от гугла. Но все они какие-то или сырые или не функциональные, зачастую из интерфейса не предоставляют доступ ко всем возможностям docker, некоторые денег хотят. Одним словом пока все не очень хорошо. Но и тут есть основания думать, что очень скоро все улучшится. Docker давно уже обещали свою систему оркестрации (в версии 1.6 даже уже сделали какой-то прототип), и я думаю где-то через пол годика они ее доведут до ума. Тут надо отдать должное традиционным системам виртуализации, у всех более менее крупных игроков - есть довольно качественные и удобные системы мониторинга и управления - свои или сторонние.

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

Заключение

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

1 комментарий: