An der VHS Braunschweig findet vom 04. bis 08. Februar 2019 ein Bildungsurlaub zum Thema "Container mit Docker" statt.
Virtualisierungstechniken nehmen in den IT-Infrastrukturen eine immer größere Bedeutung ein. Manche sprechen bei Containern von der nächsten "Evolutionsstufe" der Virtualisierung. Dieses Seminar widmet sich der Praxis von Containern mit Docker und wird auch die technischen und theoretischen Themen für Applikationscontainer nicht vernachlässigen.

Sie werden die Administration von Docker erlernen und den unterschiedlichen Einsatz von Docker für Projektumgebungen kennen lernen. Und natürlich sollen auch die netzwerk- und sicherheitsspezifischen Aspekte nicht zu kurz kommen.
Hier die Rahmendaten unseres Seminars:
Ort: VHS Braunschweig, Heydenstraße 2, Raum 2.11
Termine: Mo., 04.02. bis Fr., 08.02.2019; jeweils 08.30 - 16.00 Uhr
Ich werde unsere Seminarthemen an dieser Stelle ausführlich begleiten und die Infos rund um Docker nachhaltig verfügbar machen.
Ihr Trainer Joe Brandes
Tag 01
Montag, 04.02.2019, 08.30 - 16.00 Uhr
Orientierungsphase, Teilnehmer-Themen
Bereitstellung von ausführlichem Docker-HandOut durch Trainer Joe Brandes ab Tag 02!
SingleHTML Hand-Out online (nicht immer aktuell oder verfügbar ;-)
Allgemeines
Wir setzen verschiedene Betriebssyteme ein für eine komplette Sicht auf die verschiedensten Einsätze von Docker-Containern auf unterschiedlichen Betriebssystemen und Netzwerkumgebungen.
Technik / Installationen
Teilnehmer-PCs mit aktuellen Core-i5 Intel-Systemen:
- Wechsel-SSDs:
240 GB (System-Installs) + ggf. 120 GB (Data und/oder Zweit-Install) - 16 GB RAM
Beachten: Host-System (ca. 2 GB) und später Docker Desktop für Windows (ca. 2 GB)
VM-Host Grundinstallation: Windows 10 Pro (1809) mit USB-Stick-Install-Medien
Anm.: bitte keinerlei Datenpartitionierungen - wir wollen einfach nur ein Virtualisierungs-Host ohne "Verschnitt"
Hyper-V aktivieren und Grundkonfiguration (nach Neustart) testen/analysieren
Alle Installationen mit "Generation 2" und weiteren Vorschlägen (Netzwerk: Default Switch, Dynamisches RAM, Ausschalten autom. Snapshots, Bootreihenfolge, Secure Boot, ...).
Installationen Hyper-V-VM-Gäste: (ISOs per Freigabe über Trainer-PC vorbereitet)
- Debian Stretch 9.7
Standard-Install mit LVM und Vorschlag für Partitionen /var, /home, /tmp - CentOS 7.6 (1810)
Standard-Install - openSUSE Leap 15.0 - Tag 01
Wichtig/Empfehlung: keine BtrFS-Partitionen nutzen!
Docker Versionen
Docker Software gibt es für nahezu alle Betriebssysteme. Und in unseren Seminaren wollen wir die OS-Implementierungen versuchen in Gänze zu erfassen - aber: aktuell ist Docker einfach heimisch
auf Linux-Plattformen!
Die Fa. Docker.Inc bietet aktuell an:
- Community Edition (CE) - wird im Seminar eingesetzt werden
- Enterprise Edition (EE)
- Testversion CE Edge
geplante Docker Installationen:
- Debian (eig. Standard-OS für Services im Internet)
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/debian/ - CentOS (Vertreter Red Hat OS)
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/centos/ - openSUSE (Vertreter Novell SLES) - Tag 01
Installation: per zypper installieren oder besser (aktueller) über
Build-Service Virtualization/Container: https://software.opensuse.org/package/docker - Docker Desktop for Windows
Installation / Setup über https://docs.docker.com/docker-for-windows/install/
Anm.: Scrollen bis "Install Docker Desktop for Windows desktop app" und dort Link zur Installer-exe mit ca. 500 MB Download
Bitte überprüfen, ob der Docker Daemon läuft und enabled ist für Standard-Target/Runlevel!
Alle Aufrufe (hier folgend) und dann auch für docker müssen mit root-Rechten durchgeführt werden.{code lang:bash showtitle:false lines:false hidden:false}systemctl status docker.Service
systemctl start docker.Service
systemctl enable docker.Service
docker version
usermod -aG docker standarduser{/code}Im Docker Aufruf docker version müssen Client und Server aufgelistet sein.
Im Seminar soll auch der Standarduser für docker berechtigt werden, um die tägliche Seminar- und Schulungsarbeit zu erleichtern: usermod -aG docker standarduser
Gefahr: Docker mit Standarduser kann ein großes Sicherheits darstellen! Darstellungen hierzu folgen!
Fachbegriffe
An dieser Stelle mal gesammelt - mehr dazu im Seminarverlauf...
Basis-Begriffe:
- Images - unveränderlich / ro
- Container - basieren auf Images, nutzen ein Overlay-Dateisystem
Container basiert auf Image; Container-Instanz ist R/W (Read/Write) Layer
maximale Anzahl Layer: 127 - Container-Host physikalische/reale oder virtuelle Maschine
- Volumes - vom Container getrennte Verzeichnisse im Docker-Host-System
Vertiefung:
- Services - Dienst/Aufgabe
Um diese kümmert sich Docker selbst! Sogar auf welchem Docker-Host die Services laufen sollen! - Stacks - Administration von Service-Gruppen
- Cluster - Vorraussetzung für Services und Stacks
Docker Nomenklatur: Swarm; s.a. Python-Skriptooldocker-compose - Kubernetes - Google Open Source für Container-Verwaltungen
Container Community lässt verlauten: läuft Docker Swarm den Rang ab! - Continouus Delivery / Continous Integration (CD/CI)
Versuch der Eklärung: (semi-)automatisierte Verfahren (CI) von kleinteiligen Releases mit ebenfalls möglichst automatischen Deployment-Test (CD)
Literatur - siehe: Liebel Kap. 2.3ff
Technik
Weitere Fachbgegriffe und kurze Erläuterungen:
- docker Client-Server-Modell
Linux: docker /dockerd; bei Windows/MacOS „komplizierter“ - Docker Images Windows
siehe Nano Server, IIS, ASP.NET; Anm.: Nano Server nur für Windows Server Hyper-V-Instanz! - Registry
Image-Datenbank mit Service zum pullen und pushen von Images
Im Produktionsbetrieb müsssen aus Sicherheitaspekten vertrauenswürdige und daher firmeninterne Registries genutzt werden.
Beispielhafte Registry: https://index.docker.io/v1/
Registry finden:docker info | grep -i registry - Repository
Logische Unterteilung einer Registry; Fundus mit mehreren Images (siehe Tags); siehe ubuntu:* (beliebige Ubuntu-Varianten) - keine init/systemd Techniken
Was passiert bei mehr als einem Dienst pro Container? - Virtuelle VMs vs. Container
die Container als „Leichtgewichte“ und ohne Prozesse-Lasten; und Nutzung von VMs für Docker-Hosts! - Container Lösungen (Wikipedia Containervirtualisierung )
- Klassiker: FreeBSD Jails, Solaris Zones, OpenVZ (siehe Virtuozzo von Parallels)
- LXD für LXC (Linux Containers oder Lightweight Linux Container) - Ausgangsbasis für Docker
- rkt (sprich: Rocket) - von CoreOS (bzw. Produkt Container Linux)
- VMware Photo
- Docker - März 2013 Fa. dotCloud - dann Oktober 2013 umbenannt in Docker Inc. mit Sitz in Berlin
Neue Componenten (ab Version >= 1.11): containerd, runc, aus „Docker Daemon“ wurde Docker Engine;
aber Version 1.12 mit eingebauter Swarm Technik: Swarm Mode
mit Schwerpunkt auf Applikationsvirtualisierung und nicht auf abgespeckte VMs
- Container Formate:
- Docker, CoreOS/rkt, LXD/LXC, Photon, …
- OCF (Open Container Format) der OCI (Open Container Initiative - www.opencontainers.org
- Namespaces
Ressourcen von Kernel lassen sich isolieren
Erste Docker Befehle
Für den ersten Tag haben wir einfach mal "Learning by Doing" genutzt - also einfach Docker Kommandos nach Vorgabe ausprobiert.
Hierbei wurden stets die entsprechenden Fachbegriffe weiter eingeführt:
Images, Container, Registry, Repository, Tags
Allgemeine Docker Befehle
Die Versionen für Docker Client und Daemon anzeigen lassen: docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.8
Git commit: e68fc7a215d7
Built: Mon Jan 14 12:00:00 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: e68fc7a215d7
Built: Mon Jan 14 12:00:00 2019
OS/Arch: linux/amd64
Experimental: false
Die Konfigurationen/Einstellungen der Dockertechnik anzeigen lassen: docker info
Dockers Hello World!
Wie in jedem "guten" Technikseminar: erst einmal Proof-of-Concept bzw. Funktion:{code lang:bash showtitle:false lines:true hidden:false}docker run hello-world
docker ps -a
docker container ls -a
docker images{/code}Zeile 1: Image hello-world aus Registry pullen und starten
Zeile 2+3: alle beendeten Container anzeigen lassen (unterschiedlich gewachsene Syntax)
Zeile 4: Images anzeigen lassen, die sich in unserem Docker-System befinden
Basis-Image ubuntu:18.04
Jetzt mal ein "echtes" Image in Form eines offiziellen Ubuntu-Basis-Image aus der Docker Registry (aus dem Docker Hub) mit dem Tag 18.04.
Hier wollen wir das Image pullen und clever starten: Parameter -it (interaktiv / Terminal bereitstellen) und Namen für Container und Hostname bereistellen:
docker run -it --name meinubuntu --hostname meinubu ubuntu:18.04
Wenn wir einen bereits vorhanden Container nochmals starten wollten:
docker start -i meinubuntu
Anm.: das gewünschte "t" benötigen wir hier nicht, das weiß der Container schon (s.o.).
Testaufrufe mit uname -a zeigen innerhalb des (hier) Ubuntu-Containers und auf dem Docker-Host denselben Kernel: das ist ja gerade der Clou an Containern - sie nutzen dieselben Systemtechniken wie der Docker-Host!
Auch mal kurz Prozessanalyse im Container (ps ax - zeigt nur einen Prozess: /bin/bash ) und im Docker-Host kann man mit ps axf die Prozesshierarchien und den /bin/bash-Prozess des Containers unter anderer PID im Docker-Host wiederfinden!
Basis-Image alpine:latest
Ein sehr spannendes Image:
- sehr klein (ca. 6 MB Image!)
- kompaktes, einfaches Paketverwaltungssystem (apk) und mit
- Busybox eine sehr gute "Toolbox" für Linux-Standardbefehle (ip, ping, traceroute, ...)
Wir werden uns an anderer Stelle speziell dem Alpine Linux widmen.
Wir haben auch ein wenig aufgeräumt: docker container rm <container-name> (entfernt Container)
und mit docker image rm <image-name> (kann man Images entfernen; alt: docker rmi )
Wir werden uns im Seminar Befehlsübersichten ("Cheat Sheet") und Hilfen zur Docker-Konsole erarbeiten.
Tag 02
Dienstag, 05.02.2019, 08.30 - 16.00 Uhr
Rekapitulation, Teilnehmer-Fragen
Ausführliche Rekapitulation der Themen von Tag 01 - inkl. Unterstützung/Bereitstellung der Ausarbeitungen von Trainer J. Brandes ("Hand-Out" als Website - später auch PDF)
Installationen (Forts.)
heutige Docker Installationen:
- Debian (eig. Standard-OS für Services im Internet) - Tag 02
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/debian/ - CentOS (Vertreter Red Hat OS)
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/centos/ - openSUSE (Vertreter Novell SLES) - Tag 01
Installation: per zypper installieren oder besser (aktueller) über Build-Service Virtualization/Container: https://software.opensuse.org/ - Docker Desktop for Windows - Tag 02
Installation / Setup über https://docs.docker.com/docker-for-windows/install/
Anm.: Scrollen bis "Install Docker Desktop for Windows desktop app" und dort Link zur Installer-exe mit ca. 500 MB Download
Und immer wieder: Tests der Dockerinstallation und Sicherstellen der neuesten Docker-Techniken für die gewünschten Betriebssystemplattformen.
Docker Desktop for Windows
Spezielles Installationsarchiv für eine Windows-Umgebung mit Hyper-V-"Rolle".
Installiert werden verschiedenste ISOs (docker-for-win.iso, config.iso, docker.iso) ein eigenes Hyper-V-Netzwerk DockerNat und genutzt mittels Virtuellem Computer MobyLinuxVM.
Die Docker-Installation wird über ein "Managment-Symbol" in der Systemleiste/Taskleiste verwaltbar. Die Konfiguration der Docker-Umgebung wurde angepasst (Anzahl CPU Kerne) und neu gestartet.
Die Docker Aufrufe sollte man mittels PowerShell durchführen. Ein Aufruf von docker version zeigt dann die genaue Ausgangssituation nach einer Standardinstallation:
Client: Docker Engine - Community
Version: 18.09.1
API version: 1.39
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:34:26 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.1
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:41:49 2019
OS/Arch: linux/amd64
Experimental: false
Also: wir nutzen hier eine Linux Engine und einen Windows Client!
Docker Hilfe
Anm.: eingeschränkte Unterstützung bei Windows (siehe Linux mit Paket docker-bash-completion )!
Also bitte immer fleißig "tab-ben".
Wir haben schon einigen Docker CLI Kommandos genutzt. Jetzt sollen komplettere Aufstellungen folgen.
Onlineportal: Docker Kommandos
Die Aufrufe sind nach Kategorien gegliedert. Die Aufrufe lassen sich teilweise in langer und kurzer Schreibung aufrufen:
docker container ps -a # oder auch kürzer und klassisch mit
docker ps -a
Das hat auch mit historischen Entwicklungen innerhalb der Docker-Versionen zu tun! Eine neue und saubere Kommanostruktur wurde mit Docker Version 1.13 eingeführt.
Wir beginnen aber wie immer mit der eingebauten Hilfe…
Onlineportal: Docker Engine Referenz CLI
Und natürlich kann man auch jederzeit mal die interaktive Docker Hilfe nutzen: docker help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/home/joeb/.docker")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") ...info
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default ".../.docker/ca.pem")
--tlscert string Path to TLS certificate file (default ".../.docker/cert.pem")
--tlskey string Path to TLS key file (default "/home/joeb/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
Mit der Hilfe kann man sich auch weiter in die Kommando-Hierarchien begeben: docker container ps --help
Usage: docker container ls [OPTIONS]
List containers
Aliases:
ls, ps, list
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display numeric IDs
-s, --size Display total file sizes
Und ja: es handelt sich bei der Textausgabe der Hilfe nicht um einen Fehler!
Es wurde docker container ps --help aufgerufen - man erkennt dann die Aliase.
Und zuletzt wurden auch klassische Man-Pages für die docker-Kommandos implementiert, die man einfach über mit "-2 (Bindestrich) zusammengesetzte Aufrufe erhält: man docker-container-start
Registry - Repository, Image:Tag
Klärung der wichtigen technischen Zusammenhänge:

Registry
Die Standard-Registry der Docker-Umgebung analysiert man mit: docker info | grep -i registry
Das ist normalerweise der Docker-Hub : https://index.docker.io/v1/ (Registry in Version 1 - es gibt aktuell auch schon V2)
Später wollen wir ggf. auch Private Registry betreiben (z.B. vm-opensuse-10:5000)
Online kann man den Docker Hub über das Webportal analysieren: hub.docker.com
Empfehlung: später mal einen Account anlegen für eigene Ablagemöglichkeiten auf Docker Hub und Sicht auf technische Analysen von Images (Sicherheitschecks)!
In der Konsole:
Einfache Suche: docker search ubuntu
Anzahl Images (hier: ubuntu): docker search ubuntu | grep "\/ubuntu\ " | wc -l
Filtern: docker search --filter=stars=7 --filter=is-official=true ubuntu
Die Images werden per docker pull aus der Registry geholt, indem man den Namen des gewünschten Repository bzw. Image angibt.
Repository, Image:Tag
Zusammenfassung aller Versionen (Tags) zu einem Image.
Offizielle Docker Images erkennt man am einfachen Namen (ohne /): ubuntu
Wird nur der Name genannt pullt Docker das Image ubuntu:latest
Inoffizielle Repositories haben einen Schrägstrich im Bezeichner: phpmyadmin/phpmyadmin
Der erste Teil ist die Docker ID auf dem Docker Hub (der Standard-Registry) und danach kommt der Image-Name.
Bei den Offiziellen Docker Images ist der formale komplette Name (z.B.): library/ubuntu
Images und Container
Übungen und Techniken: wie kommen wir über Images an nutzbare Container?!
Auszug aus Trainer-Cheat-Sheet (für Teilnehmer als LibreOffice Draw und als Download auf diesem Portal)

Der Container in "einem Schritt": docker run -it --name ubu1 ubuntu:18.04
Achtung: jedes weitere docker run ... erzeugt immer wieder neue Container!
Die Schritte im Einzelnen:
docker pull ubuntu:18.10 (Image ubuntu:18.10 aus Registry holen)docker create -i -t --name ubu2 ubuntu:18.10 (erstellt Container ubu2 aus Image ubuntu:18.10 mit interaktiv- und tty-Schaltern!)docker start -a -i ubu2 (startet Docker Container ubu2 attached und interaktiv)
Das "Attachen" an Container kann man auch nutzen, wenn man einen Container mal einfach ohne die Schalter gestartet (start, run) hat.docker attach ubu2 (Zugriff auf Container-Terminal von ubu2)
Und für die "äußerliche" Nutzung von Containern hilft immerdocker exec ubu2 cat /etc/os-release (Befehl in Container ubu2 ausführen)
Achtung: bei den meisten Containern ist ja die Bash (oder Sh) der "Urprozess". Das heißt, das man mit dem Befehl exit natürlich auch den Container stoppt!
Stattdessen kann man das Terminal auch mittels Strg+P, Strg+Q terminieren - also ohne den Container zu stoppen.
Für die Erstellung neuer Images zeigt die Kurzübersicht docker commit ... als Umsetzung. Das ist aber häufig keine sauber und gute Lösung für neue Images, da bei dieser Herstellung häufig zu viele Schichten (Layers) und zu hohe Image-Größen entstehen. Wir benötigen einen sauberen Build-Prozess mit docker build ... und Dockerfile Direktiven.
JSON - (docker inspect)
Bei der Analyse von Images und Containern hilft das docker [...] inspect Kommando.
Die Ausgabe entstehen in Form von JSON Dateien (Link Wikipdia)
Bitte denken Sie beim Bearbeiten von JSON-Dateien an Folgendes:
- Kommas und Hochkommas
- kein Komma mehr hinter dem letzten Listen- oder Dictionary-Element
- Saubere eckige, geschweifte Klammern
Empfehlung für saubere Ausgabe, Formatierungen und Filterungen: jq (noch nachinstallieren)
Das kann man auch für die verbesserte Ausgabe von manuellen HTTP-RESTful-Api Docker-Test mit "Webbrowser curl" nutzen:curl -s --unix-socket /var/run/docker.sock http://localhost/images/json | jq
Tag 03
Mittwoch, 06.02.2019, 08.30 - 16.00 Uhr
Rekapitulation, Teilnehmer-Fragen
Installationen (Forts.)
heutige Docker Installationen:
- Debian (eig. Standard-OS für Services im Internet) - Tag 02
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/debian/ - CentOS (Vertreter Red Hat OS) - Tag 03
Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/centos/
Tipps CentOS:
Auflösung Hyper-V-VM mit Toolgrubby
Installation von EPEL-Repos:yum install epel-release - openSUSE (Vertreter Novell SLES) - Tag 01
Installation: per zypper installieren oder besser (aktueller) über Build-Service Virtualization/Container: https://software.opensuse.org/ - Docker Desktop for Windows - Tag 02
Installation / Setup über https://docs.docker.com/docker-for-windows/install/
Anm.: Scrollen bis "Install Docker Desktop for Windows desktop app" und dort Link zur Installer-exe mit ca. 500 MB Download
Und immer wieder: Tests der Dockerinstallation und Sicherstellen der neuesten Docker-Techniken für die gewünschten Betriebssystemplattformen.
JSON und jq Ausgaben
Hinweis: bei CentOS mittels der EPEL-Repos Zugriff auf jq Paket.
Standardausgaben von docker inspect ... (JSON-Format) aufarbeiten und filtern mit jq.
Beispiel: (Kurzerläuterung: JSON als Array interpretieren)
Image Inspektion - nur Abschnitt ContainerConfig - Image ausgeben:
docker image inspect hello-world:latest | jq [.[0].ContainerConfig.Image]
Links zu Tool jq:
Die Ausgabe von Docker Kommandos ist auch über Go-Templates möglich: (Go Templates )
docker image inspect alpine:latest --format '{{.Config.Cmd}}'
[/bin/sh]
docker image inspect alpine:latest --format '{{json .Config.Env}}' | jq
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]
# weitere Beispiele
docker inspect -s -f "{{.State.Status}}" mariadb-test5
docker inspect -s -f "{{.State.FinishedAt}}" mariadb-test5
Oder aber wir optimieren die Ausgabetabelle eines Docker-Befehls.
Formatierte / tabellarische Ausgaben mit Schalter --format:
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Labels}}"
Besondere Erwähnung neben dem Format table sollte hier das Format json erfahren, was uns wieder zum Tool jq bringt (s.o.)!
Dockerfile (Einführung)
Bis jetzt haben wir fertige Images (siehe hub.docker.com) genutzt und mit diesen Images die Container erstellt.
Hinweis: später mit docker-compose werden mehrere Container kombiniert eingerichtet!
Die meisten Images waren auch ordentliche Vorlagen, aber z.B. in Ubuntu würde man vielleicht gerne das Paket iproute2 nachinstallieren, … usw.
Also wollen wir jetzt unsere eigenen Images erstellen und bedienen uns eines Dockerfile, das die nötigen Anweisungen enthält!
Kurzanleitung
- Ordner für Image-Bauprozess erstellen
- ggf. Dateien im Ordner bereitstellen (z.B. Skripte, Webdateien/Ordner)
- Datei
Dockerfileim Ordner erzeugen und Inhalt/Konfiguration für Image festlegen - mit
docker buildein neues Image lokal erzeugen - mit
docker push(ggf.) im Docker-Hub veröffentlichen (wörtlich zu nehmen: public)
Alternative Veröffentlichungstechniken für eigene Images:
- GitHub für Dockerfile bzw. Ordner/Dateien für automatisierte Builds
- Private Image Repository auf Docker Hub (ggf. $)
- Eigenes (privates) Docker Repository
Links:
In einer Fortsetzung zu docker-Builds (Dockerfile) später mehr zu den Anweisungen und technischen Umsetzungen.
An dieser Stelle müssen wir aber erst einmal noch weitere "Verdrahtungen" (Ports, Netzwerke, Prozesse) der Docker-Container kennenlernen. Dafür werden wir ein paar praktische Beispiele durchgehen und hierbei die nötigen Erfahrungen sammeln.
Beispiele MariaDB
Das Image stellt mit dem MariaDB-Service einen Background Prozesse zur Verfügung!
Anm./Erinnerung: Container ohne Prozess(e) wird gleich wieder beendet! (siehe: hello-world)
Wir starten einen Container für das offizielle Image mariadb:latest im detached-Mode (quasi: Hintergrund):
docker run -d --name mariadb-test1 -e MYSQL_ROOT_PASSWORD=geheim mariadb
# Stoppen des Containers:
docker stop mariadb-test1
# Containerinfos auslesen:
docker inspect maria-db-test1
Beachten: MariaDB Datenbank Verzeichnis /var/lib/mysql liegt im Docker-Container!
Die Datenbank (wenn diese läuft) mit gerne MySQL/MariaDB-Client checken:
docker exec -it mariadb-test1 mysql -u root -p
# Den Container analysieren:
docker exec -it mariadb-test1 /bin/bash
cat /etc/os-release
ps ax
mysqld --version
exit
Das Logging übernimmt Docker für den Hintergrund-Daemon Mysqld:
docker logs mariadb-test1.
Jetzt erweitern wir das Beispiel mit eigenem Volume im Userdir Home: (genauer: wir binden 2 Verzeichnisse)
mkdir /home/joeb/varlibmysql # manuelles mkdir (ggf.) nicht nötig!
docker run -d --name mariadb-test2 \
-e MYSQL_ROOT_PASSWORD=geheim \
-v /home/joeb/varlibmysql/:/var/lib/mysql mariadb
So jetzt haben wir einen neuen Container mariadb-test2 mit den DB-Dateien im Homedir eines Users.
Hinweis: Diese Umleitung für Volumes kann bei Nicht-Linuxen problematisch sein!
Jetzt noch ein Container - hier mit Portumleitungen:
docker run -d --name mariadb-test3 \
-v /home/joeb/varlibmysql/:/var/lib/mysql \
-p 13306:3306 mariadb
Und jetzt klappt der Zugriff auch direkt über den Docker-Host:
mysql -u root -p --port 13306 --protocol=tcp
Die Belegung von Ports ist immer zu hinterfragen, zu checken und bestenfalls zu kommentieren!
Beispiel Networking
Mit Ports kann man also (in)direkt auf die Dockerdienste / Dockerprozesse zurgreifen. Besser ist es allerdings mit eigenen Dockernetzwerk die nötigen Container zu verbinden.
Anm.: bitte vorher alle beteiligten „MariaDB-Container“ stoppen.
Neues Netzwerk erstellen und und neuen MariaDB-Container mit PhpMyAdmin nutzen:
docker network create test-network
docker run -d --name mariadb-test4 \
-v /home/joeb/varlibmysql/:/var/lib/mysql \
--network test-network mariadb
docker run -d --name pma -p 8080:80 \
-e PMA_HOST=mariadb-test4 \
--network test-network phpmyadmin/phpmyadmin
Anm.: beim letzten Aufruf ist der volle Name für das PhpMyAdmin-Image zu beachten.
Siehe: PhpMyAdmin Image auf Docker Hub
Docker-Netzwerke erledigen selbstständig die Namensauflösungen!
Aber: es werden die mit der Option „- - name“ erstellten Bezeichner verwendet.
docker network …
Hauptbefehl für Docker-Networking (siehe auch wieder docker network --help)
Kurze Befehlsliste: docker network ...
- create (Netzwerk erstellen)
- connect
- inspect
- ls (Netzwerke auflisten)
- prune (ungenutzte Netzwerke löschen; siehe später docker-compose)
Online: Infoseite Docker Networking
Beispiel WordPress
Vor der Bereitstellung von WordPress benötigen wir eine MySQL/MariaDB-Docker-Instanz und ein passendes Dockernetzwerk.
Infos zum Wordpress Image siehe: Wordpress Image auf Docker Hub
Auf dem Docker Hub Portal zu Wordpress finden sich auch die Erläuterungen für die speziellen WordPress Umgebungsvariablen (siehe Parameter -e).
Hier die vollständigen Konfigurationen…
Lokale Verzeichnisse für DB und WordPress-Website:
(Anm.: ich habe gerne ein Hauptverzeichnis für die Docker-Dirs - beachten Sie aber Pfade und ggf. Rechte)
mkdir -p /home/joeb/docker/varlibmysql
mkdir /home/joeb/docker/wp-html
Test-Netzwerk:
docker network create test-net
docker network list
DB MariaDB bereitstellen: (bei Tests auf Name --name achten - Nummerierungen)
docker run -d --name mariadb-test5 \
-e MYSQL_ROOT_PASSWORD=geheim --network test-net \
-v /home/joeb/docker/varlibmysql/:/var/lib/mysql mariadb
Und jetzt noch WordPress:
docker run -d --name wp-test1 --network test-net \
-v /home/joeb/docker/wp-html:/var/www/html -p 8081:80 \
-e WORDPRESS_DB_PASSWORD=geheim \
-e WORDPRESS_DB_HOST=mariadb-test5 wordpress
Und natürlich lässt sich auch der PhpMyadmin Zugriff bereitstellen:
docker run -d --name pma -p 8080:80 \
--network test-net -e PMA_HOST=mariadb-test5 phpmyadmin/phpmyadmin
Hinweis: Bitte auf die Ports achten!
Soweit ein kleiner Überblick mit praktischen Beispielen. Wir müssen jetzt wieder zurück ans "Reißbrett" (Dockerfile - docker build) und uns überlegen, wie wir am Besten gleich mehrere Container geeignet und kombiniert starten und verwalten (docker compose).
Tag 04
Donnerstag, 07.02.2019, 08.30 - 16.00 Uhr
Rekapitulation, Teilnehmer-Fragen
Basis-Images
Für die meisten Docker-Umsetzungen werden erst einmal vorbereitete Images genutzt.
Übersicht
Alle bisher benutzten Images in allen Beispielen basieren auf Grund-Images.
Diese Basis-Images werden per Docker Registry in Form von Repositories bereitgehalten. Später wollen wir uns von der Docker Registry trennen und werden unsere eigenen Registrys betreiben wollen.
Die Suche nach vertrauensvollen Basis Images: Docker Registry
Mit der Registrierung auf dem Docker-Hub haben Sie Einblick in die automatisierten Sicherheitsüberprüfungen für die verschiedenen Images in einem Repository (Reiter Tags).
Oder natürlich mit der Docker CLI: Docker CLI Search
Beispielaufrufe:
docker search ubuntu # Images ubuntu suchen docker search --filter "is-official=true" ubuntu # offizielle Images Ubuntu docker search --filter stars=10 debian # min. 10 Sterne
Die offiziellen Images haben einen einfachen Namen: also alpine und nicht testcom/alpine!
Hier ein paar der offiziellen Images (Anzahl gesamt: 16; Stand: Jan 2019)
- Scratch
für das Imagen „FROM scratch“ - Alpine
Ein Imaga-Build from scratch mit kleinem Linux-rootfs-TAR - der aktuelle Docker Builds Liebling!
Werden wir noch häufiger nutzen und bedarf einer weiteren Vertiefung, da es andere Administrationsmechanismen (z.B. Paketverwaltung) nutzt, als die Standard-Linux-OS. - CentOS
Image des RED HAT Community OS - Debian
Image Debian - Fedora
Image des RED HAT Fedora OS - Ubuntu
Image von Canonicals Ubuntu - Busybox
The Swiss Army Knife of Embedded Linux - Bash
nur die Bash ;-) - Amazon Linux
Amazon Linux is provided by Amazon Web Services (AWS)
Beachten: der Unterstrich in den Docker Hub Links/URLs steht für die offiziellen Images.
Hier mal eine kleine Übersicht über die durchschnittlichen Image-Größen:
| Distribution | Docker Image Größe |
|---|---|
| Alpine Linux | ca. 5 MiB |
| CentOS 7 | ca. 210 MiB |
| Debian 9 (Stretch) | ca. 100 MiB |
| Ubuntu 16.04 LTS | ca. 110 MiB |
| Ubuntu 18.04 LTS | ca. 80 MiB |
Tags
Über Repositories in der Docker Registry können unterschiedliche Images bereitgestellt werden, die man über ihre Tags genauer bestimmt.
Beispielhaft Übersicht (online - Images Centos): https://hub.docker.com/_/centos?tab=tags
Anm.: auf dieser Übersicht sehen angemeldete Docker Hub User auch immer die Sicherheitsanalysieren zu den Images!
Das lässt sich auch in der Kommandozeile zaubern: (Anm.: Tool jq genutzt für lesbare Darstellung)
curl -sL https://index.docker.io/v1/repositories/library/centos/tags | jq '.[].name' "latest" "5" "5.11" "6" "6.10" ... "7" "7.0.1406" ... "7.6.1810" ...
Für eigene Images gerne ein eigenes Präfix für die Images nutzen: joebrandes/alpine:15.0
Eigenes Basisimage
(s.a. Stichwort: Vertrauenswürdige Images)
Hiweis: jedes lokale erstellte Image kann immer nur über eine Registry genutzt werden!
Tarball
Wir erstellen/installieren ein Template-System (hier: openSUSE) und erstellen daraus einen Tarball.
tar --numeric-owner --exclude=/proc --exclude=/sys --exclude=/.snapshots -cvf opensuse.tar /
Dieses lässt sich dann auf dem Docker-Host wieder Importieren.
docker import opensuse.tar joebrandes/opensuse:42.3
Image-Erzeugung per Skript
Beispiel (Docker Entwickler): YUM-Based mit Skript online
Oder über Moby-Project: wget https://raw.githubusercontent.com/moby/moby/master/contrib/mkimage-yum.sh
Aufruf: bash mkimage-yum.sh joebrandes/centos
Debian / Ubuntu
Diese Systeme gehen mit einem eigenen Tool zum Extrahieren eines Tarball aus einem System an den Start: debootstrap
Das Tool kann über das gleichnamige Paket installiert werden.
debootstrap --variant=minbase stretch ./rootfs
tar -C ./rootfs -c . | docker import - joebrandes/debian:9
Anm.: nach Test ca. 165 MB groß!
Alpine Linux
Für das Linux zeichnet die Firma Gliderlabs verantwortlich.
Quellen:
Technisches:
- als C-Standardbibliothek wird musl statt glibc genutzt
das stellt häufig ein Problem bei zu kompilierenden Programmen dar - einfachere Auswertung von /etc/resolv.conf (keine domain und search Beachtung)
- es existiert für Alpine Linux optimierte glibc (pkg-glibc )
- als Init-System wird OpenRC statt systemd oder sysv-init genutzt
erinnert eher als klassisches init-System und arbeitet mit /etc/inittab - Wichtig: OpenRC ist installiert! Arbeitet aber nicht! S.a. Logging (rsyslog nachinst.)
- Linux Kommandos stammen von BusyBox
Alpine Linux lässt sich schnell ausprobieren:
docker run -it -h alpine --name alpine alpine Unable to find image 'alpine:latest' locally latest: Pulling from library/alpine cd784148e348: Pull complete Digest: sha256:46e71df1e5191ab8b8034c5189e325258ec44ea739bba1e5645cff83c9048ff1 Status: Downloaded newer image for alpine:latest / # cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.8.2 PRETTY_NAME="Alpine Linux v3.8" HOME_URL="http://alpinelinux.org" BUG_REPORT_URL="http://bugs.alpinelinux.org" / #
Container-Analyse (in separater Shell natürlich): docker ps -s (Größen anzeigen) zeigt einen nur wenige Bytes großen Container, was normal ist für frisch erstellte Container.
Shell
Die Shell ist standarmäßig /bin/sh bzw. /bin/ash (Teil von BusyBox)
Die Bash lässt sich nachinstallieren, was den Komfort erhöht, aber auch die Speichergrößen anschwellen lässt.
apk add --update bash bash-completion
BusyBox
Enthält ca. 140 Linux Standardkommandos, die als Symlinks zu busybox integriert sind.
Siehe: ls /bin /sbin -l
Hilfe zu BusyBox: https://busybox.net/downloads/BusyBox.html
Hilfen / Dokumentation
Es gibt keine man-Pages oder den Pager less! Nachinstallation möglich mit:
apk add --update man man-pages mdocml-apropos less less-doc
export PAGER=less
apk add --update bash-doc
Die man-Pages der Tools habe immer die -doc Paketendung!
Hilfe zu diesen Topics: siehe Alpine Doku
Paketverwaltung apk
Das Verwalten von Paketen (Software) mit apk unter Alpine Linux:
| Kommando | Funktion |
|---|---|
| apk add <paketname> | installiert Pakete |
| apk del <paketname> | entfernt Paket |
| apk info (<paketname>) | listet installierte Pakete auf (auch mit -L und --who-owns) |
| apk search <paketname> | sucht Paket in Paketquellen |
| apk stats | zeigt Anzahl Pakete |
| apk update | zeigt, welche Pakete aktualisierbar sind |
| apk upgrade | aktualisiert Pakete |
Pakete in Roh-Alpine: apk info | sort
/ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.2-19-g151c2021d6 [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.2-18-gd7f33f856a [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9546 distinct packages available
/ # apk info | sort
alpine-baselayout
alpine-keys
apk-tools
busybox
libc-utils
libressl2.7-libcrypto
libressl2.7-libssl
libressl2.7-libtls
musl
musl-utils
scanelf
ssl_client
zlib
/ #
Empfehlung: ein apk update vor irgendwelchen Installationen / Konfigurationen! Es gibt gut 9500 Pakete!
Tipp: In Dockerfile ein apk add --no-cache zum installieren nutzen: es wird ein --update durchgeführt, aber nach dem Install wird das System wieder bereinigt!
# Datei Dockerfile
...
RUN apk add --no-cache \
build-base \
python-dev \
jpeg-dev \
zlib-dev \
ffmpeg \
&& pip install sigal \
&& pip install cssmin \
&& apk del build-base python-dev jpeg-dev zlib-dev
Paketübersicht online: https://pkgs.alpinelinux.org/packages
Hier waren jetzt auch die Paketquellen erkennbar; Anzeige mit: cat /etc/apk/repositories
Dockerfile
Bis jetzt haben wir fertige Images (siehe hub.docker.com) genutzt und mit diesen Images die Container erstellt.
Die meisten Images waren auch ordentliche Vorlagen, aber z.B. in Ubuntu würde man vielleicht gerne das Paket iproute2 nachinstallieren, … usw.
Also wollen wir jetzt unsere eigenen Images erstellen und bedienen uns eines Dockerfile, das alle nötigen Anweisungen enthält!
Kurzanleitung
- Ordner für Image erstellen
- ggf. Dateien im Ordner bereitstellen (z.B. Skripte, Webdateien/Ordner)
- Datei Dockerfile im Ordner erzeugen und Inhalt/Konfiguration für Image festlegen
- mit docker build ein neues Image lokal erzeugen
- mit docker push (ggf.) im Docker-Hub veröffentlichen (wörtlich zu nehmen: public)
Alternative Veröffentlichungstechniken für eigene Images:
- GitHub für Dockerfile bzw. Ordner/Dateien für automatisierte Builds
- Private Image Repository auf Docker Hub ($)
- Eigenes Docker Repository
Links:
- Automatic Builds
siehe (aktuelle) c't 04/2019 "Container-Images in der Cloud bauen mit Docker Hub" - Docker Registry
Syntax
Schlüsselworte für ein Dockerfile (Directives) als Tabelle:
| Schlüsselwort | Bedeutung |
|---|---|
| FROM | gibt das Basis-Image an |
| LABEL | legt Zeichenkette fest |
| RUN | führt das Kommando aus |
| ADD | kopiert Dateien in das Dateisystem des Images |
| COPY | kopiert Dateien aus Projekverzeichnis in das Image |
| ENTRYPOINT | führt Kommando beim Start des Containers aus |
| CMD | führt Kommando beim Start des Containers aus |
| ENV | setzt Umgebungsvariablen |
| EXPOSE | gibt die aktiven Ports an |
| USER | Account für RUN, CMD und ENTRYPOINT |
| VOLUME | gibt/legt Volumes an |
| WORKDIR | Arbeitsverzeichnis für RUN, CMD und ENTRYPOINT |
Erläuterungen:
Kurze Analyse / Erläuterungen:
ADD vs. COPY - scheinen ja dasselbe zu tun, aber ADD kann…
- … auch mit URL umgehen
- … auch (wie COPY) Verzeichnisinhalte komplett kopieren
- … mit TAR-Archiven arbeiten/entpacken (gzip, bzip2, xz)
Beide können mit –chown=user:group Parameter umgehen.
In Kürze: COPY nur für einfaches Kopieren einer lokalen Datei.
CMD vs. ENTRYPOINT - Startkommandos für Container
Wenn man Container mit mit docker run Komandos anfügt, dann …
- … wird bei CMD das angefügte Kommando anstelle von CMD ausgeführt
- … wird bei ENTRYPOINT das Kommando hinzugefügt
Beispiele: Images mit Dockerfile bauen
Beispiel 1: einfacher Webserver mit Ubuntu und Apache2
mkdir -p /home/joeb/projektverzeichnis/samplesite
cd /home/joeb/projekverzeichnis
touch samplesite/index.html samplesite/style.css # HTML/CSS-Site nach Gusto
touch Dockerfile # siehe Dockerfile Beispiel
docker build -t joebrandes/testwebserver . # Image erzeugen / taggen
docker run -d -p 8080:80 -p 8443:443 -h webtest \ # Container erzeugen
--name testwebserver joebrandes/testwebserver:1.0
Die normale (und https-gesicherte) Seite sollte sich jetzt im Browser öffnen lassen!
Beispiel für einfachen Webserver:
Quelle: Dockerfile für Webserver nach Öggl/Kofler (S. 69)
# Datei Dockerfile
FROM ubuntu:18.04
LABEL maintainer "Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!"
LABEL description "Test"
# Apache installieren, und unnötige Dateien aus dem Paket - Cache
# gleich wieder entfernen
RUN apt-get update && \
apt-get install -y apache2 && \
apt-get -y clean && \
rm -r /var/cache/apt /var/lib/apt/lists/ *
# HTTPS -Unterstützung aktivieren
RUN a2ensite default-ssl && a2enmod ssl
ENV APACHE_RUN_USER=www-data \
APACHE_RUN_GROUP=www-data \
APACHE_LOG_DIR=/var/log/apache2
EXPOSE 80 443
# gesamten Inhalt des Projektverzeichnisses
# samplesite nach /var/www/html kopieren
COPY samplesite/ /var/www/html
CMD ["/usr/sbin/apache2ctl" , "-D" , "FOREGROUND"]
Beispiel 2: Alpine Linux mit Apache2 Webserver
Hier sind wir durch Recherchen zu Alpine Linux und diversen Dockerfile Analysen herausgefordert worden (Anm.: Apache als Prozess am Laufen halten im Container!)
FROM alpine
LABEL maintainer "Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!"
LABEL description "Test Alpine und Apache"
RUN apk update && apk upgrade && \
apk add apache2 libxml2-dev apache2-utils && \
rm -rf /var/cache/apk/*
# dieses run-Verzeichnis musste man. erstellt werden!
RUN mkdir /run/apache2
ENV APACHE_RUN_USER=apache \
APACHE_RUN_GROUP=www-data
EXPOSE 80 443
COPY samplesite/ /var/www/localhost/htdocs
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
Die benutzte Beispielseite (HTML-Projekt in Ordner samplesite) als einfaches HTML5-Gerüst mit einfachem Prüftext.
Alpine Linux 5 MiB
/etc/docker/daemon.json
Win: Docker Webservice
Webserver: http(s)
Mounts analysiert
Dockerfile
Tag 05
Freitag, 08.02.2019, 08.30 - 16.00 Uhr
Rekapitulation, Teilnehmer-Fragen
docker-compose
Jetzt wollen wir die Bereitstellungen von Containern verbessern. Mit docker run geht das zwar relativ einfach, aber wir wollen die Anweisungen zentral organisieren.
YAML
Die Konfiguration wird in der Textdatei docker-compose.yml bereitgestellt. Es handelt sich also um ein YAML gestylte Konfigurationsdatei.
Infoseiten zu YAML:
Für die Konformität der *.yml-Dateien kann wieder ein ordentlicher Editor (siehe VS Code) mit entsprechender Unterstützung sorgen.
Hinweis: Die Einrückungen (mit Leerzeichen) müssen genau passen - sie bestimmen die Gliederungen!
Kurzanleitung:
- Abschnitt mit —
- Kommentar mit #
- Liste mit Bindestrich - oder in [eins, zwei, drei]
- Hash mit key: wert oder {name: Joe, nachname: Brandes}
- Textblock (mit Zeilenumbrüche) mit |
- Textblock (ohne Zeilenumbrüche) mit >
Beispiel:
# Datei sample.yaml
data:
list:
- item1
- item2
key1: >
Dieser Text ist dem
Schlüssel 'data.key1' zugeordnet.
key2: |
code line 1
code line 2
YAML-Tool: shyaml (ein Python-Script)
openSUSE: sudo pip install shyaml
Beispielaufruf: shyaml get-value data.key1 < sample.yaml
Technik
Technischer Hintergrund: (Anm.: bei Docker Desktop für Windows ist docker-compose bereits verfügbar)
In aktueller Docker-Technik kann man die docker-compose Techniken auch mit docker stack deploy Techniken - also: Swarm Services - ausführen und arbeitet quasi mit einem Minimal-Swarm von einer Docker-Instanz!
Hinweis: das docker-compose Python-Skript kann Problemchen bereiten (Python!)
Wir beschränken uns - an dieser Stelle - auf docker-compose und behalten uns die Swarm-Techniken für später auf.
Webportal zu docker-compose: Docker Compose
Releases / Downloads GitHub: docker-compose Releases
Einfacher Download bzw. Installation: (alternative Bereitstellungen - siehe Webportal - sollten analysiert werden)
curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m`
-o /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose # Originalanleitung mit /usr/local/bin - siehe $PATH
docker-compose.yml
Was für die Docker Standardtechniken (docker run) das Dockerfile darstellt ist nun die Konfigurationsdatei docker-compose.yml für unser Tool docker-compose!
Hier: Wordpress-Installation:
# Datei test/docker-compose.yml
version: '3.7'
services:
db:
image: mariadb:latest
volumes:
- /var/dc-test-db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: geheim
restart: always
wordpress:
image: wordpress:latest
volumes:
- /var/dc-test-www:/var/www/html
ports:
- "8082:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: geheim
restart: always
Dieses Hello WordPress!-Beispiel zu docker-compose zeigt die zusätzliche Intelligenz des docker-compose-Tools gegenüber den Basistools Docker. Nicht einmal Netzwerkkonfigurationen werden benötigt!
cd test # hier ist das docker-compose.yml
mkdir /var/dc-test-www # Volume Wordpress HTML; kann man weglassen (!)
mkdir /var/dc-test-db # Volume MariaDB Databases; kann man weglassen (!)
docker-compose up -d
Test hier einfach wieder mit Browser (URL): localhost:8082 und man schaut sich mal Docker Netzwerke und alle möglichen Container an.
Danach kann man alles wieder beenden und löschen:
docker-compose down # es bleiben nur die Volumes!
rm -Rf /var/dc-test-db /var/dc-test-www # Volumes müssen manuell gelöscht werden
docker-compose <commands>
- config (Analyse)
- up | down (up normalerweise kombiniert mit -d)
- events
- kill (falls stop|down nicht funzt)
- logs
- pause | unpause
- ps
Mit einem 2. docker-compose Beispiel (Joomla-Installation) können wir die Nutzung von Docker Volumes sehen:
# Datei: joomla/docker-compose.yml
version: '3.1'
services:
joomla:
image: joomla:apache-php7
ports:
- 8080:80
volumes:
- webdata:/var/www/html
environment:
JOOMLA_DB_HOST: mariadb
JOOMLA_DB_NAME: dockerbuch
JOOMLA_DB_USER: dockerbuch
JOOMLA_DB_PASSWORD: johroo2zaeQu
mariadb:
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: eengi7suXeut
MYSQL_DATABASE: dockerbuch
MYSQL_USER: dockerbuch
MYSQL_PASSWORD: johroo2zaeQu
volumes:
webdata:
Hier wurde also ein Docker Volume mit dem Namen webdata deklariert und (oben) genutzt!
Wir wollen uns also jetzt mal die Docker Volumes etwas näher ansehen.
Volumes
Volumes lassen sich unter Docker als Mounts technisch nutzen und können unterschiedlich erstellt/gebunden sein.
- Bind Mounts (z.B. durch
-v /var/dc-test-www:/var/www/html) - Docker Volumes (mit docker volume create .. manuell erzeugen oder s.o. als Direktiven in docker-compose.yml oder Dockerfile)
Nur echte Volumes lassen sich mit docker volume ls auflisten.
Die Volumes lassen sich genauer mit docker volume inspect ... analysieren.
Docker (Mini) Swarm
An dieser Stelle nur zum reinschnuppern: ein 1-Node-Swarm!
Mit docker stack deploy einen Cluster mit nur einem Docker-Mitglied nutzen.
Hinweis: Übungen mit docker-compose (s.o.) inkl. Volumes vorher aufräumen/löschen!
Docker-Schwarm initieren: docker swarm init
docker swarm init # Docker Swarm initieren cd test # hier ist das docker-compose.yml mkdir /var/dc-test-www # Dir Wordpress HTML erstellen mkdir /var/dc-test-db # Dir MariaDB Databases erstellen docker stack deploy -c docker-compose.yml stacktest # und los geht es... docker stack rm stacktest # alles (bis auf Volumes, Dirs) löschen!
Das Beispiel zeigt ganz schön die zusätzliche Abstraktionsebene beim Testen der Docker-Technik.
Testen der WordPress-Installation im Browser (URL): 172.20.0.2:8082 (bwz. 172. ...)
Also: die Portumsetzung quasi eine Netzwerk-Ebene weiter (siehe GW-Netzwerk)! Die richtige IP analysieren Sie über docker network Analyse (s.o.), oder auch einfach mit ip a s auf Docker Host.
Achtung: Der Docker läuft weiterhin im Swarm-Modus!
Beenden mit: docker swarm leave --force
Für Docker Swarm dann auch weitere Deploy-Einstellungen (später mehr bei Swarm):
- deploy.mode
- deploy.placement.constraint ; Regeln: node.id, node.hostname, node.role
- …
Wenn später mehrere Node (Docker Host Swarm Mitglieder) gejoint werden (docker swarm join ...) müssen weitere Vorbereitungen und Konfigurationen beachtet werden: insbesondere die Nutzung von Zeitservice NTP, damit die Nodes genau gleich "ticken".
Docker Registry
Wir wollen unsere eigene Docker Registry betreiben. Hierfür stehen verschiedene technischen Umsetzungen zur Verfügung.
Die Registry steht in den Versionen V1 und V2 zur Verfügung. Vor den Bereitstellungen sollte man die entsprechenden Versionen recherchieren (siehe CentOS/RHEL mit V1).
Techniken Registry:
- V1 - in Python implementiert
- V2 - in Golang (Go)
Desweiteren starten wir erst einmal mit einer Insecure Registry - also ohne verschlüsselte Transporte.
Übersicht über die Bereitstellungen für Docker Registry:
- Registry Software auf Github https://github.com/docker/distribution
Anm.: wird hier nicht genutzt. - Registry als Docker Image vom Docker Hub https://hub.docker.com/_/registry
Anm.: mit Debian nutzen. - Software in Linux-Distributionen - und wieder: bitte die Version der Registry vorher klären
Anm.: mit openSUSE nutzen.
Registry Image
Die Umsetzung möglichst auf Debian-System. Anm.: eigenes Docker-Registry-Tool dann mit openSUSE-System.
Ein offizielles Registry-Image lässt sich auf dem Docker Hub finden und mit docker-compose nachhaltig implementieren.
Für eine Ansprache der eigenen Docker Registry nutzen wir z.B. hub.example.org oder andere FQDNs nach Wahl.
Diese Adresse müssen wir natürlich auflösen lassen - am einfachsten über die /etc/hosts.
Tipp: Bei der Nutzung Hyper-V Default Switch erhält man FQDNs und Namensauflösungen: hostname.mshome.net.
Aber: keine echtes DNS und Routing!
Jetzt benötigen wir nur noch ein Docker Compose Verzeichnis für die docker-compose.yml und schon kann es losgehen.
Docker Compose Ordner anlegen mkdir ~/docker/registry && cd $_ und in Ordner wechseln.
Datei docker-compose.yml:
registry:
image: registry:2
container_name: registry
restart: always
ports:
- 5000:5000
volumes:
- /srv/docker/registry:/var/lib/registry
Und los geht es: docker-compose up -d
Damit jetzt auch der unsichere Zugriff auf die Registry möglich ist, muss Docker über /etc/docker/daemon.json entsprechend konfiguriert werden:
{
[ggf. Vorherige Einträge - diese Zeile weglassen;-)],
"insecure-registries": [ "hub.example.org:5000" ]
}
Testen der eigenen Registry:
docker pull ubuntu:16.04
docker tag ubuntu:16.04 hub.example.org:5000/ubuntu:16.04
# und jetzt pushen:
docker push hub.example.org:5000/ubuntu:16.04
# löschen der Images:
docker image rm ubuntu:16.04
docker image rm hub.example.org:5000/ubuntu:16.04
# und jetzt das Image aus eigener Registry holen:
docker pull hub.example.org:5000/ubuntu:16.04
Die genutzte Registry (quasi der Weg für das Image) erschließt sich also aus dem Image-Namen!
Hinweis: Ändern Sie den Namen der Registry muss man Anpassungen an Dockerfile und docker-compose.yml-Dateien vornehmen!
Analyse des Registry-Containers:
docker exec registry ps aux
docker exec registry cat /etc/docker/registry/config.yml
Mit dieser config.yml kann die Registry Konfiguration dann auch angepasst/überschrieben werden.
Links zur Docker Registry:
- https://github.com/docker/distribution/blob/master/docs/configuration.md
- https://docs.docker.com/registry/configuration/
Registry Distro-Package
Die Umsetzung erfolgt auf einem openSUSE-System mit dem Paket docker-distribution-registry.
Es muss mit systemctl entsprechend gecheckt (systemctl status registry) und gestartet (systemctl start registry) werden.
Auch hier muss wieder eine Konfiguration für insecure-registries nach obigem Beispiel für die Standard-Registry vorgenommen werden.
Über /etc/docker/daemon.json also enntsprechend konfiguriert:
{
[ggf. Vorherige Einträge - diese Zeile weglassen;-)],
"insecure-registries": [ "opensuse.mshome.net:5000" ]
}
Repositories einer Registry anzeigen lassen:
curl http://opensuse.mshome.net:5000/v2/_catalog
Hinweis
Tests erst einmal nur mit den jeweils lokalen Maschinen, sonst benötigt man ja vollständiges DNS und Routing!
Das Löschen von Images in privaten Registries ist extrem unhandlich und umständlich (Literatr: Liebel, Kap. 6.4.4, S. 418ff).
Docker Hub Account
Anm.: hat auch Vorteile beim Einschätzen von Docker Hub Images
Erinnerung: die Docker Technik hält Konfiguration vor, wo sie standardmäßig die Registry erwartet:
docker system info | grep -i registry
Registry: https://index.docker.io/v1/
Das lassen wir auch erst einmal so. Auch um die verschlüsselte Kommunikation mit unseren Registries oder die Nutzung von Registry-Mirrors werden wir uns (ggf.) später kümmern.
Empfehlung: eigenen Account auf https://hub.docker.com/signup erzeugen für Repositories.
Docker Befehle: docker login | logout (Authentifizierung hinterlegt (!) in /etc/docker/key.json)
(Digitale) Unterlagen für TN
Hand-Outs Trainer J. Brandes
- Ausarbeitungen zu Docker: (erstellt per RestructuredText Docs)
- PDF ca. 80 S. und
- HTML-Versionen (HTML & SingleHTML)
Allgemeine Unterlagen
- Screenshots Seminarwoche ("Diashow" zum Seminar)
- Diverse PDF / Workshops
Letzte TN-Fragen, Feedback-Bögen, TN-Bescheinigungen
Win docker-compose
docker compose up -d
Docker Volume
Docker Mini Swarm
Swarm GW Networking
Private Registry
Literatur
Literatur
Die folgenden Docker Bücher liefern die Schwerpunkte zu unserer Seminarpraxis und den Übungen.
Hinweis: Texte und Anmerkungen zu den Büchern von Amazon bzw. Verlagen
Und natürlich liefert auch die Linksammlung viele Quellen für weitere Beschäftigungen.
Docker - Praxisbuch
Autoren: Bernd Öggl und Michael Kofler
Docker: Das Praxisbuch für Entwickler und DevOps-Teams.
Docker: Das Praxisbuch für Entwickler und DevOps-Teams. Gebundene Ausgabe: 431 Seiten Verlag: Rheinwerk Computing; Auflage: 1 (24. August 2018) Sprache: Deutsch ISBN-10: 3836261766 ISBN-13: 978-3836261760 Größe und/oder Gewicht: 17,2 x 3 x 24,6 cm
Software-Container verstehen und produktiv einsetzen
Docker ist aus der modernen Softwareentwicklung nicht mehr wegzudenken. Ob Sie Entwickler oder Administrator sind, ob Sie gerade einsteigen oder bereits produktiv mit Software-Containern arbeiten: Dieses Buch zeigt Ihnen Docker und die Containerwelt.
Dabei lässt es Sie auch bei Troubleshooting und Orchestrierung nicht alleine. Inkl. Best Practices, umfangreichem Werkzeugkasten und vielen Tipps zu Projektmigration, Container-Sicherheit, Kubernetes und mehr.
Skalierbare Container
Oliver Liebel
Skalierbare Container-Infrastrukturen für Ihr Unternehmen
Skalierbare Container-Infrastrukturen: Das Handbuch für Administratoren und DevOps-Teams.
Inkl. Container-Orchestrierung mit Docker, Rocket, Kubernetes, Rancher & Co.
Gebundene Ausgabe: 1071 Seiten Verlag: Rheinwerk Computing; Auflage: 1 (28. April 2017) Sprache: Deutsch ISBN-10: 3836243660 ISBN-13: 978-3836243667 Größe und/oder Gewicht: 18,4 x 6,9 x 25,6 cm
Aktuelle Auflage:
Verlag: Rheinwerk Computing; Auflage: 2 (26. Oktober 2018)
Gebundene Ausgabe: 1380 Seiten Sprache: Deutsch ISBN-10: 3836263858 ISBN-13: 978-3836263856
Die nächste Evolutionsstufe der Virtualisierung ist ein Pflichtthema für jedes Unternehmen, dem sich DevOps-Teams und Administratoren stellen müssen: Hochskalierbare und ausfallsichere Microservice-Umgebungen.
Mit diesem Handbuch verstehen Sie die Konzepte hinter den Technologien und können Container-Infrastrukturen auf Basis von Docker in Verbindung mit Swarm Mode, Kubernetes, Rancher, Mesos und DC/OS planen, aufbauen und orchestrieren. So stellen Sie Software schneller bereit und vereinfachen das Deployment und die Wartung Ihrer Infrastruktur – damit Ihre IT-Landschaft auch zukünftig den Anforderungen an Skalierbarkeit und Planungssicherheit gewachsen ist!
Linux-Server
Linux-Server: Das umfassende Handbuch
Inkl. Samba, Kerberos, Datenbanken, KVM und Docker, Ansible u.v.m. (Ausgabe 2019)
mit einem eigenen Kapitel "Docker Container"
Auflage: 5 (23. November 2018)
Gebundene Ausgabe: 1270 Seiten Verlag: Rheinwerk Computing; Auflage: 5 (23. November 2018) Sprache: Deutsch ISBN-10: 3836260921 ISBN-13: 978-3836260923 Größe und/oder Gewicht: 22,2 x 7,3 x 24,6 cm
Wie Sie Linux-Server effizient nach den aktuellen Standards administrieren, vermittelt Ihnen dieses Buch. Von Hochverfügbarkeit über Sicherheit bis hin zu Scripting und Virtualisierung: Sie lernen Linux-Server distributionsunabhängig intensiv kennen.
Das Buch bietet Ihnen über benötigtes Hintergrundwissen hinaus zahlreiche Praxisbeispiele zu den häufigsten in Unternehmen eingesetzten Distributionen. Und dank Shell-Programmierung, Python, Ansible sowie den im Buch vorgestellten Tools und Automatisierungsskripten lassen Sie Ihre Rechner für sich arbeiten!
Links
Linksammlung
Die folgende Linksammlung natürlich ohne Anspruch auf Vollständigkeit ;-) und mit dem Versuch einer Gliederung.
Tipp: Erst nach dem Seminar stöbern! Und los geht es…
Docker
- Docker Portal
- Docker Documents - Infoportal
- Docker Enterprise Edition (Docker EE vs. CE)
- Docker Community Edition (CE) - Release Notes
- Docker für Windows - Release Notes
- Docker Hub
- Docker Hub - Offizielle Basis Images
- Intro to Docker - A Slideshow
- Docker - What is a Container
- Docker Engine Referenz CLI
Docker Registry
- https://github.com/docker/distribution/blob/master/docs/configuration.md
- https://docs.docker.com/registry/configuration/
Best Practises & HowTos
- ueberdosis.io - Tipps für schlanke Docker-Images
- Jonny Langefeld - How to Docker
- Simplilearn Slideshare
- Wie funktionieren Docker Container
- Edureka - Deep Dive in Docker
Tools
Ausgabeformatierungen
- Go Programming Templates
- jq Tutorial
- jq Manual (s.a.
man jq) - jq Ubuntuusers
Diverses
Cheat Sheets
Security
seccomp
exit-Codes
- Technik chroot:Exit Codes with special Meaning
- Docker run Exit Status: Docker reference run
Videos
- Youtube Docker Recherche
- Youtube Docker Kanal
- Youtube - Docker Basics (Live Stream)
- Youtube Recherche: Difference Virtualization and Container
- Youtube Heise - Docker Praxis mit Linux
- Youtube Edureka
- Youtube Simplilearn
Vielen Dank für Ihre tollen Feeback-Bögen und persönlichen Rückmeldungen und Anregungen - keep on Dockering...
Ihr Trainer Joe Brandes


