Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
[Allgemein] -  Docker Infos Heise-Tutorial
#1
Infos aus dem 6-teiligen Heise-Tutorial

Erstellung eines Volums.

Volums sind dafür da, um eigene Daten aufzunehmen. Damit diese nicht direkt in einen Container erfasst werden, legt man unter /usr/share zum jeweiligen Programm, z.B. nginx, ein Volume an.

Die Syntax wäre in diesem Beispiel wie folgt:

Code:
sudo docker run --name my-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx

some-nginx = Name des Containers
-v = ein Volume anhängen und deklarieren
-d = Dienst läuft im Hintergrund
nginx = Image
ro = read only

Hinweis:
In einem Dockercontainer sind nur die wichtigsten Pakete enthalten. Will man eine Textdatei erstellen, aber ein Editor ist nicht verfügbar, kann man pragmatisch folgendes machen:

Code:
echo "Hallo Docker!" > index.html

Damit erstellt man eine Datei, die dann verwendet werden kann. Will man künftig mehr in dem Container machen, empfiehlt es sich, einen Editor zu installieren (und daraus dann ein eigenes Build zu machen). Das wird so aber nicht empfohlen (?). Insgesamt ist das der denkbar schlechteste Weg.

Fazit:
Mit docker exec in einen Container zu gehen und dort Daten zu bearbeiten ist nicht gut und sollte so nicht gemacht werden.

Die Anwendungsdaten werden im Container nicht gespeichert. Sobald der Container beendet wird, sind die Daten weg. Daher müssen Volumes angelegt werden, die die Anwendungsdaten speichern udn vorhalten.

Um ein Volume zu erzeugen, ist folgender Befehl notwendig:

Code:
sudo docker volume create

Dieser Befehl erzeugt einen langen Name aus Zufallszahlen/-ziffern. Man kann den Volumennamen auch vorgeben:

Code:
sudo docker volume create html

Mit dem ls-Befehl kann ich mir die vorhandenen Volumes anzeigen lassen:

Code:
sudo docker volume ls

Das läuft analog zu den Images und den Containern.

Um nun das erzeugte Volume mit dem Namen html in den nginx-Container zu bringen, wird eine zweite Instanz aufgemacht und ein weiterer Port eröffnet (nicht zwingend erforderlich, nur zur Demonstration):

Code:
sudo docker run --name myvol-nginx -p 8081:80 -v html:/usr/share/nginx/html:ro -d nginx

ro heißt readonly.

Das erzeugte Volume liegt hier:

Zitat:/var/lib/docker/volumes

Dieses Verzeichnis kann ein Normaluser, selbst wenn er in der Gruppe docker ist, nicht sehen (sudo -s)

WICHTIG:
Selbst wenn der Container zerstört wird, bleibt das Volume erhalten. Wichtig ist dann dabei, dass das Verzeichnis /usr/lib/docker gesichert wird, wenn in diesem Verzeichnis Nutzer- und  Anwendungsdaten für die weitere Verarbeitung gespeichert werden, also produktiv genutzt werden.

Die Volumes müssen nicht unbedingt im Docker-Verzeichnis liegen, sondern können an jeder beliebigen Stelle gespeichert werden. Dazu wäre dann z.B. dem Volume HTML das Verzeichnis voranzustellen (Beispiel): /home/django/dockervolume/HTML

Die Prozesse, die innerhalb der Container laufen, müssen allerdings die Berechtigungen auf dieses Verzeichnis haben.


Docker und Netzwerke

Docker erzeugt ein eigenes Netzwerk: docker0

Code:
ifconfig docker0

Docker hat verschiedene Netzwerke, die man sich so anzeigen lassen kann:

Code:
docker network ls

Beispiel, wie zwei Container kommunizieren.

Ein Blogsystem auf Basis WordPress-Blogsystem
  • Container mit Webserver und WordPress
  • Container mit Datenbank MySQL / MariaDB

Container für Datenbank:

Code:
docker run --name test-mysql -e MYSQL_ROOT_PASSWWORD=meinpasswort -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wp -e MYSQL_PASSWORD=meinpasswort -d mysql:5.7

Container für WordPress / Webserver

Code:
docker run --name wordpress --link test-mysql:test-mysql -p 8082:80 -d wordpress

Hinweis:

Zitat:--link anstelle von --name

