k3s - Eine schlanke, skalierende Containerplattform kompatibel zu Kubernetes

k3s

Die Containervirtualisierung verspricht, die Art und Weise zu revolutionieren, wie IT-Abteilungen in ihren Anwendungslandschaften arbeiten – in etwa so wie es die Virtualisierung vor einigen Jahren getan hat.
Nahezu sämtliche moderne Open-Source-Software wird in Containern verpackt zur Verfügung gestellt, mit dem Ziel, die Applikation transportabel und skalierbar zu machen. Applikationen, die in Container verpackt sind, erreichen eine deutlich höhere Packungsdichte und Skalierbarkeit als Applikationen in Virtuellen Maschinen (VMs). Container haben einen deutlich geringeren Overhead. Sie können in deutlich kürzerer Zeit deployed und gestartet werden als VMs.

Containervirtualisierung ist eine Technik, um mehrere Instanzen einer Applikation isoliert voneinander auf einem Hostsystem (Knoten) zu betreiben. Übersteigt der Ressourcenbedarf der Applikationscontainer die Grenze eines Knotens oder wird Hochverfügbarkeit der Applikation angestrebt, so müssen die Container auf einer Containerplattform betrieben werden.
Eine Containerplattform ist ein Verbund (Cluster) von einem bis „beliebig" vielen Knoten, auf dem containerbasierte Applikationen automatisiert bereitgestellt, skaliert und gemanaged werden.

Dadurch kann sich der Workload der Applikation(en) auf dem Cluster verteilen. Die Leistungsfähigkeit lässt sich bei Bedarf durch Hinzufügen von zusätzlichen Knoten und Containern erhöhen (horizontale Skalierbarkeit). Hochverfügbarkeit kann durch das redundante Starten von Containern oder durch das Regelwerk der Containerplattform erzielt werden. Die Plattform sorgt für das Einhalten der definierten Regeln, erzwingt beispielsweise, dass ein Container immer mindestens einmal im Cluster im Zustand „Running" ist.

Als Containerplattform hat sich in den letzten Jahren Kubernetes (k8s) als De-facto-Standard etabliert. Das Softwareunternehmen Rancher Labs beschäftigt sich damit, Kubernetes-Cluster möglichst einfach aufsetzten und verwalten zu können. Es hat unter anderem das Open-Source-Project k3s initiiert, das im Vergleich zu k8s sehr geringe Ressourcenanforderungen hat und neben der x86_64-Architektur auch ARMv7 und ARM64 unterstützt. k3s besteht aus einer Binärdatei, die kleiner als 40 MB ist, benötigt im Vergleich zu k8s nur etwa die Hälfte an RAM und ist voll kompatibel zu k8s. Das bedeutet, dass sich Applikationen – beschrieben durch einen Satz Kubernetes-YAML-Dateien – zwischen k3s und k8s übertragen lassen. k3s-Cluster bestehen aus mindestens einem Linuxsystem (Knoten) und können beliebig um weitere Knoten erweitert werden.

Die Herausforderungen in containerbasierten Applikationen liegen darin, die Daten persistent zu speichern, eine Netzwerkanbindung für die Außenwelt bereitzustellen, Hochverfügbarkeit zu erreichen und updatefähig zu sein.

Im Folgenden wird ein k3s-Cluster bestehend aus zwei Knoten aufgesetzt sowie der Kubernetes Packagemanager Helm darin installiert, mit dessen Hilfe sich komplette Applikationen auf das Cluster installieren lassen. Dabei ist der zweite Knoten optional. Das Beispiel funktioniert auch mit nur einem Clusterknoten.

Voraussetzungen

Ein k3s-Cluster besteht mindestens aus einem Server (k3s-Serverprozess) und kann optional um beliebig viele Agenten (k3s-Agentenprozesse) für die Skalierung erweitert werden. Server und Agent(en) werden jeweils auf dedizierte Linux-Systeme installiert, in diesem Beispiel Ubuntu Server 18.04.02 LTS. Das Beispiel-Cluster besteht aus zwei Knoten, wobei der zweite optional ist. Auf dem Ersten mit dem Hostnamen „k3s-server" wird der k3s-Server und auf dem Zweiten „k3s-agent" entsprechend der k3s-Agenten installiert. Der Server fungiert gleichzeitig auch als Agent. Die minimalen zusätzlichen Systemanforderungen für k3s an die Knoten sind 512 MB RAM für den k3s-Server, 75 MB RAM für den k3s-Agenten und 200 MB zusätzlicher Festplattenspeicher. Dazu kommen die Anforderungen des Betriebssystems und der Applikationen, die auf dem Cluster betrieben werden sollen. k3s ist für die Betriebssystem-Plattformen x86_64, ARMv7, ARM64 verfügbar und benötigt mindestens einen Linuxkernel 3.10. Die Server in diesem Beispiel wurden jeweils mit 2 GB RAM und 20 GB Festplattenkapazität ausgestattet.

