Можно ли запускать Docker изнутри Docker?

185

Я запускаю Дженкинса в контейнере Docker. Интересно, может ли контейнер Jenkins быть хостом Docker? Я думаю о том, чтобы запустить новый докер-контейнер для каждой сборки интеграционного теста изнутри Jenkins (для запуска баз данных, брокеров сообщений и т. Д.). Таким образом, контейнеры должны быть закрыты после завершения интеграционных испытаний. Есть ли причина избегать запуска док-контейнеров из другого док-контейнера таким образом?

Johan
источник
11
Другой возможностью является монтирование сокета докера с хоста как тома в контейнере. Это позволяет вам создавать «одноуровневые» контейнеры и имеет преимущество в возможности повторного использования кэша.
Адриан Муат
4
Я обнаружил, что при использовании док-сокета с хоста, что в случаях, когда я хочу монтировать внешние тома, необходимо установить путь к тому относительно хоста, поскольку именно там запускается демон докера. Установка его относительно контейнера, который запускает контейнеры, не обязательно будет работать, если пути не совпадают.
Якоб Рунге

Ответы:

224

Запуск Docker внутри Docker (aka dind ), по возможности, следует избегать, если это вообще возможно. (Источник предоставлен ниже.) Вместо этого вы хотите настроить способ, с помощью которого ваш главный контейнер будет производить и взаимодействовать с ним. одноуровневыми контейнерами.

Жером Петаццони - автор функции, позволившей Docker запускаться в контейнере Docker, - на самом деле написал сообщение в блоге, в котором говорилось, что не следует этого делать . Описанный им вариант использования соответствует точному сценарию использования OP контейнера Docker CI, который должен запускать задания внутри других контейнеров Docker.

Петаццони перечисляет две причины, по которым Динд мешает:

  1. Он плохо взаимодействует с модулями безопасности Linux (LSM).
  2. Это создает несоответствие в файловых системах, что создает проблемы для контейнеров, созданных внутри родительских контейнеров.

Из этого поста в блоге он описывает следующую альтернативу:

[Самый простой способ] - просто выставить сокет Docker для вашего контейнера CI, привязав его с помощью -v флагу.

Проще говоря, когда вы запускаете свой CI-контейнер (Jenkins или другой), вместо того, чтобы взламывать что-то вместе с Docker-in-Docker, начните его с:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Теперь этот контейнер будет иметь доступ к сокету Docker и, следовательно, сможет запускать контейнеры. За исключением того, что вместо запуска «дочерних» контейнеров, он запускает «родственные» контейнеры.

predmijat
источник
1
Как выполнять команды Docker без, sudoкогда делать так? Спасибо
c4k
3
Вам нужно добавить пользователя в dockerгруппу: sudo usermod -aG docker $USER. Вам нужно будет сделать это после этого.
predmijat
2
Как перепихнуться изнутри в контейнер?
thiagowfx
1
@AlexanderMills Это то же самое, потому что ваш док-сокет также находится в том месте, /var/run/docker.sockкогда вы запускаете Docker для Mac на вашем MacOS-компьютере.
Брюс Сан
1
что насчет окон? у меня нет/var/run/docker.sock
Абдельхафид
54

Ранее я отвечал на аналогичный вопрос о том, как запустить Docker-контейнер внутри Docker .

Запустить докер внутри докера определенно можно. Главное, чтобы у вас runбыл внешний контейнер с дополнительными привилегиями (начиная с --privileged=true), а затем установить докер в этот контейнер.

Проверьте это сообщение в блоге для получения дополнительной информации: Docker-in-Docker .

Один из возможных вариантов использования для этого описан в этой записи . В блоге описывается, как создавать док-контейнеры в док-контейнере Jenkins.

Тем не менее, Docker внутри Docker не является рекомендуемым подходом для решения этого типа проблем. Вместо этого рекомендуется создать «одноуровневые» контейнеры, как описано в этом посте.

Таким образом, запуск Docker внутри Docker многие считали хорошим решением для такого рода проблем. Теперь, тенденция состоит в том, чтобы использовать «родственные» контейнеры вместо этого. Смотрите ответ @predmijat на этой странице для получения дополнительной информации.

wassgren
источник
Смотрите комментарий ниже о том, как избегать Docker в Docker.
Дэн Полтавски
6

Можно запускать Docker-in-Docker (DinD), и фактически у Docker (компании) есть официальный образ DinD для этого.

Однако предостережение заключается в том, что для этого требуется привилегированный контейнер, который, в зависимости от ваших потребностей в области безопасности, не может быть жизнеспособной альтернативой.

Альтернативное решение запуска Docker с использованием одноуровневых контейнеров (также называемых Docker-out-of-Docker или DooD) не требует привилегированного контейнера, но имеет несколько недостатков, связанных с тем, что вы запускаете контейнер из контекста, который является отличается от того, в котором он запущен (т.е. вы запускаете контейнер из контейнера, но он работает на уровне хоста, а не внутри контейнера).

Я написал блог с описанием плюсов и минусов DinD vs DooD здесь .

Сказав это, Nestybox (стартап, который я только что основал) работает над решением, которое безопасно выполняет настоящий Docker-in-Docker (без использования привилегированных контейнеров). Вы можете проверить это на www.nestybox.com .

ctalledo
источник
0

Да, мы можем запустить Docker в Docker, нам нужно прикрепить сокет Unix "/var/run/docker.sock", который демон Docker по умолчанию прослушивает как том, к родительскому докеру, используя "-v / var / run" /docker.sock:/var/run/docker.sock». Иногда могут возникнуть проблемы с разрешениями для сокета демона Docker, для которого вы можете написать «sudo chmod 757 /var/run/docker.sock».

А также потребуется запустить докер в привилегированном режиме, поэтому команды будут такими:

sudo chmod 757 /var/run/docker.sock

запуск докера --privileged = true -v /var/run/docker.sock:/var/run/docker.sock -it ...

Рену Сайни
источник