Docker
Diese Seite beschäftigt sich mit Docker Containern zur Virtualisierung von Applikationen.
Allgemein
Docker Webseiten
- Docker Homepage
- Docker Hub
- Offizielle Images haben im Pfad der Tags ein "/library/", z.B. https://hub.docker.com/r/library/opensuse/tags/
- Docker Store
- Docker Forums
- Docker Cloud
Artikel und Infos
- siehe c't 11/14 S.46
- Docker einrichten unter Linux, Windows, macOS (heise.de)
- Docker - 10 Tipps für einen besseren Workflow
- Panamax vereinfacht Docker-Container-Verwaltung (pro-linux.de)
- Praxis siehe c't 17/14 S.146
- Report siehe LM 09/14 S.32
- Docker-Container am praktischen Beispiel von OwnCloud: siehe LM 09/14 S.56
- Datenbank und Webserver in getrennten Containern
- Docker verwaltet LXC Container: LM 08/13 S.64
- Docker Einführung und Panamax als GUI: siehe LU 12/14 S.78
- Docker mit Swarm: siehe iX 03/15 S.108
- Anwendungen mit Docker isolieren
- Docker Report: siehe iX 05/15 S.46
- Docker Container Einführung: siehe c't 05/16 S.108
- Docker Container einsetzen: siehe c't 05/16 S.112
- Systemd vs. Docker (lwn.net)
- PHP development with Docker
- Docker Grundlagen, Praxis, User Defined Networks: siehe c't 15/17 S.106 ff
- Docker Container aktuell halten: siehe LM 06/18 S.48
- Docker Images (allgemein, Auswahl): siehe c't 16/18 S.104 ff
- Docker auf dem Raspberry Pi: siehe c't 02/19 S.149
- Multi Stage Builds mit Docker (am Beispiel einer Node.js Applikation)
- Indiz: Zwei oder mehrere FROM Anweisungen im Dockerfile
- siehe c't 03/19 S.152
- Images automatisch im Docker Hub bauen via GitHub: siehe c't 04/19 S.138 , http://ct.de/y3tz , https://github.com/ct-Open-Source/docker-autobuild-example
Ökosystem
- Einführung in Test-driven Docker Development
- Container und das Docker-Ökosystem – Status quo (entwickler.de) zur Studie The State of Containers and the Docker Ecosystem 2015
Versionshinweise
1.3
- Containerisierung: Mehr Orchestrierung und bessere Interoperabilität bei Docker 1.13 (heise.de)
- Docker 1.13 bringt Rückwärtskompatibilität des CLIs und Kommando-Redesign (entwickler.de)
Projekte und Verbände
- Open Container Project (OCP)
- Cloud Native Computing Foundation (CNCF)
Repository Server
- Docker Registry Frontend - Browse and modify your Docker registry in a browser.
- Siehe auch "Docker Registry Frontend" in rawino.
Betriebssysteme
Besonders auf Docker abgestimmte (schlanke) Betriebssysteme (Linux):
Sicherheit
- https://www.docker.com/resources/security/
- Gartner Studie Security Properties of Containers Managed by Docker
- VMware Report 2015
- http://www.pro-linux.de/news/1/22315/docker-erhoeht-die-sicherheit.html
- http://opensource.com/business/14/7/docker-security-selinux
- https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=docker16.100 - PDF komplett
- https://d3oypxn00j2a10.cloudfront.net/assets/img/Docker%20Security/WP_Intro_to_container_security_03.20.2015.pdf - PDF Kurzfassung
- Script überprüft Docker-Sicherheit
- Docker Container sicher betreiben: siehe iX 05/15 S.54
- NeuVector delivers an application and network intelligent container security solution that automatically adapts to protect running containers.
- Docker absichern mit Bordmitteln (TLS Clientzertifikate, Linux Capabilities, User Namespaces, Mandatory Access Control): siehe LM 01/18 S.30
- anchore - The Open Platform for Container Security and Compliance
- anchore.io scannt Images (CVE) und stellt Ergebnisse dar
- Kata Containers zur Isolation: siehe LM 12/18 S.60
- Tools zur Absicherung von Containern: siehe iX 04/19 S.98
Orchestrierung
Bei der Orchestrierung geht es um Verwaltung, Skalierbarkeit und Automatisierung:
- Container massenweise auf beliebigen Hosts (automatisch) starten
- Container auf mehreren Hosts in ein "virtuelles" Netzwerk integrieren, mit dynamischer Vergabe von IP-Adressen und Ports (internes DNS und Service Discovery)
- Dienste und Anwendungen aus einer Vielzahl von Container in Clustern erstellen und steuern
- Mehrere Versionen einer Anwendung parallel laufen lassen mit schnellem Wechsel der Versionen
Siehe:
- Dockers Ökosystem: Kubernetes, etcd, Project Atomic, Open Stack, siehe LM 11/14 S.70
- Deis vereint Docker und Core OS: siehe LM 03/15 S.62
- Flocker: Verwaltung von Speicher-Ressourcen / Daten
- siehe LM 09/15 S.60
- Docker-Tools im Vergleich: Welches Container-Tool passt zu mir? (entwickler.de)
- Vergleich Docker Swarm, Nomad, Kontena, Rancher, Azk: siehe LM 08/18 S.56
- Docker-Orchestrierung mit Kubernetes
- http://kubernetes.io
- siehe LM 11/14 S.70
- siehe LM 05/15 S.70
- siehe iX 05/15 S.49
- Kubernetes & OpenShift E-Book
- siehe c't 05/16 S.116
- fabric8: Open source microservices platform based on Docker, Kubernetes and Jenkins
- siehe iX 02/17 S.38
- Einführungstutorials in der iX
- Teil 1: Logik und Terminologie, iX 07/17, S. 98
- Teil 2: Kubernetes installieren, iX 08/17, S. 122
- Teil 3: Produktiveinsatz planen und vorbereiten, iX 09/17, S. 138
- Kubeapps, Kubeapps startet Apps auf Kubernetes (linux-magazin.de)
- Introducing commercial Kubernetes applications in GCP Marketplace (Google)
- A practical Introduction to Kubernetes (Video)
- Cloud Native Storage (i.d.R. CEPH) als Volume in Kubernetes einbinden mit Rook: siehe LM 09/18 S.58
- Compose, Machine, Swarm
- Deploy and Manage Any Cluster Manager with Docker Swarm (docker.com)
- siehe c't 05/16 S.116
- siehe c't 15/17 S.120 (am Beispiel zweier Dienste Tor + Bitmessage), http://ct.de/yqws
- Docker Compose: siehe c't 26/18 S.148 http://ct.de/y1b5
- Beispiel: Mattermost
- Kommandos:
docker-compose build docker-compose up -d docker-compose up <name> -d docker-compose down docker-compose restart <name> docker-compose logs
- Rancher
- http://rancher.com
- https://github.com/rancher
- https://hub.docker.com/u/rancher/
- https://jaxenter.de/mit-rancher-1-0-kommt-eine-agnostische-container-management-plattform-38162
- https://stackshare.io/stackups/kubernetes-vs-rancher
- Rancher 1: siehe iX 02/17 S.32
- Rancher 2: siehe iX 04/18 S.60
- DC/OS von Mesosphere
- siehe iX 02/17 S.42
- OpenStack
- Magnum: siehe iX 01/19 S.106
- Kubic
- openSUSE MicroOS Container Operating System and the Kubic Container as a Service Platform based on MicroOS and kubernetes
- Kleinere Tools:
- Watchtower prüft nach neuen Versionen für Images, macht ein Pull und startet Container neu
- Management GUIs
- Testbericht siehe LM 09/18 S. 48 (Dockstation, Kitematic, Portainer)
- Portainer, management user interface for your Docker environments, https://portainer.io , siehe c't 16/18 S.109 und LM 09/18 S.48
Anwendungen
openSUSE
- https://news.opensuse.org/2014/08/07/official-docker-containers/
- http://www.pro-linux.de/news/1/21376/docker-container-fuer-opensuse-131-verfuegbar.html
Icinga
Training und Lernen
- Mini-course: Docker in SUSE Linux Enterprise Server 12
- Continuous Integration (CI) mit Docker und GitLab: siehe LM 01/18 S.58
- Docker Spielwiese im Browser: https://labs.play-with-docker.com/ , siehe c't 06/18 S.57
Literatur
- Verschiedene Bücher von Packt.
- "Pro Docker" vor allem mit Beispiel-Containern für Linux, Datenbanken, und Applikationen; siehe iX 10/16 S.156
- Docker
- "Software entwickeln und deployen mit Containern" - dpunkt
- Docker, Rheinwerk, 2018: siehe LM 02/19 S.85
- Kubernetes
- Kubernetes, Dpunkt, 2018: siehe LM 02/19 S.85
Betrieb
Hilfe
man docker man docker run docker --help docker run --help
Netzwerk
- Wenn man von einem Container eine TCP-Verbindung zum Docker Host machen möchte, z.B. um eine MySQL DB auf dem Host zu nutzen, dann muss bei aktivierter Firefall das interne Docker-Netzwerk freigeschaltet werden, z.B. als "Trusted Network":
FW_TRUSTED_NETS="172.17.0.0/16"
- Beim Start des Docker-Daemons kann Firewall-Funktion deaktiviert werden.
- Reverse Proxy als Docker-Container für den automatischen Einsatz bei vielen Containern unter einer IP, die z.B. alle auf Port 80 und 443 erreichbar sein sollen: https://hub.docker.com/r/jwilder/nginx-proxy/
- siehe c't 15/17 S.113
- Software Defined Networking, z.B. mit Contiv: siehe iX 06/18 S.110
User Defined Networks
- User Defined Networks: siehe c't 15/17 S.116
- Netzwerke anzeigen:
docker network ls
- Bridge "docker-extern" (einmalig) erstellen und einen Container aus der Standard-Bridge dort hineinfügen:
docker network create docker-extern docker network disconnect docker0 docker network connect docker-extern mycontainer
oder beim Start des Containers mit "docker run" das Netzwerk angeben
docker run ... --network docker-extern
- Netzwerk Alias - zur Verlinkung von Diensten/Hostnamen (z.B. einer Datenbank mit Hostnamen "db") - anstatt Link:
docker run ... --network docker-extern --name dbserver --network-alias db
- Man kann mehrere Container im gleichen Netz denselben Alias zuweisen: Round Robin des eingebetteten DNS-Servers
- Man kann einem Container mehrere Aliase geben: Mehrere Namen in einem Container
- Container in mehrere User Defined Networks erreichbar machen (alias):
docker network connect --alias db docker-extern mycontainer
- Verbindungen (Inter Container Connectivity) zwischen User Defined Networks verhindern:
docker network create -o 'com.docker.network.bridge.enable_icc=false' docker-isoliert
- Keine Netzwerkverbindung im impliziten Netzwerk "none"
- Keine Verbindung nach außen (Internet):
docker network create --internal docker-intern
- Feste IP-Adressen im Netz auf im Container:
docker network create --subnet 172.20.0.0/16 --gateway 172.20.0.1 docker-extern docker run ... --network docker-extern --ip 172.20.0.2
Konfiguration
Images landen hier:
/var/lib/docker
Info ausgeben:
docker info
Images
Handling von Images
Image suchen:
docker search debian
Ein Image herunterladen:
docker pull debian
Vorhandene (lokale) Images auflisten:
docker images
Image in Tar-Archiv umwandeln:
docker images save > myimage.tar
Image (lokal) löschen (nur möglich, solange kein Container es nutzt):
docker rmi debian
Image pushen (zuerst "Rename" des Images in Non-Root-Pfad durch Taggen [1], dann einmalig Login [2]):
docker tag meinnginx2:latest <username>/meinnginx2:latest docker login docker push <username>/meinnginx2
- Login-Daten landen in /root/.docker/config.json
Neues Tag "v2.0" pushen auf Basis von "latest":
docker tag <username>/meinnginx2:latest <username>/meinnginx2:v2.0 docker push <username>/meinnginx2:v2.0
Eigenes Image bauen
- siehe c't 15/17 S.120 (Beispiel Tor), http://ct.de/yqws
- Sehr einfaches Beispiel: https://github.com/ct-Open-Source/docker-autobuild-example/blob/master/Dockerfile
Beispiel 1: Apache auf Basis Debian
Das folgende Beispiel setzt ein Apache-Image mit einer statischen Webseite auf Basis eines Debian "Betriebssystem-Images" auf.
1. Verzeichnis für den Bau erstellen
mkdir -p /data/docker/newimage
2. Die statische Seite(n) erstellen, die dem Image hinzugefügt werden sollen
cd /data/docker/newimage vi index.html
3. Das Dockerfile anlegen
vi Dockerfile
FROM debian
MAINTAINER Ralf Kruedewagen <docker@kruedewagen.de>
RUN apt-get update && apt-get install -y apache2
ADD index.html /var/www/html/
EXPOSE 80
# Apache ENVs, sonst Fehlermeldung beim Start von Apache, siehe
# https://github.com/paulczar/docker-apache2/blob/master/Dockerfile
# http://tech.paulcz.net/2015/03/optimizing-your-dockerfiles/
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_LOG_DIR /var/log/apache2
ENV LANG C
# Fehlermeldung mit APACHE_LOCK_DIR -> https://log.axcoto.com/article/164442852
RUN [ ! -d ${APACHE_RUN_DIR:-/var/run/apache2} ] && mkdir -p ${APACHE_RUN_DIR:-/var/run/apache2}
RUN [ ! -d ${APACHE_LOCK_DIR:-/var/lock/apache2} ] && mkdir ${APACHE_LOCK_DIR:-/var/lock/apache2} && chown ${APACHE_RUN_USER:-www-data} ${APACHE_LOCK_DIR:-/var/lock/apache2}
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
# alternativ:
# ENTRYPOINT ["/usr/sbin/apache2"]
# CMD ["-D", "FOREGROUND"]
4. Das Image bauen
docker build -t meinapache /data/docker/newimage/
5. Container anlegen und starten
docker run -d --name meinapachecontainer -p 8080:80 meinapache
Mehr Infos zu Apache und Docker:
- https://hub.docker.com/_/httpd/
- http://linoxide.com/linux-how-to/configure-apache-containers-docker-fedora-22/
- http://slopjong.de/2014/09/17/install-and-run-a-web-server-in-a-docker-container/
- http://stackoverflow.com/questions/27768194/how-to-use-docker-container-as-apache-server
- http://stackoverflow.com/questions/21280174/docker-centos-image-can-not-auto-start-httpd
Beispiel 2: Nginx auf Basis Debian
Genau so wie bei Apache mit einigen Änderungen im Dockerfile:
FROM debian
MAINTAINER Ralf Kruedewagen <docker@kruedewagen.de>
RUN apt-get update && apt-get install -y nginx
ADD index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Beispiel 3: Parsoid mit Node.js
Parsoid wird für den Visual Editor von MediaWiki benötigt und ist ein webbasierter Dienst.
Voraussetzungen / Bemerkungen:
- MediaWiki läuft auf dem Host selbst (Dockerhost). Für das Ansprechen namensbasierter virtueller Webserver sind FQDN-Einträge in uri nötig.
- Parsoid soll in einem Container laufen, daher benötigt der Dockerhost Zugriff auf den Parsoid-Port im Container und im Gegenzug benötigt Parsoid Zugriff auf das Wiki im Dockerhost.
- wie man den Dockerhost aus dem Container ansprechen kann (Eintrag in hosts Datei mit --add-host beim Starten des Containers) erklärt https://github.com/docker/docker/issues/1143.
/data/docker/parsoid/config.yaml (only the "conf" section):
mwApis:
- # This is the only required parameter,
# the URL of you MediaWiki API endpoint.
uri: 'https://dockerhost/w/api.php'
domain: 'localhost' # optional
- # This is the only required parameter,
# the URL of you MediaWiki API endpoint.
uri: 'http://www.example.org/w/api.php'
domain: 'example.org' # optional
# Use selective serialization (default false)
useSelser: true
# Allow override of port/interface:
serverPort: 8142
#serverInterface: '127.0.0.1'
# Require SSL certificates to be valid (default true)
# Set to false when using self-signed SSL certificates
strictSSL: false
};
/data/docker/parsoid/Dockerfile:
FROM debian
MAINTAINER Ralf Kruedewagen <docker@kruedewagen.de>
# for HTTPS sources
RUN apt-get update && apt-get install -y apt-transport-https
# Install Node.js
RUN apt-get install -y curl
RUN curl -sL https://deb.nodesource.com/setup_5.x | bash -
RUN apt-get update && apt-get install -y nodejs
# Add Parsoid repo
RUN apt-key advanced --keyserver keys.gnupg.net --recv-keys 664C383A3566A3481B942F007A322AC6E84AFDD2
RUN echo "deb https://releases.wikimedia.org/debian jessie-mediawiki main" > /etc/apt/sources.list.d/parsoid.list
# Install Parsoid
RUN apt-get update && apt-get install -y parsoid
# Copy config
ADD config.yaml /etc/mediawiki/parsoid/
EXPOSE 8142
CMD ["/usr/bin/nodejs", "/usr/lib/parsoid/src/bin/server.js", "-c", "/etc/mediawiki/parsoid/config.yaml"]
Image bauen:
docker build -t parsoid /data/docker/parsoid/
Container starten (IP des Dockerhost einsetzen):
docker run -d --name parsoid -p 8142:8142 --add-host=dockerhost:172.17.0.1 parsoid
oder mit zwei URLs:
docker run -d --name parsoid -p 8142:8142 --add-host=dockerhost:172.17.0.1 --add-host=www.example.org:172.17.0.1 parsoid
oder inkl. automatischem Restart:
docker run -d --name parsoid -p 8142:8142 --add-host=dockerhost:172.17.0.1 --add-host=www.example.org:172.17.0.1 --restart=always parsoid
optional mit "--restart=unless-stopped"
Images erstellen nach Änderungen im Container
Man kann Änderungen im Container in ein neues Image "committen". Dabei wird aus dem Basis-Image plus den Änderungen ein neues Image erstellt.
1. Basis-Image holen
2. Container darauf aufsetzen
3. Änderungen im Container vornehmen (z.B. im o.g. Beispiel die Webseite ändern)
4. Container ID feststellen
docker ps -l
5. Neues Images aus laufendem Container bauen:
docker commit <CONTAINER ID> <NEUES IMAGE> docker commit 05c85da33c4a meinnginx2 docker commit -m="Webseite angepasst + vim installiert" -a "Ralf Kruedewagen" 05c85da33c4a meinnginx2
6. Neues Image inspizieren
docker inspect meinnginx2
Image auf Docker Hub erstellen
- Git Repository (z.B. aus GitHub), das Dockerfile und weiteren Dateien enthält, in Docker Hub referenzieren
- Nach jedem Commit (Push) im Git Repo wird neues Images erstellt.
Weitere Steuerungsmöglichkeiten
- Script kann über Variablen das Verhalten der Container steuern
Dockerfile
Siehe:
Container
- siehe c't 15/17 S.120 (Beispiel MySQL in Container packen, X-Anwendung im Container mit SSH), http://ct.de/yqws
Anlegen und Starten
Container in einem Rutsch anlegen und starten (und auch Image herunterladen falls nötig):
docker run --name meindebian -it debian
- Wordpress mit MySQL
mkdir /data/mysqlcontainer docker run -d --name meinmysql -v /data/mysqlcontainer/:/var/lib/mysql/ -e MYSQL_ROOT_PASSWORD=xxx mysql docker run -d --name meinwordpress --link meinmysql:mysql -p 8080:80 wordpress
- Parameter: "--link" erstellt die MySQL-Konfig im Wordpress Container gemäß Daten/Status des MySQL Containers (Interface, IP, Port) -> "Docker Networks" ersetzt "--link"
- "-v" reicht Verzeichnisse vom Host in den Container durch (kann auch im Dockerfile fest vorgegeben sein)
Container (nur) anlegen:
docker create --name=meindebian -it debian
- Parameter: i = interaktiv, t = terminal (nötig weil es ein Basis-Image mit "Bash" als Dienst ist)
Container starten:
docker start -ia meindebian
- Parameter: i = interaktiv, a = Ausgabeumlenkung / Konsole verbinden
- Exit aus Bash stoppt den Container
Container stoppen (mehrere Container können angegeben werden):
docker stop meindebian
Container löschen (Daten im Container gegen verloren, Image bleibt unberührt):
docker rm meindebian
Managen von Containern
Laufende Container zeigen ("-a" zeigt auch nicht-laufende):
docker ps docker ps -a
Shell in laufendem Container starten:
docker exec -it meindebian bash
Shell in einem Container starten (dabei "CMD" übergehen):
docker run -it --entrypoint=/bin/bash <image> -i
Etwas im Container installieren:
docker run meindebian apt-get install -y dovecot
Ausgaben auf Konsole anzeigen (Logging):
docker logs meindebian
In syslog loggen mit Namen statt ID des Containers:
docker run ... --log-driver=syslog --log-opt tag="mycontainer"
Kommandos in Image einbauen zur Verwendung im Container
docker exec gitweb addauth test test
Debugging
- siehe LM 03/18 S.58
docker logs -f docker top docker pause | unpause docker exec -it /bin/bash docker history docker stats docker inspect
Volumes
Volumes auflisten:
docker volume docker volume inspect <VOLUME_ID>
Volume eines Containers:
docker inspect -f 'Vorlage:.Mounts' <CONTAINER_ID>
Volumes erben (hilfreich um laufenden Container zu ersetzen, zuerst laufenden Container umbenennen):
--volumes-from mycontainer
Aufräumen
Nicht mehr benötigte Container entfernen, die im Status "exited" sind:
docker rm -v $(docker ps -a -q -f status=exited)
Images löschen, die nicht in Gebrauch sind:
docker rmi $(docker images -f "dangling=true" -q)
Überflüssige Volumes finden und löschen:
docker volume ls --filter "dangling=true" docker volume prune
Unbenutze Container, Networks und Images löschen:
docker system prune
Auch unbenutzte Volumes löschen:
docker system prune --all --force --volumes
Weblinks / Quellen (u.a. auch zu Tipps zu Volumes):
- http://blog.yohanliyanage.com/2015/05/docker-clean-up-after-yourself/
- https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes
- https://medium.com/the-code-review/clean-out-your-docker-images-containers-and-volumes-with-single-commands-b8e38253c271
Tools
- docker-distribution-pruner, siehe c't 15/18 S.164
Troubleshooting
- Container starten dauernd neu
Best Pratices - Tipps & Tricks
- https://success.docker.com/article/mta-best-practices
- https://github.com/FuriKuri/docker-best-practices
- Nummer des virtuellen Netzwerkdevice (veth) im Docker-Container feststellen (siehe c't 24/17 S.157)
- zuerst Nummer des Interfaces im Container herausfinden:
cat /sys/class/net/eth0/iflink
6
- Dann auf dem Host nach dieser Nummer suchen:
grep -l "^6$" $(find /sys/devices/virtual/net -name "ifindex")
/sys/devices/virtual/net/veth034c9d0/ifindex
- Mehrere Prozesse / Applikationen in einem Container managen mit supervisord
- Docker in der Praxis: Lehren aus dem Umgang mit komplexen Web-Apps (entwickler.de)
Tools
- container-diff, pro-linux.de
- Container Structure Test zur Validierung von Docker Containern
- Prüft Container und ggf. Image auf:
- Dateisystem inspizieren (Existenz + Datei-Inhalt)
- Kommandos im Container aufrufen und Ergebnis prüfen
- Konfiguration und Metadaten des Containers
- siehe LM 10/18 S.70
- Prüft Container und ggf. Image auf:
- Backup mit Bivac: siehe c't 11/19 S.100 , https://github.com/camptocamp/bivac
Monitoring
- siehe LM 01/16 S.56
- https://github.com/newrelic/check_docker
Siehe auch
- Office-Paket Collabora Online als Docker-Container
- Parsoid als Docker-Container
- GitLab für die CI/CD Pipeline u.a. mit Docker