Für die Netzwerkkommunikation zwischen den Clusterknoten müssen alle Knoten den TCP-Port 6443 des k3s-Servers erreichen können und in der Lage sein, sich jeweils untereinander über den UDP-Port 8472 erreichen zu können. Falls die Clusterknoten in einem öffentlichen Netzwerk wie z.B. einer Cloud betrieben werden, so sollte aus Sicherheitsgründen der Port 8472 durch eine Firewall bzw. Security Group so geschützt werden, dass dieser nur innerhalb des Clusters zwischen den Cluster-Knoten geöffnet ist. Für die Installation ist auf den Systemen Internetzugriff notwendig.

Installation des Servers  

Nach dem Verbinden mit „k3s-server" per ssh sind folgende Kommandos auszuführen:

ssh user@k3s-server

Entweder die aktuellste k3s-Version installieren ...

user@k3s-server:~$ curl -sfL https://get.k3s.io | sh -

… oder alternativ eine Vorgegebene:

user@k3s-server:~$ curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v0.5.0 sh -

Nun wird noch das Administrationskommando kubectl durch das Ausführen der folgenden Kommandos auf den Server gerichtet:

user@k3s-server:~$ sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
user@k3s-server:~$ sudo chown user:user ~/.kube/config

Die Installation des Servers ist nun abgeschlossen. kubectl ist das Administrationskommando mit dem z.B. die Knoten im Cluster und deren Status angezeigt werden können:

user@k3s-server:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-server Ready<none> 9m2s v1.14.1-k3s.4

Zugriff von einem Linux System außerhalb des Clusters einrichten (optional)  

Die Adminsitration des k3s-Clusters kann auch von einem beliebigen Linuxsystems außerhalb des Clusters erfolgen. Dazu muß kubctl heruntergeladen und entsprechend konfiguriert werden:

user@mydesktop:~$ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.14.1/bin/linux/amd64/kubectl
user@mydesktop:~$ chmod +x ./kubectl
user@mydesktop:~$ sudo mv ./kubectl /usr/local/bin/kubectl

Um mit kubectl auf das Cluster zugreifen zu können, muss die Datei /etc/rancher/k3s/k3s.yaml, die durch die Installation auf dem k3-Server erzeugt wurde, in ~/.kube/config auf dem Linuxsystem kopiert werden und der Eintrag 'localhost' gegen die IP-Adresse oder den Hostnamen des k3s-servers ausgetauscht werden. Nach dem Anpassen des Kommandos auf die Umgebung kann dazu dieses Kommando verwendet werden:

user@mydesktop:~$ sed -i "s#server: https://localhost:6443#server: https://k3s-server:6443#g" ~/.kube/config

Einbinden von weiteren Linuxsystemen als k3s-Agenten in das Cluster (optional) 

Das Cluster kann nun um zusätzliche Agenten (im Beispiel `k3s-agent`) erweitert werden. Der Agent authentifiziert sich über ein Token, das bei der Installation auf dem Server in /var/lib/rancher/k3s/server/node-token erzeugt wurde.

user@k3s-server:~$ sudo cat /var/lib/rancher/k3s/server/node-token
K10f2999e7296565f0f09a03a272c17aa8690072771d9b12aba2f6202d6bd42a922::node:744990a6ce604bbe07fdd242779c6d05

Mithilfe des Tokens wird nun der k3s-agent installiert und in das Cluster integriert. Dazu wird eine Verbindung per ssh mit dem System `k3s-agent` hergestellt:

ssh k3s-agent

Installation des k3s-Agenten und Ausrichtung auf den k3s-Server. Der Name des k3s-Servers und das Token sind entsprechend anzupassen:

user@k3s-agent:~$ curl -sfL https://get.k3s.io | K3S_URL=https://k3s-server:6443 K3S_TOKEN=K10f2999e7296565f0f09a03a272c17aa8690072771d9b12aba2f6202d6bd42a922::node:744990a6ce604bbe07fdd242779c6d05 sh -

Der neu hinzugefügte Agent sollte nun nach kurzer Zeit im Cluster angezeigt werden:

user@k3s-server:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-agent Ready
<none> 6m51s v1.14.1-k3s.4
k3s-server Ready<none> 11h v1.14.1-k3s.4

Sollte dies nicht der Fall sein, so können die Logs des Agenten-Prozesses (k3s-agent) Hinweise auf die Ursache der Störung geben:

user@k3s-agent:~$ tail -f /var/log/syslog | grep -i k3s-agent

k3s installiert dieContainer-Laufzeitumgebung containerd ohne das Docker-Laufzeitumgebung CLI auf den Knoten. Durch Austauschen des Kommandos docker gegen crictl kann man aber wie gewohnt arbeiten:

user@k3s-server:~$ sudo crictl ps

CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID
1c963937c704b 98768a8bf3fed 12 hours ago Running traefik 0 e6f5aa79b3cac
86cbbbe700f74 4a065d8dfa588 12 hours ago Running lb-port-443 0 675c65b9e57eb
2e20e3ff3ec42 4a065d8dfa588 12 hours ago Running lb-port-80 0 675c65b9e57eb
21b51a3291685 2ee68ed074c6e 12 hours ago Running coredns 0 f9020f641d6e1

