Container Management

Mit Portainer den Überblick behalten.

Container Management
Photo by Timelab / Unsplash

Zum Abschluss unserer Reihe zur Erstellung von Internet-Services kommen wir nun zur einem Webfrontend für Docker.

In der Web-Service Serie hatten wir den Ordner /var/docker/admin für administrative Aufgaben vorgesehen, die die Verwaltung der Container selbst betreffen. Eine bereits beschriebene Aufgabe ist das automatische Auktualisieren der Container. Will man sich den Status der Container grafisch anschauen, Images verwalten oder Volumes untersuchen, steht ein webbasiertes Werkzeug zur Verfügung.

Portainer

Portainer ist wohl eines der bekanntesten Tools. Und da wir bereits im Vorfeld eine gute Struktur eingehalten haben, können wir das /var/docker/admin/docker-compose.yml File leicht um eine weitere Aufgabe erweitern. Dazu fügen wir folgendes hinzu:

  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    command: -H unix:///var/run/docker.sock
    restart: unless-stopped
    ports:
      # If noone else can access this net:
      - 9000:9000
      # If on the internet, access via ssh-tunnel:
      # - 127.0.0.1:9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./portainer/data:/data
    labels:
      - com.centurylinklabs.watchtower.enable=true

Hier eine kurze Erklärung, was diese Konfiguration bedeutet:

  1. container_name: portainer: Dies gibt dem Docker-Container den Namen "portainer".
  2. image: portainer/portainer-ce:latest: Es wird das Docker-Image "portainer/portainer-ce" in der neuesten Version ("latest") verwendet.
  3. command: -H unix:///var/run/docker.sock: Hier wird der Docker-Daemon über den Unix-Socket /var/run/docker.sock angesprochen. Dies ermöglicht dem Portainer-Container, mit dem Docker-Daemon auf dem Host-System zu kommunizieren.
  4. restart: unless-stopped: Damit wird der Portainer-Container automatisch neu gestartet, es sei denn, der Benutzer hat ihn explizit gestoppt.
  5. ports: Hier werden die Ports konfiguriert, über die auf den Portainer-Webinterface zugegriffen werden kann. Der Container-Port 9000 wird auf den Host-Port 9000 gemappt. Es gibt auch eine alternative Konfiguration, die auskommentiert ist und es erlauben würde, den Portainer nur über einen ssh-Tunnel über die lokale Adresse 127.0.0.1 zu erreichen.
  6. volumes: Hier werden Docker-Volumes konfiguriert, um persistente Daten zu speichern. Der erste Eintrag bindet den Docker-Socket des Host-Systems an den Container, um die Kommunikation mit dem Docker-Daemon zu ermöglichen. Der zweite Eintrag bindet das Verzeichnis ./portainer/data des Host-Systems an das Verzeichnis /data im Container, um Portainer-Konfigurationsdaten zu speichern.
  7. labels: Hier wird ein Label gesetzt, das Watchtower aktiviert. Watchtower ist ein Docker-Tool, das automatisch Container-Updates durchführt, wenn neue Versionen der Images verfügbar sind.

Los gehts

Um auf Portainer zuzugreifen, öffnet man im Browser http://server-ip:9000

Hier finden wir nun unsere beiden Stacks wieder. Wie man sieht, weiß Portainer bereits über die Container und deren internen Netzwerke bescheid. Das liegt am Zugriff auf /var/run/docker.sock.

Wenn wir uns nun den Admin-Stack meines Test-Servers anschauen, sehen wir die zugehörigen Verwaltungs-Container:

Da dieser Server in meinem internen Testnetz läuft, können wir hier bereits sehen, daß Portainer über den Port 9000 von extern erreichbar ist. Das wäre für einen im Internet befindlichen Server natürlich fatal. In diesem Fall würde man natürlich im docker-compose.yml File die Variante über 127.0.0.1:9000 wählen.

Dennoch ist hier bereits der externe Zugriff gut zu sehen.

Klicken wir auf den Stack namens web, können wir die Container verwalten, die wir für Webservices angelegt haben:

Hier kann man gut die Überreste sehen, die beim Erstellen dieser Serie entstanden sind. Man deutlich sehen, dass keiner der Dienste von außen erreichbar ist. Das liegt daran, dass der einzige Weg in das interne Netz web nur über den Reverse-Proxy möglich ist. Dieser ist natürlich als einziger von außen erreichbar.

Den ersten Service habe ich bereits gestoppt. Er kann nun markiert und durch Druck auf Remove gelöscht werden:

Nun ist zwar der Container und die zugehörigen Volumes gelöscht, die Images (also die Dateisysteme in den Containern) liegen nun ungenutzt auf dem Server und können ebenfalls gelöscht werden. Dazu klicken wir auf Images:

Hier finden wir nun auch die ungenutzen Images, welche wir auf die gleiche Weise entfernen können, wie auch schon die Container:

Man kann auch gut sehen, welchen Anteil ein Container an der gesamten CPU-Last auf dem Server hat:

Durch Druck auf Inspect erfahren wir alle Details über den Container. Das kann wichtig sein, wenn wir zum Beispiel das Vertrauensverhältnis zwischen Nextcloud und dem vorgelagerten Reverse-Proxy herstellen wollen. Nextcloud muss dabei die IP des Proxies wissen, die wir auf der Inspect-Seite des Proxies erfahren können.

Fazit

Mit den in dieser Serie aufgezeigten Werkzeugen ist ein sicherer Betrieb von Internet-Diensten sogar kostenlos möglich. Man muss auch nicht alles ohne übersichtliche Tools bedienen. Den Alltag kann man sich mit Instrumenten, wie Portainer, durchaus erleichtern. Grundsätzlich gilt jedoch immer: Niemals mehr Dienste nach außen freigeben, als erforderlich.

Wer es bis hierhin geschafft hat, hat nun einen sicheren Server im Internet.