Benutzer-Werkzeuge

Webseiten-Werkzeuge


docker

Dies ist eine alte Version des Dokuments!


Docker

Sonstiges

https://forums.docker.com/t/some-way-to-clean-up-identify-contents-of-var-lib-docker-overlay/30604

> docker volume rm $(docker volume ls -qf dangling=true)
> docker system prune -a -f
> docker volume prune -f

Docker in Verbindung mit einer Container-Orchestrierung

Docker ist mehr als LXC

Docker – was bringt’s für Entwickler?

Ist Docker also nur ein Kommandozeilenprogramm zum Verwalten einer Containertechnologie, die sowieso in Linux integriert ist? Nein, Docker ist mehr:

  • Die Ausführungsumgebung für Container im Linux-Kernel ist eine wichtige Grundlage, jedoch für die tägliche Arbeit als Softwareentwickler nicht einfach genug verwendbar. Docker bietet ein portables Format zum Zusammenstellen und Übertragen (packaging) von Containern mit einem entsprechenden API, das ein bequemes Arbeiten mit Containern ermöglicht.
  • Docker hat einen De-facto-Standard für ein API für Anwendungscontainer geschaffen. Das hat den Vorteil, dass Tools unabhängig von der jeweiligen Containerimplementierung darauf aufsetzen können. Rund um Docker ist dadurch bereits ein reiches Ökosystem von Werkzeugen (z. B. Web-UI für Docker, Cluster-Management-Tools etc.) entstanden.
  • Docker enthält eine eigene Sprache (Dockerfile) zum Erstellen von Containern beziehungsweise den zugrunde liegenden Images über Quellcode. Mit einem Dockerfile lässt sich ein Container-Image immer wieder ohne manuelle Installations- oder Konfigurationsschritte neu erstellen.
  • Docker enthält eine Versionsverwaltung für Container-Images.
  • Container-Images können auf anderen Images basieren. Man kann also einen Basiscontainer für beispielsweise ASP.NET vNext erstellen und diesen als Grundlage für viele verschiedene Anwendungen verwenden.
  • Mit dem Docker Hub steht eine Plattform zum Teilen von Container-Images und Dockerfiles zur Verfügung. Hersteller wie Microsoft können dort offizielle Basis-Images anbieten (z. B. für ASP.NET vNext unter Ubuntu), und Sie können darauf aufbauen. Sie können aber auch Docker-Images für Ihre eigene Software dort anbieten, damit Ihre Kunden mit Docker Ihre Anwendung leichter installieren und betreiben können.

Im Docker-Container Kommandos ausführen

https://gist.github.com/ElijahLynn/72cb111c7caf32a73d6f

docker exec -it -u root 7005b71222f6 free -h
docker exec -it -u root 7005b71222f6 mysql -uroot -pYWwzNHR6Cg -e "SHOW STATUS LIKE 'wsrep_last_committed';"
echo "free -h" | sudo docker exec -i -u root 7005b71222f6 /bin/bash -
echo "mysql -uroot -pYWwzNHR6Cg -e 'SHOW STATUS LIKE \"wsrep_last_committed\";'" | sudo docker exec -i -u root 7005b71222f6 /bin/bash -

Installation

> apt install docker docker.io

https://hub.docker.comhttps://hub.docker.com/_/mysql/

> docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
802b00ed6f79: Pull complete 
30f19a05b898: Pull complete 
3e43303be5e9: Pull complete 
94b281824ae2: Pull complete 
51eb397095b1: Pull complete 
54567da6fdf0: Pull complete 
bc57ddb85cce: Pull complete 
d6cd3c7302aa: Pull complete 
d8263dad8dbb: Pull complete 
780f2f86056d: Pull complete 
8e0761cb58cd: Pull complete 
7588cfc269e5: Pull complete 
Digest: sha256:038f5f6ea8c8f63cfce1bce9c057ab3691cad867e18da8ad4ba6c90874d0537a
Status: Downloaded newer image for mysql:latest

> docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              6a834f03bd02        4 weeks ago         484MB

jetzt können wir im Container eine BASH öffnen:

> docker container start -ai db01

oder

> docker container run -it --name db00 mysql bash
root@3fe6bea75eeb:/#
root@3fe6bea75eeb:/# apt update
root@3fe6bea75eeb:/# apt install ssh vim screen
root@3fe6bea75eeb:/# exit

den Container "db01" mit Anbindung an den lokalen Port "3321" anlegen+starten

