Derzeit stelle ich einige virtuelle Maschinen von VirtualBox auf Docker um. Der Hauptgrund für mich ist die Tatsache, dass Container weniger Speicher und Ressourcen benötigen als Container.

Die meistens Maschinen konnte ich ohne Probleme umstellen. Nur Jenkins machte mir ein paar Probleme. Der Grund dafür ist, dass ich die Jenkins-Pipeline (Buildjobs) mit Docker ausführe. Dadurch wird ein Prozess nicht mehr direkt auf der VM ausgeführt, sondern in einem Docker-Container in der VM.

Es gibt verschiedene Artikel, um Jenkins in Docker auszuführen:

In meinem Falle nutze ich Docker auf meinem Hostsystem und reiche Docker an den Jenkins-Container durch. Der Aufruf dazu sieht grundlegend so aus:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(which docker):/usr/bin/docker \
  -p 8080:8080 \
  -p 50000:50000 jenkins/jenkins:lts

Durch den -v Parameter übergeben wir den Docker-Socket und auch das Programm, sodass die Kommandozeile den Befehl docker findet.
Docker.sock ist ein Unix-Socket, wodurch andere Anwendung (und hier unsere Container) mit dem Docker-Dienst auf dem Host kommunizieren können.

Wenn ihr nun eine Shell in eurem Container öffnet (oder eine Pipeline in Jenkins verwendet), werdet ihr den Befehl docker help ausführen können.
Ein Befehl wie docker ps -a wird fehlschlagen, da die Berechtigungen nicht ausreichen.

Container als root ausführen

Daher müssen wir den Aufruf anpassen und den Container als root ausführen. Somit ergänzen wir der Parameter -u root:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(which docker):/usr/bin/docker \
  -p 8080:8080 \
  -p 50000:50000 \
  -u root jenkins/jenkins:lts

Achtung: Einen Container als Root auszuführen und ihm die Rechte über docker.sock zu geben kann eine Sicherheitslücke darstellen. Ihr solltet daher sicherstellen, dass nur bestimmte Personen Zugriff auf den Host bekommen oder Buildjobs vorher geprüft werden. Im Prinzip kann jedes Repository docker ps -a ausführen und anschließend alle Container mit docker rm CONTAINER löschen.

Eigenes Jenkins-Image erstellen

Alternativ könnt ihr euch ein eigenes Dockerfile erstellen, damit der Container als root ausgeführt wird:

FROM jenkins/jenkins:lts
USER root

Durch den Befehl USER root wird der Container von diesem Image als root ausgeführt. Ihr spart euch damit den -u Parameter beim Aufruf.


Bildnachweis: Pixabay.com