Entdecken Sie Millionen von E-Books, Hörbüchern und vieles mehr mit einer kostenlosen Testversion

Nur $11.99/Monat nach der Testphase. Jederzeit kündbar.

K8s Applications mit MicroK8S auf Raspberry PI
K8s Applications mit MicroK8S auf Raspberry PI
K8s Applications mit MicroK8S auf Raspberry PI
eBook876 Seiten4 Stunden

K8s Applications mit MicroK8S auf Raspberry PI

Bewertung: 0 von 5 Sternen

()

Vorschau lesen

Über dieses E-Book

Beispiele für das Entwickeln und Betreiben von Anwendungen auf einem MicroK8s Kubernetes Cluster auf Raspberry PI Basis. Es werden die folgenden Elemente beschrieben

Infrastrukturservices
◦ Repository
◦ NTP
◦ LDAP
◦ Secretmanagement
Monitoringservices
◦ Prometheus
◦ Grafana
◦ Alert-Agent
Storage und Backup
◦ Longhorn
◦ Externe Storage
Webservice – Stateful
◦ Joomla
◦ PostgresDB
Gitlab
◦ Build-Pipelines
◦ GitRunner
Buildautomatisierung
◦ Eigene einfache Buildpipeline
◦ kpt
◦ kustomize
Servicemesh Linkerd

Alle Services werden als yaml-File beschrieben.
SpracheDeutsch
Herausgeberneobooks
Erscheinungsdatum16. Jan. 2022
ISBN9783742770134
K8s Applications mit MicroK8S auf Raspberry PI

Ähnlich wie K8s Applications mit MicroK8S auf Raspberry PI

Ähnliche E-Books

Allgemeine Belletristik für Sie

Mehr anzeigen

Ähnliche Artikel

Rezensionen für K8s Applications mit MicroK8S auf Raspberry PI

Bewertung: 0 von 5 Sternen
0 Bewertungen

0 Bewertungen0 Rezensionen

Wie hat es Ihnen gefallen?

Zum Bewerten, tippen