> docker container run -de MYSQL_ROOT_PASSWORD=geheim -p 3321:3306 --name db01 mysql
> docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
3fe6bea75eeb        mysql               "docker-entrypoint.s…"   8 seconds ago       Exited (1) 4 seconds ago                       db01

wenn sie läuft, dann kann man so die Statistischen Werte des Containers sehen:

> docker container stats db01
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
3fe6bea75eeb        db01                0.35%               375.8MiB / 7.746GiB   4.74%               4.15kB / 0B         0B / 997MB          36
> docker container exec -it db01 bash
root@3fe6bea75eeb:/#
root@3fe6bea75eeb:/# exit

den Container anhalten

> docker container stop db01

den Container löschen

> docker container rm db01

einen neuen Container anlegen und starten, der auch per SSH erreichbar sein soll + SSH-Schlüssel hinterlegen + SSHD-Installation:

> docker container run -de MYSQL_ROOT_PASSWORD=geheim -p 3321:3306 -p 2221:22 --name db02 mysql
> docker container exec -it db02 bash -c "apt -y update ; apt -y install ssh vim screen ; mkdir /root/.ssh ; echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGAWEqDGlpnFbWIWNqwo7CqS/PQHWadUM/sPHPRMd4Io root' > /root/.ssh/authorized_keys ; echo -e '\nPermitRootLogin yes\nPubkeyAuthentication yes\nPasswordAuthentication no\n' >> /etc/ssh/sshd_config ; service ssh restart"
> ssh -i .ssh/id_ed25519 root@localhost -p 2221

leider funktioniert das nur auf IPv6:

> netstat -antp | fgrep 21
tcp6       0      0 :::3321                 :::*                    LISTEN      974/docker-proxy    
tcp6       0      0 :::2221                 :::*                    LISTEN      986/docker-proxy    

https://stackoverflow.com/questions/29957143/make-docker-use-ipv4-for-port-binding#30006034

> sysctl net.ipv6.bindv6only

IPv6

docker hat ja ein default bridge netzwerk, man kann mit diesen kommandos 2 neue bridges erstellen, die ipv6 können:

> docker network create bridge6 --ipv6 -o com.docker.network.bridge.host_binding_ipv4="::"
> docker network create bridge64 --ipv6

das 1. aktiviert ipv6 im container und macht, dass ports per default auf ipv6 gepublished werden, also -p "8080:80" auf bridge6 verhält sich dann so wie -p "[::]:8080:80" sich auf der normalen bridge verhalten würde

das 2. aktiviert einfach nur ipv6 im container, d.h. -p "8080:80" auf bridge64 führt dazu, dass der service auf dem host unter [::]:8080 und 0.0.0.0:8080 erreichbar ist

wichtig zu wissen, ipv6-only services im container sind nicht erreichbar, egal was man macht, denn docker macht auch in ipv6 aktivierten netzwerken immer ipv6→ipv4 und/oder ipv4→ipv4 (applikationen im container müssen also den socket auf dem sie listen wollen mit dem flag IPV6_V6ONLY gleich false oder 0 erstellen, in nginx geht das mit ipv6only=off)

einen Docker-Container auf einer dedizierten IP per TAP laufen lassen

Testumgebung:

  • Name des Docker-Containers: test01
  • IP des Hostsystems: 10.10.1.2
  • IP für des Docker-Container: 10.10.1.21
  • MySQL-Port (umkonfiguriert von 3306 auf 3321): 3321
  • Galera-Port (SST, nicht umkonfigurierbar): 4444
  • Galera-Port (Galera Cluster replication traffic): 4567
  • Galera-Port (IST, nicht umkonfigurierbar): 4568
  • Mount-Point, in dem die Datenbankdateien liegen: /var/lib/mysql/port_3321
  • hier werden unsere frischen Docker-Images gebaut: hubdocker
  • dieses Docker-Image verwenden wir: ubuntu18:20190619_0724

den Docker-Container mit dedizierter IP starten

ip tuntap add mode tap name tap21
ip a add 10.10.1.21/16 dev tap21
brctl addif br0 tap21
docker run -dit --restart=always --name test01 --add-host test01:10.10.1.2 10.10.1.21 -p 3321:3321 -p 4444:4444 -p 4567:4567 -p 4568:4568 -h test01 -v /root/bin_docker:/root/bin -v /root/.my.cnf:/root/.my.cnf -v /var/lib/mysql/port_3321:/var/lib/mysql -w /root hubdocker:443/ubuntu18:20190619_0724

