2. Docker¶
2.1. Einführung¶
Docker ist eine Container-Technologie, die es ermöglicht, Anwendungen und Services in isolierten Containern auszuführen. Im Gegensatz zu virtuellen Maschinen, die einen eigenen Betriebssystem-Kernel benötigen, teilen sich Docker-Container den Kernel des Host-Systems. Dadurch sind sie leichtgewichtiger und schneller zu starten. Zudem bietet Docker eine Vielzahl von Vorteilen, wie z.B. Portabilität, Skalierbarkeit, einfache Bereitstellung von Anwendungen und eine konsistente Umgebung für die Entwicklung und das Deployment von Anwendungen. Docker besteht aus mehreren Komponenten, darunter der Docker-Daemon, der Docker-Client und das Docker-Registry-System, das es ermöglicht, Docker-Images zu speichern und zu teilen.
2.2. Grundlegende Begriffe¶
- Docker-Image:
Eine ausführbare Datei, die sowohl eine Anwendung, als auch ihre Abhängigkeiten enthält. Es kann als Vorlage für die Erstellung von Docker-Containern verwendet werden. Docker-Images werden in der Regel aus Dockerfiles erstellt.
- Docker-Container:
Eine laufende Instanz eines Docker-Images. Er enthält eine isolierte Umgebung für das Ausführen von Anwendungen und Services. Docker-Container können schnell erstellt, gestartet, gestoppt und entfernt werden.
- Dockerfile:
Eine Textdatei, die die Schritte zur Erstellung eines Docker-Images definiert. Es enthält Anweisungen zum Herunterladen von Abhängigkeiten, zum Konfigurieren von Anwendungen und zum Festlegen von Umgebungsvariablen.
- Docker-Compose:
Ein Tool, mit dem mehrere Docker-Container gleichzeitig gestartet und verwaltet werden können. Es ermöglicht die Definition von Services, Netzwerken und Volumes in einer YAML-Datei, um komplexe Anwendungen zu organisieren.
- Docker-Registry:
Ein Speicherort für Docker-Images. Sie können öffentlich oder privat sein und es ermöglichen, Docker-Images zwischen verschiedenen Systemen und Teams zu teilen und bereitzustellen.
- Docker-Daemon:
Der zentrale Prozess von Docker, der für die Verwaltung von Docker-Containern und Images verantwortlich ist.
- Docker-Client:
Ein CLI-Tool, mit dem Docker-Images erstellt, gestartet, gestoppt und verwaltet werden können.
2.3. Installation Docker¶
Docker kann auf verschiedenen Betriebssystemen installiert werden, darunter Linux, Windows und macOS. Je nach Betriebssystem gibt es unterschiedliche Installationsmethoden - auf Linux zum Beispiel kann Docker über die Paketverwaltung des Betriebssystems installiert werden. Auf Windows und macOS gibt es hierfür Docker Desktop, welches sowohl die Installation von Docker Engine, Docker CLI und Docker Compose beinhaltet. Es ist auch (für jedes Betriebssystem) möglich, Docker in einer virtuellen Maschine oder einem Cloud-Dienst zu installieren, um eine isolierte und skalierbare Umgebung zu schaffen.
Linux:
# Paketquellen aktualisieren
sudo apt-get update
# cURL installieren
sudo apt-get install curl
# Aktuelles Docker package holen
curl -fsSL https://get.docker.com/ | sh
# Account zur Docker group hinzufügen
sudo usermod -aG docker <your_username>
# Docker verifizieren
docker run hello-world
- Windows/macOS:
Einfache Installation möglich über Docker Desktop
2.4. VM inbetriebnahme¶
Im Rahmen des zweiten Projektes wurde uns eine VM im Hochschulnetz zur Verfügung gestellt. Nachfolgend wird beschrieben, wie wir diese aufgesetzt haben.
Zunächst haben wir den Benutzer ‚gruppe‘ erstellt. Anschließend haben wir durch ssh-keygen einen SSH-Schlüssel erstellt und den öffentlichen Teil in Gitlab als Deploykey hinterlegt.
# ssh key generieren
ssh-keygen
cat .ssh/id_rsa.pub
Für eine bessere Zusammenarbeit benutzten wir tmate, eine text- und konsolenbasierte Zusammenarbeitsumgebung. Durch einfaches Einfügen eines Tmate-Sitzungsschlüssel in ein Terminal können alle Benutzer der Sitzung Eingaben tätigen.
sudo apt update
sudo apt install tmate
# Eingabe des Sitzungsschlüssel, z.B.:
ssh 2JsH2jCTu3S9eLV7N93YffxqH@lon1.tmate.io
2.5. Podman vs. Docker¶
Podman ist ein Open-Source Container-Engine-Tool, das dazu verwendet werden kann, Container auszuführen, zu erstellen und zu verwalten. Es stellt somit einen quelloffenen Konkurrenten zum kommerziellen Container-Tool Docker dar. Einer der wichtigsten Unterschiede zwischen Podman und Docker ist, dass Podman standardmäßig Rootless ist. Das bedeutet, dass es nicht wie bei Docker als Root-Benutzer ausgeführt werden muss, und somit in puncto Sicherheit weniger Risiken bereitet und die Einhaltung von Richtlinien erleichtert.
Ein weiterer Unterschied besteht darin, dass Podman keine Daemon-Prozesse erfordert, um Container auszuführen, zu erstellen oder zu verwalten. Docker hingegen verwendet einen Daemon-Prozess, der stets im Hintergrund läuft. Dieser Prozess kann schwierig zu verwalten und zu konfigurieren sein.
Zudem kann Podman Docker-Images und Container ausführen, aber es verwendet dabei keine Docker-Daemon-Prozesse oder Docker CLI-Tools. Docker hat hingegen eine große Community und viele Ressourcen wie Docker Hub, eine zentrale Bibliothek mit Docker-Images, und Docker Compose, ein Tool zum Definieren und Ausführen von Multi-Container-Anwendungen.
Installation Podman
sudo apt-get -y update
sudo apt-get -y install podman
sudo apt install docker-compose
# add alias
echo 'alias docker=podman' >> ~/.bash_aliases
# add source for docker images
# add 'unqualified-search-registries=["docker.io"]' to the end of the file:
vim /etc/containers/registries.conf
# enable socket
systemctl enable --now podman.socket
# alter the docker run to use the podman.socket
docker run -d --name gitlab-runner --restart always -v gitlab-runner-config:/etc/gitlab-runner -v /run/podman/podman.sock:/run/podman/podman.sock gitlab/gitlab-runner:latest
2.6. Gitlab pipeline & runner Verbesserungen¶
In diesem Kapitel geht es um Verbesserungen an der GitLab-Pipeline und dem GitLab-Runner im Zusammenhang mit Docker-Containern. Insbesondere werden Probleme bei der Verwendung von privaten SSH-Schlüsseln innerhalb der Docker-Containern behandelt.
Dockerfile:
FROM gitlab/gitlab-runner:latest
RUN apt-get update -y
RUN apt-get install -y make python3 python3-pip rsync
RUN pip3 install sphinx
RUN mkdir -p /home/gitlab-runner/.ssh
COPY --chown=gitlab-runner:gitlab-runner ssh/id_rsa /home/gitlab-runner/.ssh/id_rsa
# RUN chwon does not work ... use COPY --chown... instead
#RUN chown -R gitlab-runner:gitlab-runner /home/gitlab-runner/.ssh
COPY --chown=gitlab-runner:gitlab-runner ssh/config /home/gitlab-runner/.ssh/config
# echo + redirect does not create file in docker ¯\_(ツ)_/¯ copy instead
#RUN echo "Host remotehost\n\tStrictHostKeyChecking no\n" >> /home/gitlab-runner/.ssh/config
RUN ls /home/gitlab-runner/.ssh/
In den ersten zwei Zeilen setzen wir das Basisimage auf die neueste Version von GitLab-Runner und aktualisieren danach die Paketlisten des Systems.
Anschließend installieren wir zusätzliche Pakete, die für die Ausführung der gewünschten Aktionen innerhalb der Pipeline erforderlich sind, nämlich Python3, Python3-pip und rsync.
Danach installieren wir durch den vorherigen Schritt sphinx, um später die Dokumentation bauen zu können.
Der nächste Abschnitt besteht darin, im Benutzerverzeichnis gitlab-runner ein .ssh-Verzeichnis zu generieren und dorthin die private SSH-Schlüsseldatei id_rsa zu kopieren.
Nun geben wir den Ownership des .ssh-Verzeichnisses dem gitlab-runner Benutzer im Docker-Image
Danach disablen wir das StricHostKeyChecking durch die .ssh-config Datei
Anschließend geben wir das Verzeichnis .ssh im Home-Verzeichnis des gitlab-runner Benutzers im Docker-Image aus, um sicherzustellen, dass der private SSH-Schlüssel und die SSH-Konfigurationsdatei erfolgreich kopiert und konfiguriert wurden
Folgende Probleme sind uns während der gesamten Konfiguration begegnet:
id_rsa befindet sich noch im Docker-Image während docker build, wie man anhand sudo docker-compose up –build sehen kann
id_rsa befindet sich nicht mehr im Container wenn man docker exec -ti‚ ausführt, wie man durch ls /home/gitlab-runner/.ssh/ sieht
das Verzeichnis .ssh/config ist ursprünglich nicht vorhanden
id_rsa konnte nicht per Volume gemappt werden, da dann die Datei-Berechtigungen im Container nicht stimmen und dadurch der Benutzer gitlab-runner innerhalb des Containers keinen Zugriff auf seinen private key hat
2.7. extra insights:¶
Frage: Warum hat es uns die id_rsa file im build vorgang des images nichtmehr angezeigt, gestern jedoch schon?
der ls befehl im Dockerfile zeigt nur den output an, wenn nicht der cach verwendet wird für das image. also nur das erste mal.
Frage: Warum gehört die datei nicht gitlabrunner trotz chown in Dockerfile?
RUN chown funktioniert nicht <quelle:stackoverflow link> wir benutzen COPY –chown stattdessen <quelle:docs.docker.com>
Frage: Warum ist die config nicht im container trotz echo „…“ >> config?
RUN echo erstellt die datei nicht. wir benutzen jetzt COPY wie in der Antwort drüber.
2.8. Quellen¶
https://blog.desigeek.com/post/2022/03/podman-error-on-ubuntu-short-name-did-not-resolve-to-an-alias-and-no-unqualified-search-registries/ https://docs.docker.com/engine/reference/builder/ https://gitlab.com/gitlab-org/gitlab-runner/-/issues/29285 https://medium.com/trabe/use-your-local-ssh-keys-inside-a-docker-container-ea1d117515dc https://stackoverflow.com/questions/64176477/running-chown-in-dockerfile-does-nothing https://docs.docker.com/engine/reference/builder/#copy