Почему Docker-in-Docker считается плохим?

22

В августе 2013 года Жером Петаццони создал Docker в Docker, dindдля краткости это позволило создавать контейнеры Docker внутри Docker Containers, эта функциональность оказалась очень популярной, в результате чего репозиторий Jérôme GitHub получил более тысячи звезд и триста вилок.

Начиная с версии Docker 1.8, выпущенной спустя два года в августе 2015 года, Docker в Docker напрямую поддерживается Docker из коробки. Тем не менее, использование Docker в Docker сопровождается предупреждением, которое, по-видимому, связано с постом Жерома: Использование Docker-in-Docker для вашей компьютерной конфигурации или среды тестирования? Подумай дважды. в котором рассматриваются причины, по которым Docker в Docker не является отличным выбором для непрерывной интеграции.

Почему использование Docker в Docker считается плохим? Это просто случай, чтобы избежать Черепах до самого конца? или соображения производительности?

Черепахи все время вниз!

Ричард Слейтер
источник
Я не знаком с докером кроме того, что читал об этом. Но, подумав об этом, кажется, что у вас есть хост-ОС на аппаратном уровне, хост загружает контейнер, а затем этот контейнер загружает другой. Похоже, что накладные расходы, учитывая, что идея заключается в развертывании образа. Картинка картины Картинка ... Также интересны актуальные ответы на этот вопрос.
Нет возврата нет возврата
Вы связываете ответ на свой вопрос ... или я что-то упустил?
AnoE

Ответы:

17

Проблемы непрерывной интеграции

Вкратце: Docker в Docker (dind) плохо справляется с параллелизмом.

Причина, по которой вы не должны использовать dind для CI, заключается в том, что Docker был разработан для того, чтобы иметь эксклюзивный доступ к каталогу, который он использует для хранения (обычно /var/lib/docker). Dind не уважает это, поскольку все дочерние процессы используют этот каталог одновременно. Каждый раз, когда вы перестраиваете (например, из CI), все, что связано с вашим приложением в этом каталоге, может быть уничтожено и принудительно начинаться с нуля. Как бы это понравилось вашим пользователям, если бы они ввели свои платежные реквизиты, нажали «Купить» и вдруг оказались на экране входа в систему, как будто они никогда ничего не делали? Это просто не хороший UX. Две перестройки происходят одновременно? Это действительно плохо кончится для всех участников (включая вашу целостность данных).

Другие проблемы

По ссылке, опубликованной ОП, проблемы безопасности возникают, поскольку система будет пытаться применять политики безопасности очень «CSS-подобным» образом, когда нижний контейнер может иметь доступ к ресурсам внешнего контейнера, если это явно не запрещено. Помните, когда вы могли получить доступ к ресурсам веб-сервера, выполнив что-то вроде «mywebsite.com/../another_folder/private_resource.txt»? Кроме того, иногда файловые системы просто не играют друг с другом, когда они вложены таким образом.

Исправление

К счастью, в блоге ОП есть хорошее решение проблемы. Если ваши потребности не удовлетворяются «сборкой / запуском / отправкой Docker-контейнеров из самой вашей системы CI, работающей на Docker», вы можете использовать -vрежим (добавить том данных в ваш контейнер) на сокете Docker (обычно /var/run/docker.sock:/var/run/docker.sock), чтобы разрешить вид Доступ вам нужен к «общему» объему данных. Эти контейнеры будут запускаться рядом с родительским, а не под ним, вызывая синхронный ввод-вывод. Теперь у вас есть то же самое (почти), что и у dind, но без недостатков, которые идут с Docker, не предназначенным для параллелизма.

Ссылка (из OP): Использование Docker-in-Docker для вашей CI или среды тестирования? Подумай дважды.

Питер Г
источник
Вот один из примеров описанного подхода (dood) для Дженкинса, однако при его использовании сообщалось о нескольких проблемах hub.docker.com/r/psharkey/jenkins-dood
rombob
Из этого объяснения я до сих пор не могу точно сказать, следует ли избегать использования dind в моем случае ... Мой агент сборки работает в контейнере Docker и выполняет следующие действия: 1. Checkout repo.2. Start container & mount repo.3. Для Run some build-/test script inside container.каждого агента всегда есть только один ' Dind'-контейнер работает. Есть ли еще проблемы с dind в этом сценарии использования?
helmesjo