Dieser Part "test-mysql:test-mysql" bedeutet, dass der Container test-mysql auch als test-mysql angesprochen werden. Soll dieser Name dann anders lauten, müsste er angegeben werden (z.B. test-mysql:test-worpress).

Hinweis:
Docker hat einen eigenen DNS-Server laufen.

Für das obige Beispiel würde im Browser, da wir mit WordPress arbeiten wollen, folgendes einzugebenn sein:

Zitat:localhost:8082

Sodann würde die Installation von WordPress erfolgen.

Die Daten von WordPress werden in der Datenbank abgespeichert. WordPress und die Datenbank sind in zwei Containern aufgeteilt. Um mit den eingegebenen Daten weiter arbeiten zu können, müssten die Daten in ein Volume übertragen werden

Wie das geht, weiß ich noch nicht!

Wenn z.B.  WordPress vom Rest der Welt trennen möchte, dann kann das über ein eigenes Docker-Netzwerk erfolgen. Das sieht dann so aus:

Code:
docker network create --driver bridge test-bridge

Prüfen, ob das Netzwerk angelegt ist bzw. welche vorhanden sind, kann man mit:

Code:
docker network ls

Dieses neue Network kann man an den Run-Befehl für mysql hängen:

Code:
docker run --name test-mysql --network=test-bridge -e MYSQL_ROOT_PASSWWORD=meinpasswort -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wp -e MYSQL_PASSWORD=meinpasswort -d mysql:5.7

Hinweis:

Es gibt den inspect-Befehl. Dieser kann auf das Netzwerk angewandt werden. Um das neue Netzwerk zu inspizieren, ist folgendes notwendig:

Code:
docker network inspect test-bridge

Man kann also in das Netzwerk "hineinschauen".


Wie kann man Docker vereinfachen?

Contaner mit Compose einrichten

Mehrere Container nebeneinander betreiben.

Docker-Compose ist ein Python-Script (offizell von Docke unterstützt), mit dem vereinfacht mehrere Container aufgebaut und miteinander verbunden werden können.

Ein Compose-File ist wie folgt strukturiert (Beispiel MySQL-Container)

Zitat:version: '3'

services:
    db:
        image: mysql:5.7
        volumes:
            - ./data/db/:/var/lib/mysql
        restart: always
        ports:
            - "3306:3306"
        environment:
            MYSQ_ROOT_PASSWORD: secret123root

Die Inhalte sind quasi die gleichen wie in einem run-Befehl.

Die Aussage ist, dass selbst, wenn nur ein Container laufen soll, eine Compose-File nützlich ist.

Der data-Ordner des Volume liegt in dem Ordner, aus dem das Compose-File aufgerufen wird. Der Punkt weist auf die relative Lage hin. Hat mein einen eigenen Bereich auf der lokalen Festplatte eingerichtet, ruft man das File eben von dort aus auf.

Für das Beispiel aus dem Netzwerkabschnitt (WordPress und MySQL) sieht das Compose-File wie folgt aus:

Zitat:version: '3'

services:
    db:
        image: mysql:5.7
        volumes:
            - ./data/db/:/var/lib/mysql
        restart: always
        ports:
            - "3306:3306"
        environment:
            MYSQL_ROOT_PASSWORD: secret123root
            MYSQL_DATABASE: wordpress
            MYSQL_USER: wordpress
            MYSQL_PASSWORD: 12345wordpress54321
           
    wordpress:
        depends_on:
            - db
        image: wordpress:latest
        ports:
            - "80:80"
        restart: always
        environment:
            WORDPRESS_DB_HOST: db:3306
            WORDPRESS_DB_USER: wordpress
            WORDPRESS_DB_PASSWORD: 12345wordpress54321
        working_dir: /var/www/html
        volumes:
            - ./data/wordpress:/var/www/html/wp-content
       
        portainer:
            image: portainer/portainer
            restart: always
            ports:
                mehr sehe ich nicht, scheint ein volume zu sein, ist wohl eine grafische Oberfläche gedacht, also nicht in der Konsole wichtig.

So wird die yml-Datei, in der das Compose-File abgespeichert wurde, ausgeführt:

Code:
docker-compose up
  • up = starten
  • stop = stoppen
  • down = herunterfahren (Container werden dabei sofort gelöscht)

Damit wird wohl alles an Compose-Files gestartet.

Die Ausführung dieses Befehl ist sichtbar, da die Option -d nicht mit angegeben worden ist.

