Benutzer-Werkzeuge

Webseiten-Werkzeuge


docker

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
docker [2023-06-23 12:18:06] – [Im Docker-Container Kommandos ausführen] manfreddocker [2025-07-18 00:42:16] (aktuell) – [IPv6] david
Zeile 1: Zeile 1:
 +====== Docker ======
 +
 +  * [[http://www.linux-magazin.de/ausgaben/2017/04/rdbms-container/?utm-source=linux-magazin%20online%20newsletter]]
 +  * [[http://galeracluster.com/2015/05/getting-started-galera-with-docker-part-1/]]
 +  * [[https://www.youtube.com/watch?v=AkwtFayUlvA&list=PL5GusAoXMAEzCrlXZPGpUoZaVz20M_Vu3|Docker Tutorial - Reihe]]
 +  * [[https://www.youtube.com/watch?v=ytvht7SX0YQ|Docker Basics]]
 +  * [[https://github.com/abdala/docker-multi-stage-multi-environment|Docker multi-stage and multi-environment examples]]
 +
 +
 +===== 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
 +
 +//für zukünftige Projekte __nur__ ''docker-ce'' aus [[https://docs.docker.com/engine/install/ubuntu/|Docker-Repo]] nutzen, __nicht__ ''docker.io'' aus dem Ubuntu-Repo nutzen//
 +
 +
 +===== Docker in Verbindung mit einer Container-Orchestrierung =====
 +
 +[[Container-Orchestrierung]]
 +
 +
 +===== Docker ist mehr als LXC =====
 +
 +[[https://entwickler.de/online/docker-was-bringts-fuer-entwickler-160323.html|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.com]] -> [[https://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 :::3321                 :::                   LISTEN      974/docker-proxy    
 +  tcp6            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 ein default bridge netzwerk welches sich zwecks abwärtskompatibilität anders verhält als selbst erstellte bridge netzwerke, daher ist es empfehlenswert eigene bridge netzwerke zu erstellen:
 +
 +  > docker network create bridge64 --ipv6
 +  > docker network create bridge6 --ipv6 --ipv4=false
 +  > docker network create bridge4
 +
 +man kann auch angeben auf welcher adresse ports standardmäßig exposed/published werden (nicht von dem "ipv4" im namen verwirren lassen, man kann sowohl ipv6 als auch ipv4 angeben):
 +
 +  > docker network create bridge64 --ipv6 -o com.docker.network.bridge.host_binding_ipv4="::"
 +  > docker network create bridge64 --ipv6 -o com.docker.network.bridge.host_binding_ipv4="0.0.0.0"
 +  > docker network create bridge64 --ipv6 -o com.docker.network.bridge.host_binding_ipv4="::1"
 +  > docker network create bridge64 --ipv6 -o com.docker.network.bridge.host_binding_ipv4="127.0.0.1"
 +
 +dadurch verhält sich die minimale port notation (nur port ohne ip) so als ob man die jeweils konfigurierte ip mit angegeben hätte (die beiden letzteren sind äußerst praktisch, wenn die services nur auf localhost erreichbar sein sollen):
 +
 +  * ''-p "8080:80"'' -> ''-p "[::]:8080:80"''
 +  * ''-p "8080:80"'' -> ''-p "0.0.0.0:8080:80"''
 +  * ''-p "8080:80"'' -> ''-p "[::1]:8080:80"''
 +  * ''-p "8080:80"'' -> ''-p "127.0.0.1:8080:80"''
 +
 +wichtig zu wissen ist, dass ipv6-only services im container standardmäßig nicht erreichbar sind, egal welchen oben gezeigten weg man wählt, denn docker macht auch in ipv6 aktivierten netzwerken immer ipv6 -> ipv4 und/oder ipv4 -> ipv4 nat (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 bspw. mit ipv6only=off), alternativ kann man den docker-proxy umkonfigurieren oder deaktivieren und statt nat den routed mode nutzen, siehe dazu die offiziellen docker docs
 +
 +
 +===== 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 =====
 +
 +  * [[https://www.computerweekly.com/de/ratgeber/Grundlagen-und-Tipps-fuer-die-Docker-Vernetzung|Grundlagen und Tipps für die Docker-Vernetzung]]
 +  * [[https://entwickler.de/online/development/docker-netzwerk-container-microservices-126443.html|Docker Network Magic – der elegante Umgang mit Netzwerken]]
 +
 +  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 =====
 +
 +[[Docker-Swarm]]
 +
 +
 +===== über ETCD =====
 +
 +
 +==== ETCD starten ====
 +
 +  * [[https://github.com/coreos/etcd-operator/issues/1323]] => [[https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/container.md#running-a-single-node-etcd-1|Use persistent volumes to not lose etcd member data after a pod dies (or is deleted).]] => ''-____-data-dir=/etcd-data'' //(das macht aber eigentlich keinen Sinn, weil die Daten im ETCD normalerweise nach 60 Sekunden verschwinden sollen, um aktualisiert zu werden)//
 +
 +  root@host01:~# cd /root/service/
 +  root@host01:~/service# bash etcd.sh
 +
 +<file 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
 +</file>
 +
 +  # 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 ===
 +
 +<file text 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.
 +</file>
 +
 +
 +==== 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      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      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 ====
 +
 +  * [[https://jaxenter.de/kubernetes/kubernetes-docker-container-payara-84679|Container-Orchestrierung: Was ist Kubernetes und wie verhält es sich zu Docker?]] - vom 31. Juli 2019, von Matthew Gill 
 +
 +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. [[https://cri-o.io/|CRI-O]] oder [[https://katacontainers.io/|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:
 +  - Das Starten und Stoppen einer Instanz ist langsam.
 +  - 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.
 +  - Canonical-Linux-Packetmanager installieren: ''apt install snapd''
 +  - MicroK8s installieren: ''snap install microk8s –classic''
 +  - Kubernetes-Main-Utility umbenennen (//um ''kubectl'' anstatt ''microk8s.kubectl'' benutzen zu können//): ''snap alias microk8s.kubectl kubectl''
 +  - 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? ====
 +
 +[[https://jaxenter.de/kubernetes-docker-swarm-70654|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.
 +