Bare metal oder die klassische Installation von Services auf einem Server-Host, hat einige Vor- und Nachteile. Klar – ich kann auf der Konsole sofort die notwendigen Pakete installieren und schon steht z.B. mein Webserver bereit. Tatsächlich war ich während meiner Vorbereitungen für diesen Blog in Mitten des Setups meines Bare Metal Servers. Und dann….? Dann habe ich die Häuser abgerissen und auf der grünen Wiese alles nochmal mit Docker gebaut.

Die Nutzung von Docker erfordert für Neueinsteiger etwas Übung und im Livebetrieb ein paar Kenntnisse über Sicherheit und sinnvolle Technologie-Stacks/ Toolchains. Denn zumindest bei mir blieb es nicht bei einer reinen Basisinstallation von Docker sondern ich garnierte alles noch mit etwas “docker-compose“-Würze und Portainer, einem einfachen Management-Tool um den Überblick zu behalten.

Ich kann in diesem Artikel nicht auf alle Details von Docker eingehen. Zumindest aber möchte ich auf sinnvolle Docker und Bare Metal Services eingehen und eine Möglichkeit einer Docker-Toolchain eingehen.

Was kommt in einen Container?

Ein mögliches Szenario, das ich persönlich so umgesetzt habe.
Kriterien:

  • Handling: Der Server soll einfach mit all seinen Services kopiert werden können (z.B. beim Server-Wechsel)
  • Übersicht: Die Konfigurationen und Daten sollten nicht verteilt sondern möglichst zentralisiert sein
  • Verfügbarkeit: Bei Ausfällen der Server-Services will ich möglichst noch Zugriff auf den Server bekommen
  • Skalierung: Überall wo ich ggf. skalieren möchte, z.B. bei Webseiten für unterschiedliche Kunden möchte ich, dass die Container möglichst wenig Berührung mit dem Host bekommen (Sandbox-Ansatz)
SerViceOrtBegründung
SSHHostDer Server soll bei Ausfall oder Wartungsarbeiten von Docker noch per SSH erreichbar sein
VPNHostDer Server soll bei Ausfall oder Wartungsarbeiten von Docker noch per VPN erreichbar sein
Webserver mit DatenbankDockerIn sich geschlossener Service und durch Docker skalierbar
MailserverDockerIn sich geschlossener Service mit allen benötigten Sub-Services
Monitoring der ServicesDocker / HostJe nachdem ob Services auf dem Host oder im Docker gemonitort werden sollen. Technisch kann auch ein Docker-Monitoring vom Host und umgekehrt durchgeführt werden.
Reverse-ProxyDockerAnnahme: Die meisten Webservices wie HTTP, Mail etc. sind bereits in Docker-Containern. Vorteil: Der Reverse-Proxy verhindert die direkte Kommunikation der Docker-Container mit dem Internet
DNS und Ad-BlockerDocker / HostWenn Docker eh im Einsatz ist und der DNS-Server als Ad-Blocker im Einsatz ist. Ein Host-DNS-Server bietet sich bei Nutzung des DNS-Dienstes auf dem Server selbst an, da ich auch hier die Ausfallsicherheit dem Komfort von Docker vorziehen würde.
Docker vs. Host-Installation

Docker Toolchain – Beispiel: WordPress Server

Oder was muss ich installieren, um Docker sinnvoll auf dem System einsetzen zu können?
Als Basis dient wieder unser Ubuntu 20.04 LTS Server.

Installation von Docker und Docker-Compose auf dem Linux-Host:

sudo apt update
sudo apt install docker.io docker-compose

Wir begeben uns in ein beliebiges Verzeichnis wo der neue Heimatort unserer Docker-Services zu finden ist. In diesem Beispiel ist das /opt/containerd. Zusätzlich legen wir ein neues Unterverzeichnis an um WordPress einzurichten.

cd /opt/containerd
sudo mkdir wordpress-containerized

Und damit der Zauber mit Docker einfach und erweiterbar sein soll, legen wir noch eine neue Docker-Compose Datei an:

sudo nano docker-compose.yml

Nun fehlt nur noch ein wenig Code der unseren zukünftigen WordPress-Container konfiguriert (Auszug aus der Doku von WordPress für Docker):

version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

Mit CTRL+O, CTRL+X gespeichert und noch schnell in der Konsole

sudo docker-compose up -d

ausgeführt und kurz danach läuft ein WordPress unter Port 8080 unseres Servers z.B. http://localhost:8080.

Hätten wir das manuell auf dem Host installiert wären wir um einiges langsamer gewesen und das Skalieren für mehrere Kunden oder das Abschotten zu unseren eigenen Services wäre um ein Vielfaches schwieriger geworden.

Die Übersicht behalten mit “Portainer”

Um Docker-Images, -Container, -Volumes und Docker-Netzwerke übersichtlich in einer Grafikoberfläche verwalten zu können, bieten sich Verwaltungstools wie Portainer an. Portainer ist nicht-invasiv und lauscht zunächst am Docker-Socket, detektiert automatisch das gesamte Docker-Setup und zeigt alles übersichtlich dar.

Das Dashboard von Portainer

Alle hinzugefügten Images innerhalb eines docker-compose.yml-Files werden als “Stacks” bezeichnet und lösen gemeinsam eine Aufgabe, z.B. wird eine Webseite mit HTTP-Server, PHP und MySQL Datenbank konfiguriert:

Docker-Stacks in Portainer

Um Portainer nutzen zu können, laden wir das passende Image mit folgendem Stack:

mkdir /opt/containerd/portainer-dockerized
cd /opt/containerd/portainer-dockerized
sudo nano docker-compose.yml

Und fügen ein wenig Konfiguration in die docker-compose.yml Datei ein:

version: '3.3'

services:
  portainer:
    image: portainer/portainer-ce
    container_name: my-portainer
    restart: unless-stopped
    ports:
      - "8000:8000"
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Hiermit weisen wir den Stack an den Service “portainer” im Container “my-portainer” zu instanziieren, am Leben zu erhalten (z.B. auch nach einem Server-Reboot) und an den Ports 8000 und 9000 lauschen zu lassen. Wir räumen das Recht ein auf den Docker-Socket zuzugreifen und ein Docker-Volume mit dem Namen “portainer_data” zu nutzen.

Mit einem

sudo docker-compose up -d

starten wir das Ganze und können nun das Webinterface auf http://localhost:9000 erreichen.

Sicherheit und Docker

Das Thema Sicherheit werde ich gesondert nochmal in einem Artikel behandeln. Doch eine Sache will ich gleich hier aufzeige. Alle Ports die in den oben genannten Beispielen definiert wurden, sind bereits offen zugänglich. Wenn Sie einen Webserver direkt im Rechenzetrum betreiben, sind diese also direkt an das Internet angeschlossen.
Docker umgeht Ihre Firewall und schaltet sich direkt mit IPTabels den Weg frei! Wie sie das verhindern können behandele ich in einem gesonderten Artikel zum Thema Reverse-Proxy “Traefik”.

Viel Spaß und Erfolg mit Ihren eigenen Docker-Projekten!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.