Ist es in Ordnung, Docker von Docker aus auszuführen?

183

Ich führe Jenkins in einem Docker-Container aus. Ich frage mich, ob es in Ordnung ist, wenn der Jenkins-Container auch ein Docker-Host ist. Ich denke darüber nach, für jeden Integrationstest-Build in Jenkins einen neuen Docker-Container zu starten (um Datenbanken, Nachrichtenbroker usw. zu starten). Die Container sollten daher nach Abschluss der Integrationstests heruntergefahren werden. Gibt es einen Grund, Docker-Container nicht auf diese Weise aus einem anderen Docker-Container heraus auszuführen?

Johan
quelle
11
Eine andere Möglichkeit besteht darin, den Docker-Socket vom Host als Volume im Container bereitzustellen. Auf diese Weise können Sie "Geschwister" -Container erstellen und haben den Vorteil, dass Sie den Cache wiederverwenden können.
Adrian Mouat
4
Ich habe festgestellt, dass bei Verwendung des Docker-Sockets vom Host aus in Fällen, in denen ich externe Volumes bereitstellen möchte, der Volume-Pfad relativ zum Host festgelegt werden muss, da dort der Docker-Daemon ausgeführt wird. Das Festlegen relativ zu dem Container, der Container startet, funktioniert nicht unbedingt, es sei denn, die Pfade stimmen überein.
Jakob Runge

Antworten:

223

Das Ausführen von Docker in Docker (auch bekannt als dind ) sollte nach Möglichkeit vermieden werden, wenn dies überhaupt möglich ist. (Quelle unten angegeben.) Stattdessen möchten Sie eine Möglichkeit für Ihren Hauptcontainer einrichten, um Geschwistercontainer zu produzieren und mit ihnen zu kommunizieren .

Jérôme Petazzoni - der Autor der Funktion, die es Docker ermöglichte, in einem Docker-Container zu laufen - schrieb tatsächlich einen Blog-Beitrag, in dem er sagte, er solle es nicht tun . Der von ihm beschriebene Anwendungsfall entspricht dem genauen Anwendungsfall des OP für einen CI Docker-Container, der Jobs in anderen Docker-Containern ausführen muss.

Petazzoni nennt zwei Gründe, warum Dind problematisch ist:

  1. Es funktioniert nicht gut mit Linux Security Modules (LSM).
  2. Es entsteht eine Nichtübereinstimmung in Dateisystemen, die Probleme für die in übergeordneten Containern erstellten Container verursacht.

In diesem Blog-Beitrag beschreibt er die folgende Alternative:

[Der] einfachste Weg besteht darin, den Docker-Socket einfach Ihrem CI-Container auszusetzen, indem Sie ihn mit dem -vFlag binden .

Einfach ausgedrückt, wenn Sie Ihren CI-Container (Jenkins oder andere) starten, anstatt etwas zusammen mit Docker-in-Docker zu hacken, beginnen Sie mit:

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

Jetzt hat dieser Container Zugriff auf den Docker-Socket und kann daher Container starten. Anstatt "untergeordnete" Container zu starten, werden "Geschwister" -Container gestartet.

predmijat
quelle
1
Wie kann man Docker-Befehle ausführen, ohne dies zu sudotun? Vielen Dank
c4k
3
Sie müssen Benutzer zur dockerGruppe hinzufügen : sudo usermod -aG docker $USER. Danach müssen Sie sich erneut anmelden.
Predmijat
2
Wie kann ich mich innerhalb eines Cointainers neu anmelden?
Thiagowfx
1
@AlexanderMills Es ist dasselbe, weil sich Ihr Docker-Socket auch befindet, /var/run/docker.sockwenn Sie Docker für Mac auf Ihrem Macos-Computer ausführen.
Bruce Sun
1
Was ist mit Windows? Ich habe nicht/var/run/docker.sock
Abdelhafid
53

Ich habe zuvor eine ähnliche Frage zum Ausführen eines Docker-Containers in Docker beantwortet .

Docker in Docker auszuführen ist definitiv möglich. Die Hauptsache ist, dass Sie runden äußeren Container mit zusätzlichen Berechtigungen (beginnend mit --privileged=true) und dann Docker in diesem Container installieren.

Weitere Informationen finden Sie in diesem Blogbeitrag: Docker-in-Docker .

Ein möglicher Anwendungsfall hierfür ist in diesem Eintrag beschrieben . Der Blog beschreibt, wie Docker-Container in einem Jenkins-Docker-Container erstellt werden.

Docker in Docker ist jedoch nicht der empfohlene Ansatz, um diese Art von Problemen zu lösen. Stattdessen wird empfohlen, "Geschwister" -Container zu erstellen, wie in diesem Beitrag beschrieben

Das Ausführen von Docker in Docker wurde von vielen als eine gute Lösung für diese Art von Problemen angesehen. Jetzt geht der Trend dahin, stattdessen "Geschwister" -Container zu verwenden. Weitere Informationen finden Sie in der Antwort von @predmijat auf dieser Seite .

wassgren
quelle
Lesen Sie den Kommentar unten zum Vermeiden von Docker in Docker.
Dan Poltawski
5

Es ist in Ordnung, Docker-in-Docker (DinD) auszuführen, und tatsächlich hat Docker (das Unternehmen) ein offizielles DinD-Image dafür.

Die Einschränkung besteht jedoch darin, dass ein privilegierter Container erforderlich ist, der je nach Ihren Sicherheitsanforderungen möglicherweise keine praktikable Alternative darstellt.

Die alternative Lösung zum Ausführen von Docker mithilfe von Geschwistercontainern (auch bekannt als Docker-out-of-Docker oder DooD) erfordert keinen privilegierten Container, weist jedoch einige Nachteile auf, die sich aus der Tatsache ergeben, dass Sie den Container in einem bestimmten Kontext starten unterscheidet sich von dem, in dem es ausgeführt wird (dh Sie starten den Container aus einem Container heraus, aber er wird auf Hostebene ausgeführt, nicht innerhalb des Containers).

Ich habe hier einen Blog geschrieben, in dem die Vor- und Nachteile von DinD vs DooD beschrieben werden .

Trotzdem arbeitet Nestybox (ein Startup, das ich gerade gegründet habe) an einer Lösung, die echten Docker-in-Docker sicher ausführt (ohne privilegierte Container zu verwenden). Sie können es unter www.nestybox.com überprüfen .

ctalledo
quelle
0

Ja, wir können Docker in Docker ausführen. Wir müssen das Unix-Socket "/var/run/docker.sock" anhängen, auf dem der Docker-Dämon standardmäßig als Volume dem übergeordneten Docker mit "-v / var / run" zuhört /docker.sock:/var/run/docker.sock ". Manchmal können Berechtigungsprobleme für Docker-Daemon-Sockets auftreten, für die Sie "sudo chmod 757 /var/run/docker.sock" schreiben können.

Außerdem müsste der Docker im privilegierten Modus ausgeführt werden, sodass die Befehle wie folgt lauten:

sudo chmod 757 /var/run/docker.sock

Docker-Lauf --privileged = true -v /var/run/docker.sock:/var/run/docker.sock -it ...

Renu Saini
quelle