Installation des Kubernetes-Packagemanagers Helm 

Helm ist ein Packagemanager für Kubernetes. Mit dessen Hilfe können Applikationen für ein Kubernetes-Cluster verpackt unddeployed werden. Außerdem steht ein öffentliches Repository mit bereits verpackten Applikationen zur Verfügung. Zunächst ist der Helm-Client mit diesen Kommandos zu installieren:

user@k3s-server:~$ curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > install-helm.sh
user@k3s-server:~$ chmod u+x install-helm.sh
user@k3s-server:~$ ./install-helm.sh

Im nächsten Schritt wird Helm mit dem Clusterverbunden: 

user@k3s-server:~$ kubectl -n kube-system create serviceaccount tiller
user@k3s-server:~$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
user@k3s-server:~$ helm init --service-account tiller --upgrade

Nun kann das Helm-Repository nach Applikationen durchsucht werden:

user@k3s-server:~$ helm search mysql
NAME CHART VERSIONAPP VERSIONDESCRIPTION
stable/mysql
1.2.0 5.7.14 Fast, reliable, scalable, and easy to use open-source rel...
stable/mysqldump 2.4.1 2.4.1 A Helm chart to help backup MySQL databases using mysqldump
stable/prometheus-mysql-exporter 0.3.2 v0.11.0 A Helm chart for prometheus mysql exporter with cloudsqlp...
stable/percona 1.1.0 5.7.17 free, fully compatible, enhanced, open source drop-in rep...
stable/percona-xtradb-cluster 1.0.0 5.7.19 free, fully compatible, enhanced, open source drop-in rep...
stable/phpmyadmin 2.2.4 4.9.0-1 phpMyAdmin is an mysql administration frontend
stable/gcloud-sqlproxy 0.6.1 1.11 DEPRECATED Google Cloud SQL Proxy
stable/mariadb 6.4.0 10.3.15 Fast, reliable, scalable, and easy to use open-source rel...

Fehlersuche

Weitere Informationen zur Fehlerbehebung können den Logdateien auf Server und Agent entnommen werden:

sudo tail -f /var/log/syslog | grep -i k3s
sudo tail -f /var/lib/rancher/k3s/agent/containerd/containerd.log

Die Installation von k3s erzeugt zusätzliche Dienste, die als Kubernetes-Pods (Verbund von Containern) in speziellen Namespaces laufen:

user@k3s-server:~$ kubectl get namespaces
NAME STATUS AGE
default Active 12h
kube-node-lease Active 12h
kube-public Active 12h
kube-system Active 12h

Die internen Dienste befinden sich im Namespace kube-system und können so angezeigt werden:

user@k3s-server:~$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-695688789-7ldkp 1/1 Running 0 12h
helm-install-traefik-bjhsj 0/1 Completed 0 12h
svclb-traefik-4b8hd 2/2 Running 0 59m
svclb-traefik-f8plt 2/2 Running 0 12h
traefik-55bd9646fc-lwtgf 1/1 Running 0 12h

Fazit

Im Beispiel wurde ein k3s-Cluster bestehend aus zwei Knoten aufgesetzt und der Kubernetes Packagemanager Helm darin installiert. Das Cluster lässt sich leicht um weitere Knoten erweitern und ist nun für das Deployment von Applikationen bereit. k3s ist sehr leicht und schnell aufgesetzt, voll kompatibel zu k8s (Kubernetes) und hat gegenüber k8s einen deutlich geringeren Ressourcenbedarf und unterstützt mehrere Betriebssystem-Architekturen. k3s ist momentan im Alpharelease-Stadium und noch nicht hochverfügbar (HA). Aus diesem Grund kann eine Applikation nicht hochverfügbar auf einem k3s-Cluster bereitgestellt werden. Das komplexere k8s kann hingegen so aufgesetzt werden, dass die Serverrolle redundant und somit HA ist.

Die Hauptarbeit steckt in der Verpackung der Applikation. Ist diese einmal entwickelt, kann sie sowohl auf k3s als auch auf k8s installiert werden. Somit ist es kein Problem mit k3s als Containerplattform zu starten und bei Bedarf auf ein k8s-Cluster zu wechseln.

Mit einer deutlich einfacheren Architektur und einem viel geringeren Ressourcenbedarf ist k3s für eine Vielzahl von Setups geeignet. Sie reichen von produktiven Clustern mit nur wenigen, am besten im Vorhinein bekannten Applikationen bis hin zu Clustern, die bis auf Edge-Geräte reichen. Desweiteren ist k3s eine geeignete Basis für vorintegrierte verteilte Systeme, die z.B. als Appliance ausgeliefert sowohl Clustermanagement als auch die Applikation mitbringen. Insgesamt ist zu erwarten, dass in k3s der Administrations- und Instandhaltungsaufwand deutlich geringer ist als in k8s, was für viele IT-Teams relevant sein wird. 

Der hierauf folgende Blog-Beitrag „Helm – Ein Packagemanager für Kubernetes" zeigt, wie sich mit Helm Applikationen auf dem Cluster installieren lassen.

Quellen 

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/