Die Rezension muss mindestens 10 Wörter umfassen

    Buchvorschau

    K8s Applications mit MicroK8S auf Raspberry PI - Alfred Sabitzer

    K8s Applications

    mit MicroK8S

    auf Raspberry PI

    Beispiele für das Entwickeln und Betreiben von Anwendungen auf einem MicroK8s Kubernetes Cluster auf Raspberry PI Basis.

    Alfred Sabitzer

    https://www.linkedin.com/in/alfred-sabitzer-805312183/

    https://www.xing.com/profile/Alfred_Sabitzer/cv

    Vorwort

    Die Idee eine „Cloud zu bauen entstand während der Corona-Zeit. Anstatt „Fernsehen könnte man doch was Sinnvolles ausprobieren. Außerdem ist der vorhandene Raspberry 4 bereits überlastet, und kann schwerlich neue Dienste anbieten. Da wäre doch ein System, das skalierbar ist, beliebig viele Services anbieten kann usw. doch genau das Richtige. Außerdem sind Microservices leichter auf neue Hardware portierbar! Ich erinnere mich noch genau, wie aufwändig der Umstieg vom Raspberry 2 auf den Raspberry 3 und dann auf den Raspberry 4 war. Ich musste jedes mal aufs Neue nachdenken, wie den die Installation genau geht, habe viel Zeit investiert und  erreichte am Ende bestenfalls, dass ich nachher dieselben Dienste nutzen konnte wie vorher:)

    Darum: eine Cloud muss her.

    Generell: Der Bau einer Cloud ist ein komplexes Unternehmen (am einfachsten ist es, wenn man sich in einer bereits existenten Cloud einmietet – da gibt es genug Anbieter am Markt).

    Dieses Buch beschreibt die einzelnen Schritte, die ich durchgeführt habe um mir meine eigene Cloud zu bauen. Hier werden aufbauend auf dem Hardwareaufbau im Buch Bau einer K8s bare-metal-cloud mit RaspberryPI ISBN 978-3-7534-9851-4 unterschiedliche Konzepte und Ideen beschrieben. Der Bau von Microservices, das Einrichten einer CI/CD-Strecke, kpt, kustomize, Servicemesh usw, wird anhand von Beispielen soweit möglich erklärt.

    Hier finden sich viele Codefragmente, die eine Idee geben können, wie jemand das bei sich zu Hause selbst tun könnte. Diese Codeteile erheben keinen Anspruch auf Funktionalität oder dergleichen. Die Verwendung erfolgt auf eigenes Risiko.

    Generell würde mich der Austausch mit anderen „Cloud"-Bauern interessieren. Ideen, Verbesserungen, Anregungen udglm. sind herzlich willkommen. Der Auto ist erreichbar unter microk8s.raspberry@slainte.at erreichbar.

    Die in diesem Buch angeführten Programmteile gibt es online auf https://gitlab.com/Alfred-Sabitzer/k8sapp sowie auf https://gitlab.com/Alfred-Sabitzer/ldap .

    Einleitung

    Nach dem Aufsetzen des microK8s-Cluster auf RaspberryPI und prinzipiellem Einrichten der Infrastruktur (siehe „Bau einer K8s bare-metal-cloud mit RaspberryPI"), dient diese Beschreibung um die Schritte, Versuche und Fehlversuche zu dokumentieren, die ich beim Entwicklen, Einrichten und Betreiben von Anwendungen im k8s-Cluster unternommen habe. Es werden die folgenden Teile beschrieben

    Infrastrukturservices

    Repository

    NTP

    LDAP

    Secretmanagement

    Monitoringservices

    Prometheus

    Grafana

    Alert-Agent

    Storage und Backup

    Longhorn

    Externe Storage

    Webservice – Stateful

    Joomla

    PostgresDB

    Gitlab

    Build-Pipelines

    GitRunner

    Buildautomatisierung

    Eigene einfache Buildpipeline

    kpt

    kustomize

    Servicemesh Linkerd

    Alle Services werden als yaml-File beschrieben. Die Sourcen befinden sich auf https://gitlab.com/Alfred-Sabitzer/ldap sowie auf https://gitlab.com/Alfred-Sabitzer/k8sapp

    Leider ist nicht alles am Raspberry mit arm-Architekture verfügbar. Somit kann ein K8S-Cluster auf Raspberry Basis nicht wirklich mit einem Cluster auf Intel-Basis (oder noch besser in einer wirklichen Cloud wie Google oder Amazon) verglichen werden. Es ist dennoch eine gute und kostengünstige Basis um die Prinzipien kennen zu lernen, und Hands-On einen Cluster vom Scratch aufzubauen.

    Der hier beschriebene Cluster baut auf dem Buch

    OEBPS/images/image0001.png

    Bau einer K8s bare-metal-cloud mit RaspberryPI ISBN 978-3-7534-9851-4 auf.

    Gutes Gelingen!

    Architektur des Clusters

    Inspiration:

    https://de.wikipedia.org/wiki/Raspberry_Pi

    https://www.picocluster.com/

    Das System besteht aus einem RaspberryPI-Cluster mit microk8s. Die Raspberry-Version ist 4 mit 8GB RAM und einer 64GB SDRAM. Der Cluster besteht aus 5 Nodes. Jeder Node hat zusätzlich noch eine externe 110GB USB-SSD-Platte die als Clusterstorage konfiguriert ist.

    OEBPS/images/image0002.jpg

    Abbildung 1: k8s-Cluster

    PC ist die Abkürzung für pico-cluster. Es gibt pc1 bis pc5.

    Die SSD-Disken werden mit Longhorn verwaltet. Es steht folgender Speicherplatz für PVC'S (permanent volume claims) zur Verfügung:

    OEBPS/images/image0003.jpg

    Abbildung 2: Longhorn Clusterstorage

    Physikalisch sieht das aus wie folgt:

    OEBPS/images/image0004.jpg

    Abbildung 3: pico-Cluster von vorne

    Man sieht hier den Cluster von vorne mit der Stromversorgung und dem Nway-Switch.

    OEBPS/images/image0005.jpg

    Abbildung 4: pico-Cluster von der Seite

    Hier erkennt man den Cluster mit dem eingebauten Lüfter.

    OEBPS/images/image0006.jpg

    Abbildung 5: pico-Cluster von hinten

    Hier kann man gut die Cluster-Storage erkennen. Aus thermischen Gründen befinden sich die SSD-Platten ausserhalb des Pico-Clusters.

    Der Aufbau wird in „Bau einer K8s bare-metal-cloud mit RaspberryPI" beschrieben.

    Ein Übersicht gibt folgendes Bild:

    OEBPS/images/image0007.jpg

    Abbildung 6: MicroK8S Cluster - Gesamtsystem

    Namespaces

    Inspiration:

    https://microk8s.io/docs/registry-built-in

    Um den Cluster richtig betreiben zu können, sind auch Namespaces wichtig. Es sind (neben den technischen Namespaces, die mit k8s automatisch angelegt werden) noch die folgenden Namespaces vorhanden.

    ---

    apiVersion: v1

    kind: Namespace

    metadata:

    labels:

    kubernetes.io/metadata.name: slainte

    name: slainte

    spec:

    finalizers:

    - kubernetes

    ---

    apiVersion: v1

    kind: Namespace

    metadata:

    labels:

    kubernetes.io/metadata.name: default

    name: default

    spec:

    finalizers:

    - kubernetes

    ---

    apiVersion: v1

    kind: Namespace

    metadata:

    labels:

    kubernetes.io/metadata.name: admin

    name: admin

    spec:

    finalizers:

    - kubernetes

    ---

    Slainte ist quasi die Produktion (von aussen erreichbar). Default ist ein Test-URL der auch von aussen erreichbar ist. Die Services in admin haben keinen Ingress (sind von aussen nicht erreichbar), werden aber idR. als LoadBalancer-Services bereitgestellt.

    IP-Adressen

    Inspiration:

    https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview

    Die im Cluster verfügbaren Bereiche sind:

    OEBPS/images/image0008.jpg

    Im Konkreten:

    k8s.slainte.at                                                87.243.186.29

    default.k8s.slainte.at                                87.243.186.29

    Aus dem Cluster selbst:

    alfred@pc1:~/yaml$ k get svc --all-namespaces | grep -v ''

    NAMESPACE  NAME  TYPE  CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE

    ingress  ingress   LoadBalancer  10.152.183.126  192.168.0.210  443:31287/TCP,80:31681/TCP  22h

    kube-system  kubernetes-dashboard  LoadBalancer  10.152.183.150  192.168.0.211  443:31449/TCP  22h

    longhorn-system  longhorn-frontend  LoadBalancer  10.152.183.199  192.168.0.212  80:31444/TCP  22h

    container-registry  registry   LoadBalancer  10.152.183.207  192.168.0.213  5000:32000/TCP  22h

    admin  chrony-udp-svc  LoadBalancer  10.152.183.77  192.168.0.240  123:32658/UDP  40m

    admin  pgadmin-svc  LoadBalancer  10.152.183.201  192.168.0.241  5432:30954/TCP,80:30675/TCP,443:30676/TCP  19m

    Source Repository

    Inspiration:

    https://microk8s.io/docs/registry-built-in

    Eine Software-Registry wird benötigt, wenn man selbst entwickelte Anwendungen lokal speicher und verwenden möchte. Prinzipiell könnte man auch öffentliche Registrys nehmen, aber wir haben ja einen k8s-cluster.

    alfred@pc1:~$ microk8s enable registry:size=40Gi

    Addon storage is already enabled.

    Enabling the private registry

    Applying registry manifest

    namespace/container-registry created

    persistentvolumeclaim/registry-claim created

    deployment.apps/registry created

    service/registry created

    configmap/local-registry-hosting configured

    The registry is enabled

    The size of the persistent volume is 40Gi

    alfred@pc1:~$

    Nun ist die Registry vorhanden. Das Cluster-Setup ist wie folgt:

    alfred@pc1:~$ microk8s status

    microk8s is running

    high-availability: yes

    datastore master nodes: 192.168.0.202:19001 192.168.0.203:19001 192.168.0.204:19001

    datastore standby nodes: 192.168.0.201:19001 192.168.0.205:19001

    addons:

    enabled:

    dashboard  # The Kubernetes dashboard

    dns  # CoreDNS

    ha-clusalfred@pc1:~$ microk8s status

    microk8s is running

    high-availability: yes

    datastore master nodes: 192.168.0.202:19001 192.168.0.203:19001 192.168.0.204:19001

    datastore standby nodes: 192.168.0.201:19001 192.168.0.205:19001

    addons:

    enabled:

    dashboard  # The Kubernetes dashboard

    dns  # CoreDNS

    ha-cluster  # Configure high availability on the current node

    helm3  # Helm 3 - Kubernetes package manager

    ingress  # Ingress controller for external access

    metallb  # Loadbalancer for your Kubernetes cluster

    metrics-server  # K8s Metrics Server for API access to service metrics

    prometheus  # Prometheus operator for monitoring and logging

    rbac  # Role-Based Access Control for authorisation

    registry  # Private image registry exposed on localhost:5000

    storage  # Storage class; allocates storage from host directory

    disabled:

    helm  # Helm 2 - the package manager for Kubernetes

    host-access  # Allow Pods connecting to Host services smoothly

    linkerd  # Linkerd is a service mesh for Kubernetes and other frameworks

    portainer  # Portainer UI for your Kubernetes cluster

    traefik  # traefik Ingress controller for external access

    alfred@pc1:~$

    OEBPS/images/image0009.jpg

    Abbildung 7: Registry Clusterdisk

    Das Volume wurde als ClusterDisk angelegt. Die Storageclass longhorn ist als default eingerichtet.

    Das Skript zum Einrichten der Registry ist wie folgt:

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-23 21:37:19 +0100 (Di, 23. Nov 2021) $

    #  $Revision: 1285 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K13_registry.sh $

    #  $Id: K13_registry.sh 1285 2021-11-23 20:37:19Z alfred $

    #

    # Schnell-Installation microk8s - Installation praktischer AddOns

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    # Voraussetzung: Sauber installierte Nodes, Verbundener Cluster

    sname=$(basename $0)

    app=mikrok8s/install/${sname}

    pf=\$Revision:

    sf= \$

    fr=\$Revision: 1285 $

    revision=${fr#*$pf}

    revision=${revision%$sf*}

    xd=(`date '+%Y-%m-%d'`)

    wd=${HOME}/copy/${app}/${xd}/r${revision}

    id=/opt/cluster/${app}/${xd}/r${revision}

    rm -f -R ${wd}

    mkdir -p ${wd}

    #

    # Zu diesem Zeitpunkt sollte es eine Default-Storage-Class geben, wo das abgelegt wird.

    ansible pc1 -m shell -a 'microk8s enable registry:size=40Gi'

    ansible pc -m shell -a 'microk8s status --wait-ready'

    #

    # Adaptieren der Services

    #

    cat < ${wd}/do_registry.sh

    #!/bin/bash

    #

    #  \$Date: 2021-11-23 21:37:19 +0100 (Di, 23. Nov 2021) $

    #  \$Revision: 1285 $

    #  \$Author: alfred $

    #  \$HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K13_registry.sh $

    #  \$Id: K13_registry.sh 1285 2021-11-23 20:37:19Z alfred $

    #

    # Ändern des Services auf Loadbalancer

    #

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    # registry - 192.168.0.213

    microk8s kubectl -n container-registry get service registry -o yaml > ${id}/registry-svc.yaml

    sed 's/NodePort/LoadBalancer/' ${id}/registry-svc.yaml > ${id}/new-registry-svc.yaml

    microk8s kubectl apply -f ${id}/new-registry-svc.yaml --validate=false

    EOF

    #

    chmod 755 ${wd}/do_registry.sh

    ansible pc1 -m shell -a ${id}'/do_registry.sh ' > ${wd}'/do_registry.log'

    #

    cat < ${wd}/do_nodes.sh

    #!/bin/bash

    #

    #  \$Date: 2021-11-23 21:37:19 +0100 (Di, 23. Nov 2021) $

    #  \$Revision: 1285 $

    #  \$Author: alfred $

    #  \$HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K13_registry.sh $

    #  \$Id: K13_registry.sh 1285 2021-11-23 20:37:19Z alfred $

    #

    # Eintragen der Nodes in die hosts-Datei

    #

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    sudo sed --in-place '/docker.registry/d' /etc/hosts

    microk8s kubectl -n container-registry get service registry -o yaml > ${id}/nodes-registry-svc.yaml

    ip=\$(cat ${id}/nodes-registry-svc.yaml  | grep -i ip: | awk '{print \$3 }')

    text=\${ip}  docker.registry

    sudo sed -i $ a \${text} /etc/hosts

    #

    EOF

    #

    chmod 755 ${wd}/do_nodes.sh

    ansible pc -m shell -a ${id}'/do_nodes.sh '

    #

    # Und jetzt die Repository-Info

    #

    cat < ${wd}/do_docker.sh

    #!/bin/bash

    #

    #  \$Date: 2021-11-23 21:37:19 +0100 (Di, 23. Nov 2021) $

    #  \$Revision: 1285 $

    #  \$Author: alfred $

    #  \$HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K13_registry.sh $

    #  \$Id: K13_registry.sh 1285 2021-11-23 20:37:19Z alfred $

    #

    # Eintragen des Endpoints in die Docker-Registry

    #

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    #shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    FILENAME=/var/snap/microk8s/current/args/containerd-template.toml

    sudo sed --in-place '/docker.registry:5000/d' \${FILENAME}

    text='  [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.registry:5000]'

    echo  \${text} | tee -a \${FILENAME}

    text='  endpoint = [http://docker.registry:5000]'

    echo  \${text} | tee -a \${FILENAME}

    EOF

    #

    chmod 755 ${wd}/do_docker.sh

    ansible pc -m shell -a ${id}'/do_docker.sh '

    #

    # Und jetzt für den Docker selbst

    #

    cat < ${wd}/do_pull.sh

    #!/bin/bash

    #

    #  \$Date: 2021-11-23 21:37:19 +0100 (Di, 23. Nov 2021) $

    #  \$Revision: 1285 $

    #  \$Author: alfred $

    #  \$HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K13_registry.sh $

    #  \$Id: K13_registry.sh 1285 2021-11-23 20:37:19Z alfred $

    #

    # Konfiguration damit das docker-pull funktioniert

    #

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    #shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    sudo mkdir -p /etc/docker

    sudo rm -f /etc/docker/daemon.json

    tfile=\$(mktemp /tmp/daemon.XXXXXXXXX)

    sudo cat < \${tfile}

    {

    insecure-registries : [docker.registry:5000]

    }

    AllOver

    sudo cp -f \${tfile} /etc/docker/daemon.json

    sudo chmod 666 /etc/docker/daemon.json

    #

    EOF

    #

    chmod 755 ${wd}/do_pull.sh

    ansible pc -m shell -a ${id}'/do_pull.sh '

    ##

    ## Jetzt ist die Docker-Registry online und verfügbar

    ##

    Dieses Skript konfiguriert die Registry als LoadBalancer Service. Damit bekommt die Registry eine fixe IP-Adresse, die von aussen erreichbar ist. Somit können wir den Cluster ansprechen und sind nicht an einen bestimmten Node gebunden. Durch die Verwendung einer Clusterdisk (gesteuert durch Longhorn) ist diese Registry auch ausfallsicher. Der Service sieht dann so aus:

    alfred@pc1:~$ k -n container-registry get service

    NAME  TYPE  CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE

    registry  LoadBalancer  10.152.183.118  192.168.0.213  5000:5000/TCP  7h32m

    alfred@pc1:~$

    Das Skript trägt weiters die Registry in die Host-Dateien ein:

    alfred@pc1:~$ cat /etc/hosts

    192.168.0.201  pc1

    192.168.0.202  pc2

    192.168.0.203  pc3

    192.168.0.204  pc4

    192.168.0.205  pc5

    192.168.0.2  monitoring

    192.168.0.2  ntp

    127.0.0.1 localhost pc1

    # The following lines are desirable for IPv6 capable hosts

    ::1 ip6-localhost ip6-loopback

    fe00::0 ip6-localnet

    ff00::0 ip6-mcastprefix

    ff02::1 ip6-allnodes

    ff02::2 ip6-allrouters

    ff02::3 ip6-allhosts

    192.168.0.2 monitoring

    192.168.0.213  docker.registry

    alfred@pc1:~$

    Es wird auch der Eintrag für das unsafe Repository gemacht:

    alfred@pc1:~$ tail /var/snap/microk8s/current/args/containerd-template.toml

    [plugins.io.containerd.grpc.v1.cri.registry]

    # 'plugins.io.containerd.grpc.v1.cri.registry.mirrors' are namespace to mirror mapping for all namespaces.

    [plugins.io.containerd.grpc.v1.cri.registry.mirrors]

    [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io]

    endpoint = [https://registry-1.docker.io, ]

    [plugins.io.containerd.grpc.v1.cri.registry.mirrors.localhost:5000]

    endpoint = [http://localhost:5000]

    [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.registry:5000]

    endpoint = [http://docker.registry:5000]

    alfred@pc1:~$

    Somit ist das Repository im Cluster verfügbar.

    Verwalten des Sourcerepositorys

    Es gibt mehrere Befehle um die Daten im Sourcerepository zu beeinflußen.

    docker push ${docker_registry}/${image}:latest

    Dieser Befehle fügt ein Image in das Repository ein.

    curl ${docker_registry}/v2/${image}/tags/list

    Mit diesem Befehl kann man die bereits vorhandene tags-Liste von aussen eingesehen werden.

    Wenn man aber die Images die bereits im Kubernetes Cluster sind verwalten möchte, dann wird es ein bisschen schwieriger. Dazu habe ich folgende Skripten:

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-25 21:57:57 +0100 (Do, 25. Nov 2021) $

    #  $Revision: 1348 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/dev/registry_list.sh $

    #  $Id: registry_list.sh 1348 2021-11-25 20:57:57Z alfred $

    #

    # Manipulieren der microk8s.registry

    # https://gist.github.com/Kevinrob/4c7f1e5dbf6ce4e94d6ba2bfeff37aeb

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    #shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    docker_registry=docker.registry:5000

    repositories=$(curl -s ${docker_registry}/v2/_catalog)

    for repo in $(echo ${repositories} | jq -r '.repositories[]'); do

    echo $repo

    tags=$(curl -s http://${docker_registry}/v2/${repo}/tags/list | jq -r '.tags[]')

    for tag in $tags; do

    echo  $repo:$tag

    done

    done

    #

    Dieses Skript zeigt alle Images und deren Tags an, die in der Registry vorhanden sind.

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-25 21:57:57 +0100 (Do, 25. Nov 2021) $

    #  $Revision: 1348 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/dev/registry_delete.sh $

    #  $Id: registry_delete.sh 1348 2021-11-25 20:57:57Z alfred $

    #

    # Manipulieren der microk8s.registry

    # https://gist.github.com/Kevinrob/4c7f1e5dbf6ce4e94d6ba2bfeff37aeb

    #

    # webdefault:20211123-1301

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    #shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    docker_registry=docker.registry:5000

    # Prüfung ob gesetzt, sonst liefert die Shell hier eine Fehlermeldung

    string=${1}

    #echo ${string}

    prefix=:

    suffix=

    xrepo=${string%$prefix*}

    #echo ${xrepo}

    xtag=${string#$xrepo$prefix}

    #echo ${xtag}

    xtag=${xtag%$suffix*}

    #echo ${xtag}

    tags=$(curl -sSL http://${docker_registry}/v2/${xrepo}/tags/list | jq -r '.tags[]')

    for tag in $tags; do

    if [ ${tag} = ${xtag} ] ;

    then

    echo Lösche  $xrepo:$tag

    curl -v -k -X DELETE "http://${docker_registry}/v2/${xrepo}/manifests/$(

    curl -k -s -I \

    -H Accept: application/vnd.docker.distribution.manifest.v2+json \

    http://${docker_registry}/v2/${xrepo}/manifests/${xtag} \

    | awk '$1 == Docker-Content-Digest: { print $2 }' \

    | tr -d $'\r' \

    )"

    fi

    done

    #

    Dieses Skript löscht einen angegeben tag, wenn er gefunden wird.

    Ein typischer Löschprozess sieht dann so aus:

    alfred@bureau:~$ '/home/alfred/svn/trunk/k8s/dev/registry_list.sh'

    chrony

    chrony:latest

    chrony:20211123-1273

    chrony:20211123-1275

    hello-world

    hello-world:20211003

    pgmaster

    pgmaster:20211125-1327

    pgmaster:20211125-1337

    pgmaster:20211125-1340

    pgmaster:20211125-1339

    pgmaster:latest

    pgmaster:20211125-1345

    pgmaster:20211125-1343

    pgmaster:20211125-1334

    pgmaster:20211125-1336

    pgmaster:20211125-1341

    webdefault

    webdefault:20211123-1292

    webdefault:20211123-1293

    webserver

    webserver:20211124-1329

    webserver:20211124-1321

    webserver:20211124-1315

    webserver:20211124-1331

    webserver:20211124-1305

    webserver:20211125-1333

    webserver:20211124-1324

    webserver:latest

    webserver:20211125-1345

    webserver:20211124-1306

    webserver:20211124-1319

    webserver:20211123-1305

    webserver:20211124-1328

    webserver:20211124-1312

    webserver:20211124-1307

    webserver:20211124-1327

    webserver:20211125-1344

    webserver:20211124-1330

    webserver:20211124-1314

    webserver:20211124-1320

    webserver:20211124-1317

    webserver:20211124-1332

    alfred@bureau:~$ '/home/alfred/svn/trunk/k8s/dev/registry_delete.sh' webdefault:20211123-1293

    Lösche  webdefault:20211123-1293

    *  Trying 192.168.0.213:5000...

    * Connected to docker.registry (192.168.0.213) port 5000 (#0)

    > DELETE /v2/webdefault/manifests/sha256:ede78ca033eba1314667d5c6ced6a279833908d162ffe9103d7d1af42d53b6c7 HTTP/1.1

    > Host: docker.registry:5000

    > User-Agent: curl/7.74.0

    > Accept: */*

    >

    * Mark bundle as not supporting multiuse

    < HTTP/1.1 202 Accepted

    < Docker-Distribution-Api-Version: registry/2.0

    < X-Content-Type-Options: nosniff

    < Date: Thu, 25 Nov 2021 20:55:23 GMT

    < Content-Length: 0

    <

    * Connection #0 to host docker.registry left intact

    alfred@bureau:~$ '/home/alfred/svn/trunk/k8s/dev/registry_delete.sh' webdefault:20211123-1293

    alfred@bureau:~$

    Mit diesen beiden Skripts kann man sich die Images anzeigen lassen, und alte Images löschen.

    Zertifikate und LetsEncrypt

    Inspiration:

    https://suda.pl/5-minute-home-server-with/

    https://faun.pub/wildcard-k8s-4998173b16c8

    https://collabnix.github.io/kubetools/

    https://forum.netcup.de/netcup-intern/technik/11841-let-s-encrypt-wildcard-zertifikate-via-certbot/

    Um den Cluster vernünftig betreiben zu können braucht es Zertificate.

    Darum habe ich den Certificate-Manager installiert.

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-10-21 21:40:29 +0200 (Do, 21. Okt 2021) $

    #  $Revision: 659 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K5_certmanager.sh $

    #  $Id: K5_certmanager.sh 659 2021-10-21 19:40:29Z alfred $

    #

    # cert-manager

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    # Voraussetzung: Scripts in der richtigen Reihenfolge

    #

    # Definitionen für das Deployment

    #

    sname=$(basename $0)

    app=mikrok8s/install/${sname}

    pf=\$Revision:

    sf= \$

    fr=\$Revision: 659 $

    revision=${fr#*$pf}

    revision=${revision%$sf*}

    xd=(`date '+%Y-%m-%d'`)

    wd=${HOME}/copy/${app}/${xd}/r${revision}

    id=/opt/cluster/${app}/${xd}/r${revision}

    rm -f -R ${wd}

    mkdir -p ${wd}

    #

    cat < ${wd}/install_certmanager.sh

    #!/bin/bash

    #

    #  \$Date: 2021-10-21 21:40:29 +0200 (Do, 21. Okt 2021) $

    #  \$Revision: 659 $

    #  \$Author: alfred $

    #  \$HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K5_certmanager.sh $

    #  \$Id: K5_certmanager.sh 659 2021-10-21 19:40:29Z alfred $

    #

    # Installation des cert-managers mit helm

    #

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    # Voraussetzung: Scripts in der richtigen Reihenfolge

    microk8s kubectl create namespace cert-manager

    microk8s helm3 repo add jetstack https://charts.jetstack.io

    microk8s helm3 repo update

    microk8s helm3 install cert-manager jetstack/cert-manager \

    --namespace cert-manager --version v1.5.4 \

    --set installCRDs=true \

    --set ingressShim.defaultIssuerName=letsencrypt-production \

    --set ingressShim.defaultIssuerKind=ClusterIssuer \

    --set ingressShim.defaultIssuerGroup=cert-manager.io

    #

    #wget https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml --output-document=${id}/cert-manager.yaml

    #wget https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.crds.yaml --output-document=${id}/cert-manager.crds.yaml

    #microk8s kubectl apply -f ${id}/*.yaml

    #

    sleep 1m

    microk8s kubectl get pods --namespace cert-manager

    EOF

    chmod 755 ${wd}/install_certmanager.sh

    #

    ansible pc1 -m shell -a ${id}'/install_certmanager.sh'

    #

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-28 11:05:45 +0100 (So, 28. Nov 2021) $

    #  $Revision: 1404 $apiVersion: networking.k8s.io/v1

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s/K14_webserver.sh $

    #  $Id: K14_webserver.sh 1404 2021-11-28 10:05:45Z alfred $

    #

    # Einspielen der lokalen Konfigurationen - Produktiv ist slainte.

    # https://stackoverflow.com/questions/67430592/how-to-setup-letsencrypt-with-kubernetes-microk8s-using-default-ingress

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    #

    # Definitionen für das Deployment

    #

    sname=$(basename $0)

    app=mikrok8s/install/${sname}

    pf=\$Revision:

    sf= \$

    fr=\$Revision: 1404 $

    revision=${fr#*$pf}

    revision=${revision%$sf*}

    xd=(`date '+%Y-%m-%d'`)

    wd=${HOME}/copy/${app}/${xd}/r${revision}

    id=/opt/cluster/${app}/${xd}/r${revision}

    rm -f -R ${wd}

    mkdir -p ${wd}

    #

    cat < ${wd}/webserver-depl-svc.yaml

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: webserver-depl

    namespace: slainte

    spec:

    selector:

    matchLabels:

    app: webserver-app

    template:

    metadata:

    labels:

    app: webserver-app

    spec:

    containers:

    - name: webserver-app

    image: nginx:1.20

    ---

    apiVersion: v1

    kind: Service

    metadata:

    name: webserver-svc

    namespace: slainte

    spec:

    selector:

    app: webserver-app

    ports:

    - port: 80

    name: http

    targetPort: 80

    protocol: TCP

    - port: 443

    name: https

    targetPort: 443

    protocol: TCP

    EOF

    ansible pc1 -m shell -a 'microk8s kubectl apply -f '${id}'/webserver-depl-svc.yaml'

    cat < ${wd}/letsencrypt-staging.yaml

    apiVersion: cert-manager.io/v1

    kind: ClusterIssuer

    metadata:

    name: letsencrypt-staging

    spec:

    acme:

    #change to your email

    email: slainte@slainte.at

    server: https://acme-staging-v02.api.letsencrypt.org/directory

    privateKeySecretRef:

    name: letsencrypt-staging

    solvers:

    - http01:

    ingress:

    class: public

    EOF

    ansible pc1 -m shell -a 'microk8s kubectl apply -f '${id}'/letsencrypt-staging.yaml'

    cat < ${wd}/letsencrypt-prod.yaml

    apiVersion: cert-manager.io/v1

    kind: ClusterIssuer

    metadata:

    name: letsencrypt-prod

    spec:

    acme:

    server: https://acme-v02.api.letsencrypt.org/directory

    #change to your email

    email: slainte@slainte.at

    privateKeySecretRef:

    name: letsencrypt-prod

    solvers:

    - http01:

    ingress:

    class: public

    EOF

    ansible pc1 -m shell -a 'microk8s kubectl apply -f '${id}'/letsencrypt-prod.yaml'

    cat < ${wd}/ingress-routes-update.yaml

    apiVersion: networking.k8s.io/v1

    kind: Ingress

    metadata:

    name: webserver-routes

    namespace: slainte

    annotations:

    # Class checken mit kubectl -n ingress describe daemonset.apps/nginx-ingress-microk8s-controller

    kubernetes.io/ingress.class: public

    # Das ist für das Zertifikat

    cert-manager.io/cluster-issuer: letsencrypt-prod

    # Das ist für das http -> https forwarding

    # See https://kubernetes.github.io/ingress-nginx/examples/rewrite/

    nginx.ingress.kubernetes.io/rewrite-target: /\$1

    nginx.ingress.kubernetes.io/ssl-redirect: true

    nginx.ingress.kubernetes.io/force-ssl-redirect: true

    nginx.ingress.kubernetes.io/ssl-temporary-redirect: false

    nginx.ingress.kubernetes.io/secure-backends: true

    nginx.ingress.kubernetes.io/ssl-proxy-headers: X-Forwarded-Proto: https

    nginx.ingress.kubernetes.io/proxy-body-size: 0m

    nginx.ingress.kubernetes.io/proxy-buffering: off

    #  nginx.ingress.kubernetes.io/ssl-passthrough: true

    # https://github.com/nginxinc/kubernetes-ingress/tree/v1.12.0/examples/ssl-services

    #  nginx.ingress.kubernetes.io/ssl-services: \${image}-svc

    #  nginx.ingress.kubernetes.io/backend-protocol: HTTPS

    spec:

    tls:

    - hosts:

    - k8s.slainte.at

    secretName: k8s-slainte-at-tls

    rules:

    - host: k8s.slainte.at

    http:

    paths:

    - path: /(.*)

    pathType: Prefix

    backend:

    service:

    name: webserver-svc

    port:

    number: 80

    defaultBackend:

    service:

    name: webserver-svc

    port:

    number: 80

    EOF

    ansible pc1 -m shell -a 'microk8s kubectl apply -f '${id}'/ingress-routes-update.yaml '

    # Service PROD

    curl -k -v http://k8s.slainte.at

    #erreichbar sein.

    #Aber auch mit https

    curl -k -v https://k8s.slainte.at

    #

    ## Prüfen des Zertifikates

    ansible pc1 -m shell -a 'microk8s kubectl get certificate --all-namespaces'

    ansible pc1 -m shell -a 'microk8s kubectl describe certificate --all-namespaces'

    ansible pc1 -m shell -a 'microk8s kubectl get certificaterequests.cert-manager.io '

    ansible pc1 -m shell -a 'microk8s kubectl describe certificaterequests '

    ansible pc1 -m shell -a 'microk8s kubectl get certificatesigningrequests.certificates.k8s.io '

    ansible pc1 -m shell -a 'microk8s kubectl get Issuer'

    ansible pc1 -m shell -a 'microk8s kubectl get ClusterIssuer'

    ansible pc1 -m shell -a 'microk8s kubectl describe ClusterIssuer letsencrypt-prod '

    ansible pc1 -m shell -a 'microk8s kubectl get challenges.acme.cert-manager.io '

    ansible pc1 -m shell -a 'microk8s kubectl describe challenges.acme.cert-manager.io '

    ##

    exit

    Die Zertifikate entstehen dann, wenn sie gebraucht werden. Die Definition ist im  Ingress. Derzeit gibt es einen URL pro Namespace, und damit ein Zertifikat.

    Die Namespaces werden hier definiert.

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-23 18:03:25 +0100 (Di, 23. Nov 2021) $

    #  $Revision: 1272 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s_app/namespace/slainte_env.sh $

    #  $Id: slainte_env.sh 1272 2021-11-23 17:03:25Z alfred $

    #

    # Bauen und deployen

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    export secretName=k8s-slainte-at-tls

    export host=k8s.slainte.at

    export namespace_comment=Namespace für die Produktion

    export cluster_issuer=letsencrypt-prod

    export docker_registry=docker.registry:5000

    #

    Bzw.

    #!/bin/bash

    ############################################################################################

    #  $Date: 2021-11-23 18:03:25 +0100 (Di, 23. Nov 2021) $

    #  $Revision: 1272 $

    #  $Author: alfred $

    #  $HeadURL: https://monitoring.slainte.at/svn/slainte/trunk/k8s/k8s_app/namespace/default_env.sh $

    #  $Id: default_env.sh 1272 2021-11-23 17:03:25Z alfred $

    #

    # Bauen und deployen

    #

    ############################################################################################

    #shopt -o -s errexit  #—Terminates  the shell script  if a command returns an error code.

    shopt -o -s xtrace #—Displays each command before it’s executed.

    shopt -o -s nounset #-No Variables without definition

    export secretName=default-k8s-slainte-at-tls

    export host=default.k8s.slainte.at

    export namespace_comment=Namespace zum Testen

    # export cluster_issuer=letsencrypt-staging

    # Auch hier die Prod, wegen HTTP Strict Transport Security (HSTS)

    export cluster_issuer=letsencrypt-prod

    export docker_registry=docker.registry:5000

    #

    Das sieht dann im Ingress wie folgt aus:

    ---

    # Yaml für ${image}:${tag}

    apiVersion: networking.k8s.io/v1

    kind: Ingress

    metadata:

    name: ${image}-routes

    namespace: ${namespace}

    annotations:

    kubernetes.io/ingress.class: public

    cert-manager.io/cluster-issuer: ${cluster_issuer}

    # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

    nginx.ingress.kubernetes.io/rewrite-target: /$2

    nginx.ingress.kubernetes.io/ssl-redirect: true

    nginx.ingress.kubernetes.io/ssl-passthrough: true

    nginx.ingress.kubernetes.io/force-ssl-redirect: true

    nginx.ingress.kubernetes.io/ssl-temporary-redirect: false

    nginx.ingress.kubernetes.io/secure-backends: true

    nginx.ingress.kubernetes.io/ssl-proxy-headers: X-Forwarded-Proto: https

    nginx.ingress.kubernetes.io/proxy-body-size: 0m

    nginx.ingress.kubernetes.io/proxy-buffering: off

    # https://github.com/nginxinc/kubernetes-ingress/tree/v1.12.0/examples/ssl-services

    nginx.ingress.kubernetes.io/ssl-services: ${image}-svc

    nginx.ingress.kubernetes.io/backend-protocol: HTTPS

    spec:

    tls:

    - hosts:

    - ${host}

    secretName: ${secretName}

    rules:

    - host: ${host}

    http:

    paths: # https://github.com/google/re2/wiki/Syntax, https://www.regular-expressions.info/refcapture.html

    - path: /${image}(/|$)(.*)

    pathType: Prefix

    backend:

    service:

    name: ${image}-svc

    port:

    number: 443

    defaultBackend:

    service:

    name: default-svc

    port:

    number: 80

    ---

    Man könnte aber auch mit Wildcard-Zertifikaten arbeiten. Ist aber in unserem Falle ein wenig übertrieben. Nachdem es ja eh für jeden Namespace und jeden host  einen Ingress braucht, kann man dafür auch ein eigenes Zertifikat anlegen lassen.

    Entwicklungsumgebung

    Inspiration:

    https://pimylifeup.com/ubuntu-install-docker/

    https://brjapon.medium.com/setting-up-ubuntu-20-04-arm-64-under-raspberry-pi-4-970654d12696

    https://microk8s.io/docs/registry-built-in

    https://microk8s.io/docs/registry-private

    https://github.com/docker-library/hello-world

    https://www.freecodecamp.org/news/how-to-remove-images-in-docker/

    https://gobyexample.com/hello-world

    https://linuxconfig.org/how-to-install-go-on-ubuntu-20-04-focal-fossa-linux

    https://forums.docker.com/t/docker-private-registry-how-to-list-all-images/21136/2

    https://github.com/fraunhoferfokus/deckschrubber

    https://collabnix.github.io/kubetools/

    Um das Source-Repository nutzen zu können brauchen wir eine Entwicklungsumgebung. Dafür benutzen wir unseren Entwicklungs-Raspbery PI.

    OEBPS/images/image0010.jpg

    Abbildung 8: Gesamtsystem

    Dieser Entwicklungs-Raspberry ist ein Raspberry 4 mit 8GB RAM und einer 120 GB SDRAM Karte. Zusätzlich gibt es noch eine 1TB-USB-Platte für all die Backups.

    Auf diesem Rechner ist Docker installiert.

    alfred@monitoring:~$ docker version

    Client:

    Version:  20.10.7

    API version:  1.41

    Go version:  go1.13.8

    Git commit:  20.10.7-0ubuntu1~20.04.1

    Built:  Wed Aug  4 22:53:01 2021

    OS/Arch:  linux/arm64

    Context:  default

    Experimental:  true

    Server:

    Engine:

    Version:  20.10.7

    API version:  1.41 (minimum version 1.12)

    Go version:  go1.13.8

    Git

    Gefällt Ihnen die Vorschau?
    Seite 1 von 1