Перейти к содержимому
Главная страница » Запуск Docker in Docker

Запуск Docker in Docker

В этом блоге разберемся, как запустить Docker в Docker (DinD) тремя разными способами.

Зачем запускать Docker в Docker:

  1. Системы CI в контейнерах Docker: вы можете запускать локальные системы CI, такие как GitLab или Jenkins, в контейнерах Docker. Это позволяет создавать изолированные контейнеры для разных языков программирования и промежуточного программного обеспечения, упрощая процесс создания образов Docker для производственного использования.
  2. Среды-песочницы: Docker в Docker полезен, когда вам нужна среда-песочница, отделенная от среды хоста. Вы можете создать контейнер Docker внутри контейнера, что позволяет легко удалить всю среду, уничтожив контейнер.

Три способа запустить docker в docker:

  1. Запустите docker путем монтирования docker.sock (метод DooD)
  2. Метод DinD
  3. Использование среды выполнения Nestybox sysbox Docker
Давайте подробно рассмотрим каждый вариант. Убедитесь, что на вашем хосте установлен 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
  1. docker run: эта команда используется для запуска контейнера Docker из образа.
  2. —privileged: флаг —privileged используется для предоставления контейнеру Docker расширенных прав. Это необходимо при запуске Docker внутри Docker, поскольку требуется доступ к определённым системным возможностям, которые обычно ограничены в контейнерах.
  3. —name dind-test: этот флаг присваивает имя контейнеру Docker. В данном случае он называется «dind-test», что можно использовать для ссылки на контейнер в дальнейшем.
  4. -d: этот флаг запускает контейнер в автономном режиме, то есть он работает в фоновом режиме, а терминал остаётся доступным для других команд.
  5. 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]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *