В этом блоге разберемся, как запустить Docker в Docker (DinD) тремя разными способами.
Зачем запускать Docker в Docker:
- Системы CI в контейнерах Docker: вы можете запускать локальные системы CI, такие как GitLab или Jenkins, в контейнерах Docker. Это позволяет создавать изолированные контейнеры для разных языков программирования и промежуточного программного обеспечения, упрощая процесс создания образов Docker для производственного использования.
- Среды-песочницы: Docker в Docker полезен, когда вам нужна среда-песочница, отделенная от среды хоста. Вы можете создать контейнер Docker внутри контейнера, что позволяет легко удалить всю среду, уничтожив контейнер.
Три способа запустить docker в docker:
- Запустите docker путем монтирования
docker.sock
(метод DooD) - Метод DinD
- Использование среды выполнения Nestybox sysbox Docker
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 на хосте виртуальной машины через docker.sock
Чтобы протестировать его настройку, используйте официальный образ Docker с Docker Hub. В нём есть двоичный файл 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 вы должны увидеть образ Ubuntu вместе с другими образами 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 сбрасывается. Чтобы этого избежать, вам нужно добавить разрешение в сценарии запуска системы.
Например, вы можете добавить команду в /etc/rc.local
так, чтобы она запускалась автоматически при каждом запуске сервера.
Кроме того, имейте в виду, что 666
разрешения открывают брешь в системе безопасности. Прежде чем внедрять их в проекты на производственном уровне, проконсультируйтесь со своей службой безопасности.
Docker в Docker с использованием DinD
Этот метод фактически создаёт дочерний контейнер внутри контейнера Docker. Используйте этот метод только в том случае, если вам действительно нужны контейнеры и образы внутри контейнера. В противном случае я бы посоветовал вам использовать первый подход.
Для этого вам просто нужно использовать официальный образ Docker с тегом dind
. Образ dind содержит необходимые утилиты для запуска Docker внутри контейнера Docker.
Следуйте инструкциям, чтобы протестировать настройку.
Примечание: Для этого требуется, чтобы ваш контейнер запускался в привилегированном режиме.
Шаг 1: Создайте контейнер с именем dind-test
with docker:dind
image
docker run --privileged -d --name dind-test docker:dind
- docker run: эта команда используется для запуска контейнера Docker из образа.
- —privileged: флаг —privileged используется для предоставления контейнеру Docker расширенных прав. Это необходимо при запуске Docker внутри Docker, поскольку требуется доступ к определённым системным возможностям, которые обычно ограничены в контейнерах.
- —name dind-test: этот флаг присваивает имя контейнеру Docker. В данном случае он называется «dind-test», что можно использовать для ссылки на контейнер в дальнейшем.
- -d: этот флаг запускает контейнер в автономном режиме, то есть он работает в фоновом режиме, а терминал остаётся доступным для других команд.
- docker:dind: это название образа Docker, используемого для создания контейнера. docker:stable-dind — это хорошо известный образ для запуска Docker в Docker. Он содержит Docker внутри себя, что позволяет запускать команды Docker в этом контейнере.
Шаг 2: Войдите в контейнер с помощью exec.
docker exec -it dind-test /bin/sh
Теперь выполните шаги с 2 по 4 из предыдущего метода и проверьте инструкции командной строки Docker и создание образа.
Docker в Docker с использованием среды выполнения Sysbox
Методы 1 и 2 имеют некоторые недостатки с точки зрения безопасности из-за запуска базовых контейнеров в привилегированном режиме. Nestybox пытается решить эту проблему с помощью среды выполнения 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?
Запуск Docker в Docker с использованием методов docker.sock и dind менее безопасен, так как у него есть полные права на демон Docker.
Как запустить docker в docker в Jenkins?
Как оказалось, этого можно добиться, указав в файле dokcer-compose.yml параметр для монтирования /var/run/docker.sock. Ниже приведён пример раздела «volume».
volumes:
- ${HOST_DOCKER}:/var/run/docker.sock
- ${HOST_JENKINS_DATA}:/var/jenkins_home
Как запустить docker в docker в GitLab?
Как оказалось, один из способов сделать это — использовать локальную систему для тома конфигурации, который будет смонтирован в контейнере gitlab-runner. В официальной документации GItLab в качестве примера команды запуска приводится следующее.
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
Смотрите документацию GitLab для получения подробной информации.
Источник: How To Run Docker in Docker Container [3 Easy Methods]