В этом блоге я расскажу вам о шагах, необходимых для запуска docker в docker с использованием трех различных методов.
Запуск Docker в контейнере Docker
Существует три способа достижения docker в docker
- Запуск docker путем монтирования
docker.sock
(Метод DooD) - Docker dind method
- Использование Nestybox sysbox Docker runtime
Давайте рассмотрим каждый вариант подробно. Чтобы опробовать эту настройку, убедитесь, что на вашем узле установлен docker.
Способ 1: Docker в Docker с помощью [/var/run/docker.sock]
Что такое /var/run/docker.sock?
/var/run/docker.sock
является сокетом Unix по умолчанию. Сокеты предназначены для взаимодействия между процессами на одном хосте.
Демон Docker по умолчанию прослушивает docker.sock
. Если вы находитесь на том же хосте, где работает демон Docker, вы можете использовать команду /var/run/docker.sock
для управления контейнерами. это означает, что вы можете подключить сокет Docker с хоста в контейнер
Например, если вы выполните следующую команду, она вернет версию модуля Docker.
curl --unix-socket /var/run/docker.sock http://localhost/version
Теперь, когда у вас есть некоторое понимание того, что такое docker.sock
, давайте посмотрим, как запустить docker в docker с помощью docker.sock
Чтобы запустить docker внутри docker, все, что вам нужно сделать, это запустить docker с сокетом Unix по умолчанию docker.sock
в виде тома.
Например
docker run -v /var/run/docker.sock:/var/run/docker.sock \
-ti docker
docker.sock
, это означает, что у него больше привилегий по сравнению с вашим демоном Docker. Поэтому при использовании в реальных проектах понимайте риски безопасности и используйте это.Теперь из контейнера вы сможете выполнять команды docker для сборки и отправки образов в реестр.
В этом случае фактические операции Docker выполняются на узле виртуальной машины, на котором выполняется базовый контейнер Docker, а не внутри контейнера. Это означает, что, несмотря на то, что вы выполняете команды docker из контейнера, вы указываете клиенту Docker подключиться к docker-engine хоста виртуальной машины через docker.sock
Чтобы протестировать его настройку, используйте официальный образ Docker из docker hub. В нем есть docker — двоичный файл docker.
Выполните следующие действия, чтобы проверить настройку.
Шаг 1: Запуск контейнера Docker в интерактивном режиме, монтирование docker.sock
по мере объема. Мы будем использовать официальный образ Docker.
docker run -v /var/run/docker.sock:/var/run/docker.sock -ti docker
Шаг 2: Оказавшись внутри контейнера, выполните следующую команду docker.
docker pull ubuntu
Шаг 3: При перечислении образов Docker он должен отображаться вместе с другими образами Docker на виртуальной машине узла.
docker images
Шаг 4: Теперь создайте Dockerfile внутри тестового каталога.
mkdir test && cd test
vi Dockerfile
Скопируйте следующее содержимое файла Dockerfile, чтобы протестировать сборку образа из контейнера.
FROM ubuntu:18.04
LABEL maintainer="Bibin Wilson <bibinwilsonn@gmail.com>"
RUN apt-get update && \
apt-get -qy full-upgrade && \
apt-get install -qy curl && \
apt-get install -qy curl && \
curl -sSL https://get.docker.com/ | sh
Сборка файла Dockerfile
docker build -t test-image .
Ошибка разрешения docker.sock
Во время использования docker.sock
Вы можете получить ошибку «Отказано в разрешении». В этом случае вам нужно изменить разрешение docker.sock на следующее.
sudo chmod 666 /var/run/docker.sock
Кроме того, вам, возможно, придется добавить флаг —privileged для предоставления привилегированного доступа.
Разрешение doccker sock сбрасывает сервер. Чтобы этого избежать, необходимо добавить права доступа к скриптам запуска системы.
Например, вы можете добавить команду в /etc/rc.local
чтобы он запускался автоматически при каждом запуске вашего сервера.
Кроме того, имейте в виду, что 666
Разрешения открывают брешь в безопасности. Проконсультируйтесь со своей командой по безопасности перед внедрением в проекты производственного уровня.
Способ 2: Docker в Docker с помощью DinD
Этот метод фактически создает дочерний контейнер внутри контейнера Docker. Используйте этот метод только в том случае, если вы действительно хотите иметь контейнеры и изображения внутри контейнера. В противном случае я бы посоветовал вам использовать первый подход.
Для этого нужно просто использовать официальный образ docker с dind
ярлык. Образ dind запекается с необходимыми утилитами для запуска Docker внутри контейнера Docker.
Следуйте инструкциям по проверке настройки.
Шаг 1: Создание контейнера с именем dind-test
с docker:dind
образ
docker run --privileged -d --name dind-test docker:dind
Шаг 2: Авторизуйтесь в контейнере с помощью exec.
docker exec -it dind-test /bin/sh
Теперь выполните шаги со 2 по 4 из предыдущего метода и проверьте инструкции командной строки Docker и сборку образа.
--privileged
: предоставляет полный доступ к ресурсам хоста (необходимо для работы Docker внутри). Он хорош для систем CI или изолированных сред. Он небезопасен для производственной среды из-за угрозы безопасности, вызванного полным доступом.Способ 3: Docker в Docker с помощью Sysbox Runtime
Методы 1 и 2 имеют некоторые недостатки с точки зрения безопасности из-за запуска базовых контейнеров в привилегированном режиме. Nestybox пытается решить эту проблему, используя среду выполнения sysbox Docker.
Если вы создадите контейнер с помощью среды выполнения Nestybox sysbox, он может создать виртуальные среды внутри контейнера, который способен запускать systemd, docker, kubernetes без привилегированного доступа к базовой хост-системе.
Объяснение sysbox требует значительного понимания, поэтому я исключил его из этой статьи. Пожалуйста, обратитесь к этой странице, чтобы получить полное представление о sysbox
Чтобы получить общее представление, давайте теперь попробуем пример
Шаг 1: Установите среду выполнения sysbox. Обратитесь к этой странице, чтобы получить последние официальные инструкции по установке среды выполнения sysbox.
Шаг 2: После того как у вас будет доступна среда выполнения sysbox, все, что вам нужно сделать, это запустить контейнер docker с флагом времени выполнения sysbox, как показано ниже. Здесь мы используем официальный образ docker dind.
docker run --runtime=sysbox-runc --name sysbox-dind -d docker:dind
Шаг 3: Теперь перенесите сеанс exec в контейнер sysbox-dind.
docker exec -it sysbox-dind /bin/sh
Теперь вы можете попробовать создать образы с помощью Dockerfile, как показано в предыдущих методах.
Ключевые соображения
- Используйте Docker в Docker только в том случае, если это является обязательным требованием. Проведите POC и достаточное количество тестов, прежде чем переходить на метод Docker-in-Docker.
- При использовании контейнеров в привилегированном режиме убедитесь, что вы получили необходимые разрешения от групп безопасности предприятия о том, что вы планируете делать.
- При использовании Docker в Docker с подами Kubernetes возникают определенные проблемы. Обратитесь к этому блогу, чтобы узнать больше об этом.
- Если вы планируете использовать Nestybox (Sysbox), убедитесь, что он протестирован и одобрен корпоративными архитекторами/командами безопасности.
Docker в примерах использования Docker
Ниже приведено несколько примеров использования для запуска docker в контейнере Docker.
- Одним из возможных вариантов использования docker в docker является конвейер CI/CD, где необходимо создавать и отправлять образы Docker в реестр контейнеров после успешной сборки кода.
- Современные системы CI/CD поддерживают агенты или средства выполнения тестов на основе Docker, в которых можно выполнять все этапы сборки внутри контейнера и создавать образы контейнеров внутри агента контейнера.
- Создание образов Docker с помощью виртуальной машины довольно просто. Однако, если вы планируете использовать динамические агенты на основе Jenkins Docker для конвейеров CI/CD, docker в docker является обязательной функциональностью.
- Изолированные среды.
- В экспериментальных целях на локальной рабочей станции разработки.
Часто задаваемые вопросы
Ниже приведены некоторые часто задаваемые вопросы о докере в докере.
Безопасно ли запускать Docker в Docker?
Запуск docker в docker с помощью docker.sock
и dind
Метод менее безопасен, так как он имеет полные привилегии над демоном Docker
Как запустить docker в docker в Jenkins?
Вы можете использовать настройку динамического агента Docker Jenkins и подключить docker.sock к контейнеру агента для выполнения команд Docker из контейнера агента.
Есть ли какое-либо влияние на производительность при запуске Docker в Docker
Производительность контейнера никак не влияет на используемые методы. Тем не менее, базовое оборудование определяет производительность.
Заключение
В этом блоге мы рассмотрели три различных метода запуска Docker в Docker. При использовании этих методов в производственных средах всегда консультируйтесь с группой безопасности предприятия по обеспечению соответствия.
Если вы используете Kubernetes, вы можете попробовать создать образы Docker с помощью Kaniko. Который не требует привилегированного доступа к хосту.