Jak (i dlaczego) uruchomić Docker Inside Docker - CloudSavvy IT
Uruchamianie Dockera w Dockerze umożliwia tworzenie obrazów i uruchamianie kontenerów w już skonteneryzowanym środowisku. Istnieją dwa możliwe podejścia, aby to osiągnąć, w zależności od tego, czy chcesz uruchomić kontenery potomne, czy rodzeństwo.
Dostęp do Dockera z wnętrza kontenera Dockera jest najczęściej pożądany w kontekście systemów CI i CD. Często zdarza się, że agenty, które uruchamiają potok, są hostowane w kontenerze Dockera. W końcu użyjesz strategii Docker-in-Docker, jeśli którykolwiek z etapów potoku następnie obrazuje lub wchodzi w interakcję z kontenerami.
streszczenie
Obraz Docker-in-Docker
Docker jest dostarczany jako samodzielny obraz przez docker:dind
w Centrum Dockera. Uruchomienie tego obrazu zapewni działającą instalację demona Docker w nowym kontenerze. Będzie działać niezależnie od demona hosta, który uruchamia dind
pojemnik zatem docker ps
wewnątrz pojemnika da różne wyniki, aby docker ps
na twoim hoście.
docker run -d --privileged --name docker -e DOCKER_TLS_CERTDIR = / certs -v docker-certs-ca: / certs / ca -v docker-certs-client: / certs / klient docker: dind
Jedną z głównych wad korzystania z platformy Docker-in-Docker w ten sposób jest konieczność korzystania z trybu uprzywilejowanego. To ograniczenie ma zastosowanie, nawet jeśli używasz kontenerów bez roota. Tryb uprzywilejowany jest aktywowany przez --privileged
flaga w powyższym poleceniu.
Korzystanie z trybu uprzywilejowanego zapewnia kontenerowi pełny dostęp do systemu hosta. Jest to konieczne w scenariuszu Docker-in-Docker, aby wewnętrzny Docker mógł tworzyć nowe kontenery. W niektórych środowiskach może to jednak stanowić niedopuszczalne zagrożenie bezpieczeństwa.
Są inne problemy z dind
zbyt wiele. Niektóre systemy mogą napotkać konflikty z modułami zabezpieczeń systemu Linux (LSM), takimi jak AppArmor i SELinux. Dzieje się tak, gdy wewnętrzny Docker stosuje zasady LSM, których zewnętrzny demon nie może przewidzieć.
Kolejnym wyzwaniem są systemy plików kontenerów. Zewnętrzny demon będzie działał w normalnym systemie plików hosta, takim jak ext4
. Jednak wszystkie jego kontenery, w tym wewnętrzny demon Docker, będą opierać się na systemie plików kopiowania przy zapisie (CoW). Może to powodować niezgodności, jeśli wewnętrzny demon jest skonfigurowany do używania pilopamięć, której nie można używać w istniejącym systemie plików CoW.
Zamiast tego zamontuj wtyczkę Docker hosta
Wyzwania związane z dind
najlepiej leczyć całkowicie unikając jego stosowania. W wielu scenariuszach można osiągnąć pożądany efekt, montując gniazdo Docker hosta w docker
pojemnik:
docker run -d --name docker -v /var/run/docker.sock:/var/run/docker.sock okno dokowane: najnowsze
Docker CLI wewnątrz docker
obraz wchodzi w interakcję z gniazdem demona Docker, który znajduje w /var/run/docker.sock
. Zamontowanie gniazda hosta na tej ścieżce oznacza docker
polecenia uruchomione w kontenerze będą działać na istniejącym demonie Docker.
Oznacza to, że kontenery utworzone przez wewnętrzny Docker będą znajdować się w systemie hosta, obok samego kontenera Docker. Wszystkie kontenery będą istnieć jako rodzeństwo, mimo że wygląda na to, że zagnieżdżony Docker jest dzieckiem rodzica. Funkcjonowanie docker ps
da te same wyniki, niezależnie od tego, czy jest uruchamiany na hoście, czy w kontenerze.
Ta technika łagodzi trudności we wdrażaniu dind
. Eliminuje również potrzebę korzystania z trybu uprzywilejowanego, chociaż samo zamontowanie gniazda Docker stanowi potencjalny problem z bezpieczeństwem. Każdy, kto ma dostęp do gniazda, może wysyłać instrukcje do demona Docker, zapewniając możliwość uruchamiania kontenerów na hoście, wyodrębniania obrazów lub usuwania danych.
Kiedy stosować poszczególne podejścia
Docker-in-Docker przez dind
zawsze był szeroko stosowany w środowiskach CI. Oznacza to, że kontenery „wewnętrzne” mają warstwę izolacji od hosta. Pojedynczy kontener środowiska uruchomieniowego CI obsługuje każdy kontener potoku bez zanieczyszczania demona platformy Docker hosta.
Chociaż to często działa, jest obarczone skutkami ubocznymi i nie jest zamierzonym przypadkiem użycia dind
. Został dodany w celu ułatwienia rozwoju samego Dockera, a nie w celu zapewnienia użytkownikom końcowym obsługi zagnieżdżonych instalacji Dockera.
Według Jérôme'a Petazzoniego, twórcy dind
implementacji, przyjęcie podejścia opartego na gniazdach powinno być preferowanym rozwiązaniem. Wiązanie demona gniazda hosta jest bezpieczniejsze, bardziej elastyczne i tak samo kompletne, jak rozpoczęcie a dind
odbiorca.
Jeśli Twój przypadek użycia oznacza, że absolutnie potrzebujesz dind
, istnieje bezpieczniejszy sposób jego wdrożenia. Nowoczesny projekt Sysbox to dedykowane środowisko wykonawcze kontenera, które może zagnieżdżać inne środowiska wykonawcze bez korzystania z trybu uprzywilejowanego. Kontenery Sysbox stają się podobne do maszyn wirtualnych, dzięki czemu mogą obsługiwać oprogramowanie, które zwykle działa bez systemu operacyjnego na maszynie fizycznej lub wirtualnej. Obejmuje to Docker i Kubernetes bez żadnej specjalnej konfiguracji.
Wnioski
Uruchamianie Dockera w Dockerze jest stosunkowo powszechnym wymaganiem. Prawdopodobnie zobaczysz to podczas konfigurowania serwerów CI, które powinny obsługiwać kompilacje obrazów kontenerów z potoków utworzonych przez użytkownika.
Za pomocą docker:dind
daje Ci niezależnego demona Docker działającego we własnym kontenerze. Skutecznie tworzy kontenery podrzędne, które nie są bezpośrednio widoczne z hosta. Chociaż wydaje się oferować silną izolację, dind
jest w rzeczywistości domem dla wielu peryferyjnych problemów i problemów z bezpieczeństwem. Wynika to z interakcji systemu operacyjnego Docker.
Zamontuj gniazdo Docker hosta w kontenerze, który zawiera docker
binarny jest prostszą i bardziej przewidywalną alternatywą. Pozwala to zagnieżdżonemu procesowi Docker na uruchamianie kontenerów, które stają się jego własnym rodzeństwem. W przypadku podejścia opartego na gniazdach nie są potrzebne żadne inne parametry.