Читать книгу 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.