den Docker-Container mit dedizierter IP stoppen

docker container stop test01
docker container rm test01
brctl delif br0 tap21
ip a del 10.10.1.21/16 dev tap21
ip tuntap del mode tap name tap21

einen Docker-Container auf einer dedizierten IP per Bridge laufen lassen

docker run -itd ubuntu:latest
  apt-get update
  apt-get install net-tools
docker run --network=newnet -itd ubuntu
docker network create --driver=bridge --subnet=172.28.0.0/16 --ip-range=172.28.5.0/24 --gateway=172.28.5.254 mysuperbridgenet
docker run -itd --network=newnet -p 80:80 http

Docker-Swarm

über ETCD

ETCD starten

root@host01:~# cd /root/service/
root@host01:~/service# bash etcd.sh
docker network create --driver overlay dbnetz3306
 
#docker service update --network-add dbnetz3306 etcd
 
docker service create --name etcd --replicas 3 \
             --network services \
             --network dbnetz3306 \
             --detach=false -e SERVICE_NAME=etcd -e MIN_SEEDS_COUNT=3 appcelerator/etcd --advertise-client-urls http://etcd:2379
# cd /root/service
# bash etcd.sh
pf7s765wzpjpc18jtsfhh6iz1
8dxyua2t5izyz4plnq58447gw
llkrwh0l9ktpiix2ci91usgyw
li48rs2rlh0wlme7ul38q3a0u
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 
# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                      PORTS
li48rs2rlh0w        etcd                replicated          3/3                 appcelerator/etcd:latest   
t8laa0ewj5rj        services_registry   replicated          1/1                 registry:latest            *:443->443/tcp
# curl  -v GET https://registry.drdkvm/v2/_catalog

jp

jp --help
jq - commandline JSON processor [version 1.6]
 
Usage:  jq [options] <jq filter> [file...]
        jq [options] --args <jq filter> [strings...]
        jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
 
jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.
 
The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).
 
For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq
 
Example:
 
        $ echo '{"foo": 0}' | jq .
        {
                "foo": 0
        }
 
Some of the options include:
  -c               compact instead of pretty-printed output;
  -n               use `null` as the single input value;
  -e               set the exit status code based on the output;
  -s               read (slurp) all inputs into an array; apply filter to it;
  -r               output raw strings, not JSON texts;
  -R               read raw strings, not JSON texts;
  -C               colorize JSON;
  -M               monochrome (don't colorize JSON);
  -S               sort keys of objects on output;
  --tab            use tabs for indentation;
  --arg a v        set variable $a to value <v>;
  --argjson a v    set variable $a to JSON value <v>;
  --slurpfile a f  set variable $a to an array of JSON texts read from <f>;
  --rawfile a f    set variable $a to a string consisting of the contents of <f>;
  --args           remaining arguments are string arguments, not files;
  --jsonargs       remaining arguments are JSON arguments, not files;
  --               terminates argument processing;
 
Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].
 
See the manpage for more options.

ETCD benutzen

in einen Docker-Container (db3306_proxysql.1) einloggen

root@host01:~# docker exec -uroot -it $(docker ps -f name=db3306_proxysql.1 -q | head -n1) bash

alle IPs ausgeben

# hostname -I
10.0.0.230 172.18.0.10 10.33.06.42

die IP-Adresse aus dem Hostnamen ermitteln (geht nur wenn DNS funktioniert)

# hostname -i
10.33.06.42

nachschauen, ob das Protokoll vor der IP bzw. dem Hostnamen steht; wenn nicht, dann davor hinschreiben

if [ "${DISCOVERY_SERVICE:0:4}" != "http" ]; then
        DISCOVERY_SERVICE="http://${DISCOVERY_SERVICE}"
fi

die eigene IP in den ETCD eintragen (ist nur für 60 Sekunden gültig)

# curl "$DISCOVERY_SERVICE/v2/keys/proxysql-cluster/$CLUSTER_NAME" -XPOST -d value="$(hostname -i)" -d ttl=60

kontrollieren, ob sie drin steht:

# curl "$DISCOVERY_SERVICE/v2/keys/proxysql-cluster/$CLUSTER_NAME" | jq -r '.node.nodes[]?.value' | fgrep -v null | awk -F'/' '{print $(NF)}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   301  100   301    0     0  47178      0 --:--:-- --:--:-- --:--:-- 50166
10.33.06.42

