Как (и зачем) запускать Docker внутри Docker – CloudSavvy IT
Запуск Docker внутри Docker позволяет создавать образы и запускать контейнеры в уже контейнерной среде. Есть два возможных подхода для достижения этого в зависимости от того, хотите ли вы запустить дочерние или родственные контейнеры.
Доступ к Docker изнутри контейнера Docker чаще всего желателен в контексте систем CI и CD. Обычно агенты, которые запускают ваш конвейер, размещаются внутри контейнера Docker. В конечном итоге вы будете использовать стратегию Docker-in-Docker, если на одном из этапов конвейера затем будет создан образ или он будет взаимодействовать с контейнерами.
Образ Docker-in-Docker
Программы для Windows, мобильные приложения, игры - ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале - Подписывайтесь:)
Docker предоставляется в виде автономного образа через докер: dind тег на Docker Hub. Запуск этого образа даст вам работающую установку демона Docker внутри вашего нового контейнера. Он будет работать независимо от демона вашего хоста, который запускает контейнер dind, поэтому docker ps внутри контейнера будет давать разные результаты для docker ps на вашем хосте.
docker run -d –privileged –name docker -e DOCKER_TLS_CERTDIR = / certs -v docker-certs-ca: / certs / ca -v docker-certs-client: / certs / client docker: dind
При таком использовании Docker-in-Docker есть одна большая оговорка: вам нужно использовать привилегированный режим. Это ограничение применяется даже если вы используете бескорневые контейнеры. Привилегированный режим активируется флагом –privileged в команде, показанной выше.
Использование привилегированного режима дает контейнеру полный доступ к вашей хост-системе. Это необходимо в сценарии Docker-in-Docker, чтобы ваш внутренний Docker мог создавать новые контейнеры. Однако в некоторых средах это может быть неприемлемым риском для безопасности.
Есть другие проблемы с dind тоже. В некоторых системах могут возникать конфликты с модулями безопасности Linux (LSM), такими как AppArmor и SELinux. Это происходит, когда внутренний Docker применяет политики LSM, которые внешний демон не может предвидеть.
Другая проблема касается файловых систем контейнеров. Внешний демон будет работать поверх обычной файловой системы вашего хоста, такой как ext4. Однако все его контейнеры, включая внутренний демон Docker, будут находиться в файловой системе копирования при записи (CoW). Это может создать несовместимость, если внутренний демон настроен на использование драйвера хранилища, который нельзя использовать поверх существующей файловой системы CoW.
Установка Docker Socket вашего хоста вместо
С проблемами, связанными с dind, лучше всего справляться, полностью избегая его использования. Во многих сценариях вы можете добиться желаемого эффекта, установив сокет Docker вашего хоста в обычный контейнер докеров:
docker run -d –name docker -v /var/run/docker.sock:/var/run/docker.sock docker: latest
Интерфейс командной строки Docker внутри образа докера взаимодействует с сокетом демона Docker, который он находит в /var/run/docker.sock. Подключение сокета вашего хоста к этому пути означает, что команды докеров, выполняемые внутри контейнера, будут выполняться против вашего существующего демона Docker.
Это означает, что контейнеры, созданные внутренним Docker, будут находиться в вашей хост-системе вместе с самим контейнером Docker. Все контейнеры будут существовать как братья и сестры, даже если будет казаться, что вложенный Docker является дочерним по отношению к родителю. Запуск docker ps даст одинаковые результаты, независимо от того, запущен ли он на хосте или внутри вашего контейнера.
Этот метод устраняет проблемы реализации dind. Это также устраняет необходимость использования привилегированного режима, хотя установка сокета Docker сама по себе является потенциальной проблемой безопасности. Все, что имеет доступ к сокету, может отправлять инструкции демону Docker, предоставляя возможность запускать контейнеры на вашем хосте, извлекать изображения или удалять данные.
Когда использовать каждый подход
Docker-in-Docker через dind исторически широко использовался в средах CI. Это означает, что «внутренние» контейнеры имеют уровень изоляции от хоста. Один контейнер CI runner поддерживает каждый конвейерный контейнер, не загрязняя демон Docker хоста.
Хотя это часто работает, это чревато побочными эффектами, а не предполагаемым вариантом использования dind. Он был добавлен для облегчения разработки самого Docker, а не для обеспечения поддержки конечным пользователям вложенных установок Docker.
В соответствии с Джером Петаццони, создатель реализации dind, использование подхода на основе сокетов должно быть вашим предпочтительным решением. Bind монтирование сокета демона вашего хоста безопаснее, гибче и так же полнофункционально, как запуск контейнера dind.
Если ваш вариант использования означает, что вам абсолютно необходим dind, есть более безопасный способ его развернуть. Современный Sysbox проект – это выделенная среда выполнения контейнера, которая может вкладывать другие среды выполнения без использования привилегированного режима. Контейнеры Sysbox становятся похожими на виртуальные машины, поэтому они могут поддерживать программное обеспечение, которое обычно запускается без операционной системы на физической или виртуальной машине. Сюда входят Docker и Kubernetes без какой-либо специальной настройки.
Заключение
Запуск Docker в Docker – довольно распространенное требование. Скорее всего, вы увидите это при настройке серверов CI, которым необходимо поддерживать сборку образов контейнера из созданных пользователем конвейеров.
Использование docker: dind дает вам независимый демон Docker, работающий внутри своего собственного контейнера. Он эффективно создает дочерние контейнеры, которые напрямую не видны с хоста. Хотя кажется, что он предлагает сильную изоляцию, на самом деле dind таит в себе множество краевых проблем и проблем безопасности. Это связано с взаимодействием с операционной системой Docker.
Установка сокета Docker вашего хоста в контейнер, который включает двоичный файл докера, является более простой и предсказуемой альтернативой. Это позволяет вложенному процессу Docker запускать контейнеры, которые становятся его братьями и сестрами. При использовании подхода на основе сокетов никаких дополнительных настроек не требуется.
Программы для Windows, мобильные приложения, игры - ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале - Подписывайтесь:)