10 лет Docker: от революционной идеи до современной практики
Привет, Хабр! На момент написания статьи я занимаюсь надёжностью (SRE) в компании Workday, а ещё помогаю студентам в Практикуме осваивать курс по DevOps.
Сейчас виртуализация стала фундаментальной технологией для оптимизации работы серверов, упрощения процессов разработки и развёртывания приложений. Однако до появления Docker она оставалась относительно сложным и медленным процессом.
В последние 10 лет Docker перевернул мир виртуализации и стал незаменимым инструментом для DevOps-практик. За это время контейнеризация стала настолько распространённой и привычной, что многие даже не задумываются, как она устроена изнутри. Из моего опыта интервьюирования вопрос «Что такое Docker?» нередко ставит людей в тупик. Я считаю, что полезно досконально разбираться в вещах, чтобы эффективно решать проблемы и понимать, на каком из слоев системы что-то идёт не так.
В этой статье я поделюсь кратким обзором истории Docker, его ключевыми концепциями и мисконцепциями. Надеюсь, это будет полезно для новичков и студентов, изучающих DevOps-практики и виртуализацию.
Появление Docker
Прежде чем Docker появился на свет, существовали другие технологии контейнеризации, такие как LXC (Linux Containers) и OpenVZ. Существовали и проекты изоляций процессов на уровне файловой системы вроде jails и chroot, но это совсем другая история. Эти проекты также предоставляли средства для создания изолированных сред, но они не обладали такой же степенью простоты и переносимости, как Docker.
Docker взял вдохновение из этих ранних технологий. Он использовал LXC как один из своих первых бэкендов для управления контейнерами. Однако Docker добавил уровень абстракции и упростил процесс создания и управления контейнерами, что сделало его более доступным для широкой аудитории разработчиков и системных администраторов.
Таким образом Docker не только усовершенствовал концепцию контейнеризации, но и сделал её более доступной и широко применимой. Эта комбинация удобства использования и эффективности через какое-то время сделала Docker доминирующей технологией в мире контейнеризации и DevOps.
Дело в том, что разработчики и администраторы всегда сталкивались с рядом сложных задач по созданию, контролю консистентности сред и масштабированию сервисов. Традиционные виртуальные машины требовали больших ресурсов и времени для запуска. Управление приложениями и их зависимостями было и до сих пор является нетривиальной задачей.
Docker появился как ответ на вызовы того времени, от людей, которые не понаслышке знали всю боль и проблемы индустрии. Этот проект был запущен компанией dotCloud и его основателем Соломоном Хайксом в 2013 году и достаточно быстро стал эффективным решением для контейнеризации приложений. Но так было не всегда и, конечно же, получилось не сразу.
До первого публичного релиза прототип Docker представлял собой набор shell-скриптов. Позже проект перешел с Python на Golang, заодно и внеся вклад в популяризацию молодого языка программирования.
Docker решил многие проблемы благодаря следующим особенностям:
Изоляция: Docker позволяет запускать приложения в изолированных контейнерах, что обеспечивает уровень изоляции, сравнимый с виртуальными машинами, но с гораздо меньшими накладными расходами.
Портативность: Docker-контейнеры могут быть запущены на любой платформе, где установлен Docker. Это делает разработку и развёртывание приложений более удобными и предсказуемыми.
Управление зависимостями: Docker позволяет упаковать приложение и его зависимости в один контейнер, обеспечивая надёжное управление зависимостями и версиями.
Принятие Docker сообществом
Сразу после выпуска Docker быстро завоевал популярность среди разработчиков и системных администраторов. Сообщество внимательно следило за проектом, создавая множество инструментов и решений, основанных на Docker.
Стоит отметить, что Docker появился в тот момент, когда технологии виртуализации вроде Xen, KVM и VMWare были стандартом, а создание и контроль ВМ для запуска сервисов и разработческих сред управлялись инструментами оркестрации типа Puppet и Chef. Это было стандартом индустрии достаточно долгое время.
На рынке была масса сертифицированных специалистов разных мастей, и далеко не все из них — включая автора статьи — сразу поняли и приняли новый инструмент. Пожалуй, это послужило появлению множества мисконцепций использования контейнеризации и привело к незаслуженной критике.
Ряд разработчиков и администраторов использовали Docker не по назначению, рассматривая его как более удобную и легковесную замену ВМ. При этом они запускали в нём множество процессов как в полноценной ОС. Например, я лично видел, как люди запускали внутри supervisor, через него своё приложение, ssh-демон и, например, Zabbix-агент (тогда Zabbix ещё был весьма популярен).
Несмотря на свой впечатляющий успех и внимание со стороны сообщества, Docker также столкнулся с конструктивной критикой на начальных этапах своего развития. Замечания чаще всего были направлены на такие аспекты:
Изоляция процессов: Docker не обеспечивает такую же степень изоляции, как традиционные виртуальные машины. Это означает, что контейнеры могут влиять друг на друга, что вызывает опасения с точки зрения безопасности и стабильности.
Сложность сетевой конфигурации: настройка сети для контейнеров в Docker может быть сложной задачей, особенно при работе с множеством контейнеров и микросервисными архитектурами.
Монолитность приложений: на начальных этапах Docker-контейнеры иногда использовались для запуска монолитных приложений, что не всегда было наилучшей практикой для микросервисных архитектур.
Стоит отметить, что сообщество Docker активно работало над улучшением и разрешением этих проблем. В последующих версиях Docker были внедрены множество улучшений в области безопасности, изоляции и управления сетью. Критика стала движущей силой для развития Docker, и он сильно усовершенствовался с течением времени.
Был ещё странный момент в истории, когда в один день, без предупреждения и особых объяснений, Docker переименовали в Moby. Это вызвало у всех как минимум недоумение. Смена имени на GitHub и, соответственно, смена всех путей в коде была не очень тепло встречена сообществом и особенно контрибьюторами проекта. Начиная с этой точки коммерческая компания Docker стала активно искать пути, как заработать на своём продукте, не отказываясь от Open Source корней. |
Что есть Docker на самом деле
Docker — это инструмент, который используется для автоматизации развёртывания приложений в лёгких контейнерах, чтобы приложения могли эффективно работать в разных средах изолированно.
Docker состоит из нескольких ключевых компонентов:
Docker Engine: ядро (демон) Docker, управляющее контейнерами;
Docker Containers: изолированные среды, в которых работают приложения;
Docker Images: шаблоны для создания контейнеров;
Docker Registry: репозиторий для хранения и обмена Docker Images;
Docker CLI: консольная утилита для взаимодействия с вышеперечисленными компонентами.
Вокруг Docker сформировалась обширная экосистема инструментов и продуктов. Сервис Docker Hub стал настолько популярен среди разработчиков, что компании Docker в какой-то момент пришлось вводить лимиты на скачивание публичных образов — суммарное месячное количество скачиваний давно перевалило за 10 миллиардов.
Docker Desktop даёт возможность запускать и использовать компоненты Docker на системах, отличных от Linux, практически с тем же удобством, что в нативной среде. Он позволяет разработчикам и администраторам быстро разворачивать любые сервисы, делать сборку и тестирование единообразным способом вне зависимости от их рабочей ОС: будь то MacOS или Windows.
Также, например, Docker Compose позволяет определить и запустить множество контейнеров одновременно, в т.ч. и на множестве хостов, с помощью Docker Swarm. Kubernetes (который не так давно отказался от среды исполнения контейнеров Docker Engine в пользу Containerd) обеспечивает оркестрацию контейнеров в крупных и малых (привет Minikube!) кластерах.
Технологии ядра, используемые Docker
Помимо Golang, который вместе с сообществом внёс немалый вклад в успех проекта, Docker стоит на мощных плечах Linux. Он полагается на ряд ключевых технологий ядра операционной системы Linux для обеспечения изоляции и управления контейнерами:
Namespaces: технология ядра Linux, разработанная в достаточно далёком 2002 году. Docker использует namespaces, такие как PID (Process ID), Network и Mount, для создания изолированных пространств имён. Например, с использованием PID namespaces каждый контейнер видит только свои процессы, что обеспечивает изоляцию процессов между контейнерами.
Cgroups (Control Groups): технология, разработанная внутри компании Google еще в 2006 году. Контрольные группы используются Docker для ограничения ресурсов, доступных контейнеру: CPU, памяти и дискового пространства. Это позволяет предотвратить «голодание» ресурсов и обеспечить справедливое распределение мощностей между контейнерами.
Union File Systems: Docker использует «слоистые» файловые системы, такие как AUFS, OverlayFS и Overlay2, чтобы создавать легковесные и эффективные образы контейнеров. Это возможно благодаря тому, что они разделяют общие файлы между собой, экономя дисковое пространство.
Seccomp (Secure Computing Mode): для повышения безопасности Docker может использовать Seccomp. Он ограничивает доступ контейнера к системным вызовам, что позволяет уменьшить поверхность атаки и предотвратить выполнение опасных операций.
Capabilities: ядро Linux предоставляет разные возможности (capabilities) для выполнения привилегированных действий. Docker позволяет настраивать набор возможностей, доступных контейнеру, для более тонкой настройки безопасности.
Все эти технологии позволяют Docker создавать изолированные и легковесные контейнеры, работающие на одном ядре операционной системы, но при этом с высоким уровнем изоляции между собой. Docker обеспечивает среду, в которой приложения могут работать независимо друг от друга, при этом обеспечивается эффективное использование ресурсов и упрощение управления контейнерами.
Как правильно использовать Docker
Для максимальной эффективности и безопасности использования Docker соблюдайте следующие практики:
Изолируйте зависимости: каждый контейнер должен содержать только необходимые зависимости для запуска приложения. Используйте multistage-сборку, не оставляйте временные файлы или пакеты в образе.
Следуйте принципу одного процесса: каждый контейнер должен запускать только один процесс. Это облегчает отслеживание и управление контейнерами.
Обновляйте образы регулярно: регулярно обновляйте образы, чтобы получать последние обновления безопасности и исправления ошибок.
Практикуйте мониторинг и журналирование: используйте инструменты мониторинга и журналирования для отслеживания работы контейнеров и выявления проблем.
Не забывайте о безопасности: не игнорируйте базовые принципы безопасности, такие как ограничение доступа к хосту и контроль доступа к ресурсам.
Не запускайте контейнеры с привилегированными правами: избегайте использования флага --privileged, который предоставляет контейнеру полный (привилегированный) доступ к хосту.
Не храните секретные данные в образах: не включайте секретные ключи или пароли в Docker-образы. Используйте механизмы секретного хранения, такие как Vault или Docker Secrets.
Почему Docker совершил революцию
Docker изменил ландшафт виртуализации и стал незаменимым инструментом для DevOps-практик. Его легкость использования, эффективность и широкая экосистема делают его первым выбором для контейнеризации приложений. Унификация процессов сборки и доставки кода оказала значительное влияние на индустрию в целом, в конечном итоге позволив сэкономить огромное количество как человеко-часов, так и машинного (вычислительного) времени и — как следствие — денег.
Появление и популяризация Docker послужили толчком созданию множества новых технологий, таких как rkt, Podman, Kubernetes, kind, Rancher, Dokku. Также появилось много новых сервисов: начиная с публичных Container Registry от quay.io до gcr.io, заканчивая Serverless-сервисами — ECS, Cloud Run и так далее.
Спустя 10 лет огромный вклад Docker в развитие индустрии сложно переоценить, ещё сложнее сказать, что этот импульс принесёт нам в дальнейшем. Только одно можно с уверенностью сказать: «Революция действительно свершилась!»
Дополнительные ресурсы
Документация Docker;
Docker на GitHub;
Доклад Сергея Задорожного «Docker. Кому, зачем и как?»;
Telegram-канал DevOps | Яндекс Практикум.