nach 60 Sekunden ist der Eintrag wieder raus:

# curl "$DISCOVERY_SERVICE/v2/keys/proxysql-cluster/$CLUSTER_NAME" | jq -r '.node.nodes[]?.value' | fgrep -v null | awk -F'/' '{print $(NF)}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   109  100   109    0     0  17490      0 --:--:-- --:--:-- --:--:-- 18166

ETCD-Beispielaktionen

den Wert "9999" in das Verzeichnis "test" reinschreiben:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/ -XPOST -d value="9999"
{"action":"create","node":{"key":"/test/00000000000004002903","value":"9999","modifiedIndex":4002903,"createdIndex":4002903}}

den Wert auslesen:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/ 2>/dev/null | jq -r '.node.nodes[]?.value'
9999

den Schlüssel auslesen:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/ 2>/dev/null | jq -r '.node.nodes[]?.key'
/test/00000000000004002903

den Schlüssel mit Wert löschen:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/00000000000004002903 -XDELETE                
{"action":"delete","node":{"key":"/test/00000000000004002903","modifiedIndex":4002967,"createdIndex":4002903},"prevNode":{"key":"/test/00000000000004002903","value":"9999","modifiedIndex":4002903,"createdIndex":4002903}}

jetzt sind Schlüssel und Wert raus:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/ 2>/dev/null | jq -r '.node.nodes[]?.key'
[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test/ 2>/dev/null | jq -r '.node.nodes[]?.value'

das Verzeichnis mit allen Schlüsseln samt Werten löschen:

[root@eceae28581e6 ~]# curl http://etcd:2379/v2/keys/test\?recursive\=true -XDELETE

Container-Orchestrierung

Beziehung zwischen Kubernetes und Docker

Kubernetes wird am häufigsten zusammen mit von Docker verwalteten Containern verwendet. Doch ist es nicht strikt davon abhängig. Wie also funktionieren beide zusammen? Dies wird in diesem ausführlichen Kubernetes-Guide erläutert. Hierfür kommt zudem Payara Micro zum Einsatz, eine leichtgewichtige Open-Source-Plattform, um in einer Cloud-Kubernetes-Umgebung zu deployen.

Kubernetes definiert ein Container Runtime Interface (CRI), das Container-Plattformen implementieren müssen, um kompatibel zu sein. Diese Implementierungen werden umgangssprachlich als „Shims“ bezeichnet. Das macht die Kubernetes-Plattform unabhängig, so dass anstelle von Docker auch andere Plattformen mit entsprechenden Shims, wie z. B. CRI-O oder KataContainers verwendet werden können. Die automatische Skalierung sowie die Failover-Sicherung sind nur zwei der Vorteile moderner Cloud-Plattformen, wie Amazon AWS, Microsoft Azure und Google Cloud Platform (GCP). Allerdings gibt es immer noch Schwierigkeiten mit dieser Architektur, wie z. B. die folgenden:

  1. Das Starten und Stoppen einer Instanz ist langsam.
  2. Die Kommunikation zwischen den Nodes in dieser Architektur kann sehr komplex sein.

Kubernetes ist eine Plattform für die Verwaltung von containerisierten Services. Dabei handelt es sich um ein Tool, mit dem Details wie z. B. das Separieren von Nodes abstrahiert werden können, während andere Dinge, wie Rolling Upgrades, Failover und Services automatisiert werden. Die Idee ist, auf ähnliche Weise deployen zu können, egal ob man dies lokal oder in der Cloud tun möchte.

…folgenden Tools müssen für dieses Beispiel bereits installiert und konfiguriert sein:

  • Maven (v3+)
  • JDK 8
  • Docker

Kubernetes ist für den Einsatz mit einem Cloud-Anbieter vorgesehen. Es gibt dennoch mehrere Möglichkeiten, wie man einen Kubernetes-Cluster lokal betreiben kann. Grundsätzlich wird jede Implementierung am Ende das gleiche Interface über kubectl bereitstellen.

Verwendet man Linux, so sind MicroK8s und Minikube die zwei Wegbereiter. Letzteres läuft unter Windows, MacOS und Linux. Minikube führt einen Kubernetes-Cluster in einer einzelnen VM aus, wohin hingegen MicroK8s mit Snap installiert wird und lokal mit minimalem Overhead läuft.

MicroK8s wurde vom Kubernetes-Team Canonical entwickelt, deshalb muss es mit dem Canonical-Linux-Packetmanager (snapd) installiert werden.

  1. Canonical-Linux-Packetmanager installieren: apt install snapd
  2. MicroK8s installieren: snap install microk8s –classic
  3. Kubernetes-Main-Utility umbenennen (um kubectl anstatt microk8s.kubectl benutzen zu können): snap alias microk8s.kubectl kubectl
  4. das umbenennen rückgängig machen: snap unalias kubectl

Einige wichtige Befehle, die nur von MicroK8s zur Verfügung gestellt werden:

  • Starts MicroK8s and allows provisioning nodes: microk8s.start
  • Stops MicroK8s: microk8s.stop
  • Clear all resources and revert kubernetes to a 'clean' state: microk8s.reset

Wir müssen sicherstellen, dass MicroK8s gestartet wird, bevor wir versuchen kubectl zum Starten von Services einzusetzen (es muss auch für den oben genannten kubectl get all-Befehl in Betrieb sein).

prüfen, ob MicroK8s richtig installiert wurde:

> kubectl get all

Fatzit: Kubernetes erfüllt die Aufgabe der Container-Orchestrierung, statt Kubernetes kann auch Docker-Swarm eingesetzt werden.

Kubernetes oder Docker Swarm?

Tools zur Container-Orchestrierung: Kubernetes oder Docker Swarm? - vom 3. Mai 2018, von Hartmut Schlosser

Wer vor der Aufgabe steht, mehrere containerisierte Services in einem Cluster zu verwalten, kommt an einer Lösung zur Container-Orchestrierung kaum vorbei. Etabliert haben sich in den letzten Monaten hier vor allem Kubernetes und Docker Swarm. Im Interview mit JAXenter erklärt Jörg Müller, Principal Consultant bei innoQ und Sprecher auf dem Microservices Summit, welches Tool für welchen Einsatzzweck geeignet ist.

Kubernetes konkurriert als Orchestrierungslösung u.a. mit Docker Swarm. Wo liegen hier die Unterschiede:

Fatzit: Docker-Swarm erfüllt die Aufgabe der Container-Orchestrierung, statt Docker-Swarm kann auch Kubernetes eingesetzt werden.

  • Beide lösen das Problem der Container-Orchestrierung gut, benutzen dabei aber unterschiedliche Philosophien.
  • Docker Swarm setzt auf eine einfache Installation und einen eher monolithischen Ansatz. Alles Notwendige ist in einem Binary enthalten und kann damit leicht auf mehrere Nodes verteilt werden. Auch die Konfiguration folgt diesem Prinzip der einfachen Nutzung. Sie ist in vielen Fällen nicht komplizierter als die Konfiguration mehrerer Container mit Docker-Compose, was viele auch lokal kennen und verwenden.
  • Kubernetes verfolgt einen kleinteiligen Ansatz. Es besteht aus vielen Komponenten, von denen es oft noch unterschiedliche Implementierungen gibt. So listet die Kubernetes Webseite z.B. aktuell 18 Möglichkeiten, um das Networking zwischen den Nodes zu implementieren. Das macht die Installation aufwendiger und bedingt normalerweise den Einsatz von Installationstools, wie z.B. KOPS. Gleichzeitig ist es dadurch deutlich flexibler und kann den individuellen Bedürfnissen in seiner Umgebung sehr gut angepasst werden.
  • Ähnlich ist es mit der Konfiguration. Diese ist bei Kubernetes deutlich umfangreicher. Aber auch hier gibt es viel Unterstützung durch Werkzeuge. Die Einstiegshürde ist bei Kubernetes sicher höher als bei Docker Swarm. Letztendlich werden die eigenen Anforderungen an die Anpassungsfähigkeit des Clusters ausschlaggebend für die Entscheidung für die eine oder andere Lösung sein.
  • Momentan muss man bei der Installation eines Kubernetes Clusters sehr darauf achten, dass die notwendigen Security-Funktionen installiert und eingerichtet werden. Dabei geht es um Beschränkungen der Möglichkeiten in einzelnen Containern oder Pods, um umfangreiche Einstellungsmöglichkeiten für Nutzerrechte und um Firewall-Regeln innerhalb des Clusters. Inzwischen bieten viele der Installationstools dafür bereits Lösungen, aber oft ist das noch mit Mehraufwand verbunden.
/home/http/wiki/data/attic/docker.1724099919.txt · Zuletzt geändert: von manfred