Kubernetes in Docker mit k3s
Von Rancher Labs stammt eine abgespeckte Version von Kubernetes mit dem Namen k3s. Kubernetes wird oft als k8s abgekürzt, so dass eine reduzierte Version passenderweise als k3s bezeichnet werden kann.
Das Ziel von k3s ist, eine Kubernetes Umgebung anbieten zu können, wenn begrenzte Resourcen in der Betriebsumgebung den Einsatz einer regulären Kubernetes Installation erschweren oder unmöglich machen.
Im Gegensatz zum vollen Kubernetes Stack benötigt k3s kein etcd als Datenspeicher, sondern setzt auf SQLite. Hier macht sich die Architektur von Kubernetes natürlich besonders bezahlt: Da lediglich der Kubernetes API Server auf die Persistenz zugreifen darf, merken alle weiteren Komponenten von der Umstellung nichts. Um weiteren Hauptspeicher zu sparen wurden auch viele Controller Manager entfernt, die in der Zielumgebung jedoch sowieso nicht sinnvoll zum Einsatz kommen würden.
Im folgenden schauen wir uns an, wie mit Docker und k3s ein Kubernetes Cluster als Docker Container aufgesetzt werden kann.
Das ist besonders praktisch, wenn es darum geht, Tests zu machen oder mit Kubernetes zu entwickeln.
So spart man sich Minikube oder einen Testcluster.
Übringens arbeitet man auch bei Kubernetes selbst daran, Docker als Umgebung nutzen zu können:
Das kind-Projekt (Kubernetes in Docker) verfolgt einen vergleichbaren Ansatz: https://kind.sigs.k8s.io/
Natürlich kann k3s auch ganz ohne Docker eingesetzt werden und ist sogar der Regelfall, denn k3s soll z.B. in Kombination mit Raspberry Pi und vergleichbaren Single Board Computer (SBC) gut verwendet werden können.
Mehr zu k3s gibt es auf der offiziellen Homepage: https://k3s.io/
Am einfachsten ist k3s in Docker mit docker-compose zu verwenden. Eine Konfiguration als docker-compose.yml ist im folgenden Code-Beispiel gezeigt.
version: '3'
services:
server:
image: rancher/k3s:v0.8.1
command: server --disable-agent
environment:
- K3S_CLUSTER_SECRET=somethingtotallyrandom
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
volumes:
- k3s-server:/var/lib/rancher/k3s
# get the kubeconfig file
- .:/output
ports:
- 6443:6443
node:
image: rancher/k3s:v0.8.1
tmpfs:
- /run
- /var/run
privileged: true
environment:
- K3S_URL=https://server:6443
- K3S_CLUSTER_SECRET=somethingtotallyrandom
ports:
- 31000-32000:31000-32000
worker:
image: rancher/k3s:v0.8.1
tmpfs:
- /run
- /var/run
privileged: true
environment:
- K3S_URL=https://server:6443
- K3S_CLUSTER_SECRET=somethingtotallyrandom
volumes:
k3s-server: {}
Das Setup unterscheidet zwischen master
, worker
und einer node
.
Die node
verfügt über Portmappings, so dass Kubernetes Services als NodePort
bereitgestellt werden können.
Der worker
hat diese nicht, so dass hier eine Skalierung auf mehrere Instanzen ohne Portkonflikte möglich ist.
Nachdem das k3s Setup durch ein docker-compose up
gestartet ist, wird der Kubernetes Cluster gebootet.
Zum Zugriff auf den API Server wird im aktuellen Verzeichsnis die Konfiguration für kubectl
als Datei kubeconfig.yaml
bereitgestellt.
Diese Datei wird durch den Schalter --kubeconfig
bei kubectl
aktivier, wie im folgenden Beispiel zu sehen.
k3s
Kubernetes Cluster in Docker$ kubectl --kubeconfig kubeconfig.yaml get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-b7464766c-zc8xw 1/1 Running 0 9m41s
kube-system helm-install-traefik-44v5r 0/1 Completed 0 9m41s
kube-system svclb-traefik-g6lch 2/2 Running 0 9m24s
kube-system traefik-5c79b789c5-tkpp4 1/1 Running 0 9m24s
Bei der Abfrage der Cluster Nodes im Docker basierten Kubernetes Setup sind die Worker Nodes zu sehen.
$ kubectl --kubeconfig kubeconfig.yaml get nodes
NAME STATUS ROLES AGE VERSION
5f24d45bc295 Ready worker 5m v1.14.6-k3s.1
be629ccaa40f Ready worker 5m v1.14.6-k3s.1
Wenn man von dem k3s Kubernetes den Component-Status abfragt, fällt direkt auf, dass hier keine etcd
Instanzen zu sehen sind.
Das erklärt sich daraus, dass k3s statt etcd
auf eine SQLite Datenbank setzt.
$ kubectl --kubeconfig kubeconfig.yaml get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
Zur Demonstration kann ein einfacher Pod dienen, zum Beispiel mit dem nginx Webserver. Damit später ein Service einfach erzeugt werden kann, bietet es sich an, direkt den Port 80 zu deklarieren.
$ kubectl --kubeconfig kubeconfig.yaml run --restart=Never nginx --port 80 --image nginx
pod/nginx created
Der erzeugte Pod kann direkt abgefragt werden.
$ kubectl --kubeconfig kubeconfig.yaml get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 24s
Um auf den Pod zuzugreifen wird als nächstes ein Service vom Typ NodePort
erzeugt, indem kubectl expose
verwendet wird.
Ein Zugriff ist dann direkt auf localhost
mit dem entsprechenden Port, der in der Service Liste abgerufen werden kann, möglich.
$ kubectl --kubeconfig kubeconfig.yaml expose pod/nginx --type=NodePort
service/nginx exposed
$ kubectl --kubeconfig kubeconfig.yaml get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 38m
nginx NodePort 10.43.26.158 <none> 80:31580/TCP 25m
$ curl http://localhost:31580
<!DOCTYPE html>
<html>
<head>
...
Möchte man den Demo Cluster skalieren, so kann dies ebenfalls durch docker-compose erfolgen, indem die Anzahl der Worker spezifiziert wird: --scale worker=3
Zu beachten gilt noch, dass k3s ein eigenes Volume deklariert, in dem die Konfigurationsdaten des Kubernetes Clusters gehalten werden. Möchte man diese löschen, z.B. um noch einmal mit einem sauberen Setup zu starten, muss das Volume gelöscht werden.
$ docker-compose down
$ docker volume ls -q -f "label=com.docker.compose.volume=k3s-server"
$ docker volume rm $(docker volume ls -q -f "label=com.docker.compose.volume=k3s-server")
Dies Setup mit k3s in Docker ist derzeit ein praktischer Weg, um ein schnelles, isoliertes Setup für Experimente zu ermöglichen. Sicherlich wird das anfangs erwähnte kind-Projekt von Kubernetes eine interessante Alternative.
Zu den Themen Kubernetes, Docker und Cloud Architektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.