Читать книгу K8s Applications mit MicroK8S auf Raspberry PI - Alfred Sabitzer - Страница 8

Оглавление

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:~$

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 <<EOF > ${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 <<EOF > ${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 <<EOF > ${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 <<EOF > ${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 <<AllOver > \${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.

K8s Applications mit MicroK8S auf Raspberry PI

Подняться наверх