Kubernetes (k8s) hat das Betreiben von Software in der Cloud revolutioniert. Anwendungen werden in Containern, wie Docker, bereitgestellt und Kubernetes führt sie performant auf mehreren Servern aus und sorgt bei Last automatisch für eine entsprechende Skalierung.
Will man Kubernetes produktiv einsetzen, sollte man die Dienste der großen Cloud-Anbieter (Google GKE, Amazon EKS, Microsoft AKS) nutzen, da der eigene Betrieb eines ausfallsicheren Kubernetes-Clusters viel Hardware, Wissen und Aufwand erfordert. Für den Einstieg bietet Kubernetes Minikube, das man auf seinem lokalen Rechner installieren kann. Will man jedoch einen Kubernetes-Cluster mit mehreren Rechner aufsetzen, dann sind günstige Raspberry Pis und das ressourcensparende k3s von Ranger eine gute Alternative.
Installation als Master-Node und Worker-Node
Also schnell den stärksten Raspberry Pi (mein Modell 1 funktionierte nicht, aber Modell 2-4 schon) schnappen und als K3s-Master-Node aufsetzen:
curl -sfL https://get.k3s.io | sh - kubectl --all-namespaces=true get all
Falls wir einen weiteren Raspberry Pi haben, können wir den als K3s-Worker-Node aufsetzen und mit dem Master verbinden. Dazu benötigen wir zunächst ein Master-Token:
cat /var/lib/rancher/k3s/server/node-token K104b.....::server:8089f.....
Auf den Worker-Nodes erfolgt die K3s-Installation auf gleiche Weise, wobei wir zunächst die URL der Master-Node und das Master-Token als Umgebungsvariable angeben:
export K3S_URL=https://merkur:6443 export K3S_TOKEN=K104b.....::server:8089f..... curl -sfL https://get.k3s.io | sh -
Wenn wir jetzt die Nodes auf dem Master abrufen, dann sollten alle auf Ready stehen. Das ist bei Verwendung unterschiedlicher K3s-Versionen übrigens nicht der Fall.
pi@merkur:~ $ kubectl get nodes NAME STATUS ROLES AGE VERSION uranus Ready <none> 33d v1.17.0+k3s.1 merkur Ready master 33d v1.17.0+k3s.1
Grundlegendes zu K3s
Wollen wir K3s neu starten, kann das mit einem der folgenden Befehle erfolgen:
sudo systemctl restart k3s sudo service k3s restart
Für das Deinstallieren von K3s gibt es entsprechende Uninstall-Skripte auf Master- und Worker-Nodes:
/usr/local/bin/k3s-uninstall.sh /usr/local/bin/k3s-agent-uninstall.sh
Falls wir Kubernetes von einem anderen Rechner steuern möchten, können wir folgendermaßen vorgehen:
- kubectl installieren (z.B. auf einem MAC):
brew install kubectl
- K3s-Konfiguration auf lokalen Rechner kopieren:
scp pi@merkur:/etc/rancher/k3s/k3s.yaml ~/.kube/config-merkur
- in der Konfigurationsdatei, die Adresse
127.0.0.1
mit der IP-Adresse des Masters ersetzen - bei kubectl-Aufrufe die Konfigurationsdatei angeben:
kubectl --kubeconfig ~/.kube/config-merkur get pods
- Übrigens: wenn wir die Konfigurationsdatei unter ~/.kube/config abspeichern, benötigen wir den kubeconfig-Parameter nicht
Sobald etwas nicht funktioniert, sollten wir uns die K3s-Meldungen im Log anschauen:
tail /var/log/syslog | grep -i k3s tail /var/lib/rancher/k3s/agent/containerd/containerd.log
K3s verwendet nicht die komplette Docker-Laufzeitumgebung, sondern nutzt die Container-Laufzeitumgebung containerd. Statt docker
benutzen wir den Befehl crictl
, um entsprechende Befehle auszuführen:
sudo crictl ps -all
Anwendung mit K3s ausführen – der schnelle Weg: kubectl run
Wollen wir eine Anwendung mit Kubernetes ausführen, können wir das auf zwei Arten machen:
- per kubectl run
- per Manifest-Datei
Der einfache und schnelle Weg geschieht mit: kubectl run
. Das angegebene Container-Image wird entsprechend den Parametern gestartet:
kubectl run tomcat-reps --image=arm32v7/tomcat --replicas=2 --port=8080 --expose=true
kubectl get all NAME READY STATUS RESTARTS AGE pod/tomcat-reps-74b5dd955f-8tz9l 1/1 Running 0 59s pod/tomcat-reps-74b5dd955f-l7zwx 1/1 Running 0 59s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/tomcat-reps ClusterIP 10.43.238.192 <none> 8080/TCP 59s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/tomcat-reps 2/2 2 2 59s NAME DESIRED CURRENT READY AGE replicaset.apps/tomcat-reps-74b5dd955f 2 2 2 59s
Durch den Befehl werden folgende Dinge ausgeführt:
- lädt ein Tomcat-Image (ARM) von Docker für Raspberry Pi (–image=arm32v7/tomcat)
- ein Deployment wird erstellt
- das Deployment sorgt für ein Replicaset
- das Replicaset startet zwei Pods (–replicas=2)
- bei den Pods wird Port 8080 exponiert (–port 8080)
- Service wird erstellt, der Anfrage an die Pods weiterreicht (–expose=true)
- Tomcat-Server ist aufrufbar:
curl 10.43.238.192:8080
Den Port des Services könnte man per zwischengeschalteten Nginx herausreichen. Eine einfachere Lösung bietet der Kubernetes-Befehl kubectl port-forward
, bei dem man die IP-Adresse der Netzwerk-Schnittstelle des Hosts angeben kann:
kubectl port-forward --address 192.168.178.102 service/tomcat-reps 8080
Anwendung mit K3s ausführen – der nachhaltige Weg mit Manifest-Dateien
Falls man Änderungen an dem Deployment vornehmen möchte, muss man bei dem Run-Befehl das bestehende Deployment löschen und wieder neuanlegen. Der bessere Weg ist die Erstellung von Manifest-Dateien, da vorgenommene Datei-Anpassungen von Kubernetes erkannt und entsprechend umgesetzt werden.
Dazu erstellen wir eine Manifest-Datei für das Deployment tomcat-manifest-dep.yaml
und eine Manifest-Datei für den Service tomcat-manifest-svc.yaml
. Sobald wir die beiden Konfigurationen auf Kubernetes angewendet haben, erhalten wir das gleich Ergebnis wie zuvor. Jetzt können wir jedoch einfach Anpassungen durchführen, indem wir beispielsweise die Anzahl der Pods erhöhen.
Datei für das Deployment: tomcat-manifest-dep.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-mani labels: app: tomcat-mani spec: replicas: 2 selector: matchLabels: app: tomcat-mani template: metadata: labels: app: tomcat-mani spec: containers: - name: tomcat-mani image: arm32v7/tomcat imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP
Datei für den Service: tomcat-mani-svc.yaml
apiVersion: v1 kind: Service metadata: name: tomcat-mani labels: app: tomcat-mani spec: type: ClusterIP ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: tomcat-mani
kubectl apply -f tomcat-mani-dep.yaml,tomcat-mani-svc.yaml kubectl rollout status deploy/tomcat-mani
Wie geht es weiter?
Zunächst einmal können wir die erstellten Deployments, Services, Replicasets und Pods löschen:
kubectl delete service/tomcat-reps kubectl delete deployment.apps/tomcat-reps kubectl delete service/tomcat-mani kubectl delete deployment.apps/tomcat-mani
Damit haben wir unseren kleinen K3s-Cluster wieder bereinigt und steht bereit für weitere Kubernetes-Übungen – es gibt noch viel zu lernen 🙂 . Das ist ein guter Zeitpunkt, mit dem hervorragenden Kubernetes-Tutorial anzufangen. Und falls mal dauerhaft Anwendungen installiert werden sollen, dann lohnt sich die Verwendung des Paketmanagers Helm.