Ansonsten könnte man bei der Sichtbarkeit die einzelnen Aktionen sehen, die ausgeführt würde. Es gibt dann wohl, sobald der Datanbankserver oben ist mit der Installation von Wordpress im Browser.

Hinweis:
In einer yml-Datei ist die Einrückungstiefe immer 2 Leerzeichen. Man kann auch Tabs verwenden, aber zwei Leerzeichen sind wohl Standard.

Um z.B. auf der Shell in die Container mit dem exec-Befehl einzusteigen, kann folgender Befehl genutzt werden:

Code:
docker-compose excec db sh

Damit ist man im Container anstelle des komplexen Befehlaufrufes aus den Anfängen.


Die grafische Oberfläche für Docker

Portainer ist eine bekannte grafische Oberfläche

Sofern im Compose-File der Portainer integriert ist, kann man in der Adressezeile des Browsers über den Port 9000 die Webseite erreichen.

Zitat:localhost:9000

Ich unterstelle derweil, dass das möglich ist, denn in dem Beispiel bei Heise wird mittlerweile eine echte Domain genutzt. Sollte aber auch mit localhost funktionieren.


Zertifikate erstellen

Die Anwendungen, die man in Docker erstellt, kann man sind Internet bringen. Man muss dafür aber vieles beachten, um die Sicherheit zu gewährleisten. Mit Zertifikaten kann man das erreichen.

Eine Grundlage ist z.B. Watchtower (wird niht mehr entwickelt, es gibt was neues) und gehört zu vorherigen Compose-File.

Watchtower ein Image, welches sich um die Aktualisierung von Images kümmert, was durch Docker selber nicht geleistet wird.

Code:
watchtower:
  image: v2tec/watchtower
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  command: --interval 30

Um von außen auf die Anwendung schauen zu können, wird folgendes benötigt (Revers-Server/Proxy oder so ähnlich)

Für das nachfolgende Beispiel muss der WordPress-Container angepasst werden, da diese keine Ports mehr freigeben darf (wird weiter unten mit 80 und 443 gemacht):

Code:
wordpress:
        depends_on:
            - db
        image: wordpress:php7.1
        restart: always
        environment:
            WORDPRESS_DB_HOST: db:3306
            WORDPRESS_DB_USER: wordpress
            WORDPRESS_DB_PASSWORD: 12345wordpress54321
            LETSENCRYPT_HOST: mlsjam.leipsieb.de
            LETSENCRYPT_EMAIL: mls@ct.de
            VIRTUAL_HOST: mlsjam.leipsieb.de
            VIRTUAL_PORT: 80
        working_dir: /var/www/html
        volumes:
            - ./data/wordpress:/var/www/html/wp-content

Ob das auch auf localhost läuft, weiß ich derzeit nicht.

Code:
nginxproxy:
  image: jweilder/nginx-proxy
  restart: unless-stopped
  volumes:
    - ./data/certs:/etc/nginx/certs
    - ./conf:/etc/nginx/conf.d
    - ./dhparam:/etc/nginx/dhparam
    - ./data/vhosts:/etc/nginx/vhost.d
    - ./data/html:/usr/share/nginx.html
    - /var/run/docker.sock:/tmp/docker.sock
  ports:
    - 80:80
    - 443:443
  labels:
    - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
   
nginxproxy_comp:
  image: jrcs/letsencrypt_nginx_proxy_companion
  restart: unless_stopped
  depends_on:
    - nginxproxy
  volumes:
    - ./data/certs:/etc/bginx/certs:rw
    - ./conf:/etc/nginx/conf.d
    - ./dhparam:/etc/nginx/dhparam
    - ./data/vhosts:/etc/nginx/vhost.d
    - ./data/html:/usr/share/nginx.html
    - /var/run/docker.sock:/tmp/docker.sock:ro


In meinen Tests hatte ich mehrere Male die Probleme, dass die Ports z.B. 8080 oder 8081 als belegt gekennzeichnet wurden.

Um herauszufinden, welche Anwendungen die Ports belegen, natürlich können das auch laufende Container sein, ist folgender Befehl hilfereich:

Code:
sudo lsof -i -P -n | grep 8080

Das Ergebnis sieht so aus:

   

Somit ist für mich klar, dass ich den Port 8081 nehme.

Wie ich mit den Ports überhaupt umgehen muss, weiß ich selber noch nicht, wenn es sich um Webanwendungen handelt.
Zitieren Return to top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste