Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 17.06.2026 · 10 min Lesezeit

k3s: Leichtgewichtiges Kubernetes für den eigenen Server einrichten

Wer Docker Compose beherrscht, ist bereit für k3s: Die schlanke Kubernetes-Distribution läuft auf einem einzelnen Linux-Server, braucht nur einen curl-Befehl zur Installation und bringt Traefik v3, ServiceLB und CoreDNS bereits mit – inklusive Portainer-Integration.

Moderne IT Anleitungsgrafik zu k3s Kubernetes auf eigenem Server mit Server, Terminal Fenster, Kubernetes Symbolen und S EDV News Wasserzeichen

Wer seine containerisierten Anwendungen bisher mit Docker Compose verwaltet, stößt früher oder später an Grenzen: kein automatisches Neustart-Management über Nodes hinweg, kein eingebauter Load Balancer, keine standardisierte Rollenverteilung. Der nächste logische Schritt heißt Kubernetes – aber der Installationsaufwand eines vollständigen Clusters schreckt viele Admins zu Recht ab. k3s schließt diese Lücke: Die zertifizierte, leichtgewichtige Kubernetes-Distribution von Rancher/SUSE (heute ein CNCF-Projekt) passt in ein einziges Binary unter 70 MB, ist in unter einer Minute installiert und bringt alle wesentlichen Komponenten bereits mit. Diese Anleitung zeigt dir, wie du k3s auf einem einzelnen Linux-Server einrichtest, ein erstes Deployment über den vorinstallierten Traefik-Ingress erreichbar machst und Portainer als vertraute Oberfläche anbindest.

Voraussetzungen

  1. Betriebssystem: Linux-Server oder VM – Ubuntu 22.04/24.04, Debian 11/12, RHEL/CentOS oder SUSE; Kernel 5.x empfohlen
  2. Hardware (Server-Node): Mindestens 2 CPU-Kerne und 2 GB RAM; SSD empfohlen, besonders auf ARM-Hardware
  3. Hardware (Agent-Node, optional): Mindestens 1 CPU-Kern und 512 MB RAM
  4. Speicherplatz: Mindestens 10 GB frei
  5. Zugriff: Root- oder sudo-Zugriff auf den Server
  6. Netzwerk: Internetverbindung für den initialen Download (~70 MB); Firewall-Ports TCP 6443, TCP 80+443 und bei Multi-Node UDP 8472 müssen offen sein
  7. Hostname: Eindeutiger Hostname pro Node – bei VM-Klonen unbedingt vorher prüfen
  8. Vorkenntnisse: Docker-Compose-Erfahrung hilfreich; grundlegende Linux-Kenntnisse (SSH, sudo, Texteditor) erforderlich

k3s im Überblick: Was bekommst du?

Bevor du losliegst, lohnt ein kurzer Blick auf den Unterschied zwischen k3s und einem vollständigen Kubernetes-Cluster sowie auf die mitgelieferten Komponenten.

Merkmalk3sStandard-Kubernetes
Installationsgröße< 70 MB (1 Binary)Mehrere GB, viele Komponenten
RAM (Server-Node)ab 2 GBab 4–8 GB empfohlen
Installationsaufwand1 Befehl, < 1 MinuteStunden (kubeadm/Ansible)
ZertifizierungCNCF-zertifiziertCNCF-Referenz
IngressTraefik v3 (vorinstalliert)Keiner (manuell installieren)
LoadBalancerServiceLB/Klipper (eingebettet)Nur in Cloud-Umgebungen
DatenbankSQLite (Single) / etcd (HA)etcd (extern oder eingebettet)
ARM-UnterstützungJa (armhf, arm64, x86_64)Eingeschränkt
ZielplattformEdge, IoT, Homeserver, CI/CDGroße Cluster, Enterprise

k3s ist kein abgespeckter Kubernetes-Ersatz – es ist vollständig API-konform. Alle Standard-Kubernetes-Manifeste, kubectl und Helm funktionieren ohne Anpassungen. Was k3s weglässt, sind selten benötigte Alphafeatures und cloudspezifische Treiber, die in Bare-Metal- und Homelab-Umgebungen ohnehin nichts bringen.

Schritt 1: k3s installieren

Die Installation erfolgt über das offizielle Installationsskript. Führe den folgenden Befehl als root oder mit sudo auf dem Server aus:

curl -sfL https://get.k3s.io | sh -

Das Skript lädt das k3s-Binary herunter, richtet einen systemd-Service ein und startet den Cluster sofort. Die gesamte Installation dauert je nach Verbindungsgeschwindigkeit unter einer Minute.

Überprüfe danach den Status des Dienstes und ob der Node bereit ist:

sudo systemctl status k3s
sudo kubectl get nodes
sudo kubectl get pods -A

Verifizieren: sudo kubectl get nodes zeigt deinen Server mit Status Ready. sudo kubectl get pods -A listet unter anderem Pods für traefik, coredns und metrics-server im Namespace kube-system auf – alle im Status Running.

Schritt 2: kubeconfig für normale Benutzer einrichten

Die kubeconfig liegt standardmäßig unter /etc/rancher/k3s/k3s.yaml und ist nur für root lesbar. Um kubectl als normaler Benutzer zu verwenden, kopiere die Datei in dein Home-Verzeichnis:

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
export KUBECONFIG=~/.kube/config

Damit die Umgebungsvariable dauerhaft gilt, trage sie in deine ~/.bashrc oder ~/.profile ein:

echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
source ~/.bashrc

Alternativ kannst du in der k3s-Konfigurationsdatei write-kubeconfig-mode: "0644" setzen – dann ist /etc/rancher/k3s/k3s.yaml direkt für alle Benutzer lesbar (nur sinnvoll auf Systemen mit kontrolliertem Benutzerzugriff).

Verifizieren: kubectl get nodes (ohne sudo) gibt dieselbe Ausgabe wie zuvor – der Node ist Ready.

Schritt 3: Optionale Konfigurationsdatei anlegen

Für typische Anpassungen – etwa das Hinterlegen einer externen IP oder Domain für das TLS-Zertifikat des API-Servers – verwendest du die Konfigurationsdatei /etc/rancher/k3s/config.yaml. Diese Datei muss vor der Installation vorhanden sein oder k3s muss danach neu gestartet werden.

sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/config.yaml <<'EOF'
tls-san:
  - "DEINE-EXTERNE-IP-ODER-DOMAIN"
write-kubeconfig-mode: "0644"
EOF

Nach einer Änderung an config.yaml musst du k3s neu starten:

sudo systemctl restart k3s

Möchtest du ServiceLB (den eingebauten Load Balancer) oder andere Komponenten nicht nutzen – etwa weil du MetalLB oder einen externen Load Balancer einsetzt – deaktivierst du sie ebenfalls hier:

# /etc/rancher/k3s/config.yaml
tls-san:
  - "192.168.1.100"
  - "k3s.example.com"
write-kubeconfig-mode: "0644"
disable:
  - servicelb

Schritt 4: Erstes Deployment mit Traefik-Ingress

k3s bringt Traefik v3 als Ingress-Controller vorinstalliert mit. Du erstellst jetzt ein einfaches Test-Deployment mit dem traefik/whoami-Image, das auf HTTP-Anfragen mit Informationen zur Anfrage antwortet. Lege eine Datei whoami-demo.yaml an:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: traefik/whoami:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "50m"
            memory: "32Mi"
          limits:
            cpu: "200m"
            memory: "64Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
spec:
  selector:
    app: whoami
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: whoami
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
  - host: whoami.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: whoami
            port:
              number: 80

Ersetze whoami.example.com durch eine Domain oder einen Hostnamen, der auf die IP deines Servers zeigt. Wende das Manifest an:

kubectl apply -f whoami-demo.yaml

Verifizieren: Nach kurzer Zeit (der Image-Pull kann eine Minute dauern) zeigt kubectl get pods den whoami-Pod im Status Running. Ein curl -H "Host: whoami.example.com" http://<SERVER-IP>/ liefert eine Textantwort mit Request-Headern und Hostname zurück.

Schritt 5: Traefik anpassen

Ein häufiger Stolperstein: Die Datei /var/lib/rancher/k3s/server/manifests/traefik.yaml wird bei jedem k3s-Start automatisch überschrieben. Direktes Editieren dieser Datei hat deshalb keinen dauerhaften Effekt. Anpassungen nimmst du stattdessen über eine HelmChartConfig-Ressource vor, die k3s im selben Auto-Deploy-Verzeichnis erkennt:

sudo tee /var/lib/rancher/k3s/server/manifests/traefik-config.yaml <<'EOF'
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    dashboard:
      enabled: true
    logs:
      general:
        level: INFO
EOF

k3s erkennt diese Datei automatisch und wendet die Helm-Values auf die Traefik-Installation an. Möchtest du stattdessen einen anderen Ingress-Controller wie Nginx oder Caddy verwenden, deaktiviere Traefik vollständig über disable: [traefik] in config.yaml.

Schritt 6: Portainer als Management-Oberfläche anbinden

Wer Portainer aus der Docker-Welt kennt, kann es auch für den k3s-Cluster nutzen. Es gibt zwei Wege:

Weg A: Portainer Agent per kubectl deployen (empfohlen)

Wende das offizielle Portainer-Agent-Manifest auf deinem Cluster an:

kubectl apply -f https://downloads.portainer.io/ce2-21/portainer-agent-k8s-nodeport.yaml

Der Agent läuft als DaemonSet und ist über NodePort 30778 erreichbar. In deiner Portainer-Instanz gehst du zu Environments > Add Environment > Kubernetes > Agent und trägst https://<SERVER-IP>:30778 als Endpoint ein.

Weg B: kubeconfig importieren

Alternativ lädst du die Datei /etc/rancher/k3s/k3s.yaml in Portainer unter Environments > Add > Kubernetes > Import from kubeconfig hoch. Achte darauf, dass die IP-Adresse im server-Feld der kubeconfig von außen erreichbar ist – standardmäßig steht dort 127.0.0.1, was du durch die tatsächliche Server-IP ersetzen musst.

Verifizieren: In Portainer erscheint der k3s-Cluster unter Environments mit Status „Up" und zeigt die Anzahl der laufenden Pods und Nodes an.

Schritt 7 (optional): Agent-Node hinzufügen

k3s skaliert bei Bedarf auf mehrere Nodes. Um einen weiteren Linux-Server als Worker (Agent-Node) hinzuzufügen, benötigst du den Node-Token vom Server:

# Auf dem Server-Node ausführen:
sudo cat /var/lib/rancher/k3s/server/node-token

Auf dem Agent-Node führst du dann aus (ersetze Platzhalter durch tatsächliche Werte):

curl -sfL https://get.k3s.io | K3S_URL=https://<SERVER-IP>:6443 K3S_TOKEN=<NODE_TOKEN> sh -

Hinweis zur Firewall: TCP-Port 6443 muss vom Agent-Node zum Server erreichbar sein. Bei Multi-Node-Betrieb mit Flannel-VXLAN zusätzlich UDP-Port 8472 freigeben.

Verifizieren: kubectl get nodes auf dem Server zeigt beide Nodes mit Status Ready.

Firewall-Ports im Überblick

ProtokollPortRichtungZweck
TCP6443eingehendKubernetes API Server
UDP8472eingehendFlannel VXLAN (Multi-Node)
UDP51820eingehendFlannel WireGuard IPv4
TCP10250eingehendKubelet-Metriken
TCP2379–2380eingehendetcd HA (nur Server-Nodes)
TCP80, 443eingehendTraefik Ingress (HTTP/HTTPS)
TCP30000–32767eingehendNodePort-Services (optional)

Troubleshooting / Typische Fehler

kubectl schlägt mit „permission denied" fehl

/etc/rancher/k3s/k3s.yaml ist standardmäßig nur für root lesbar. Lösung: kubeconfig in das Home-Verzeichnis kopieren und Eigentümer anpassen (siehe Schritt 2) oder write-kubeconfig-mode: "0644" in config.yaml setzen.

Agent-Node kann sich nicht verbinden

Häufigste Ursache: Port 6443 ist durch UFW oder firewalld blockiert. Prüfe und öffne den Port:

# UFW
sudo ufw allow 6443/tcp
# firewalld
sudo firewall-cmd --add-port=6443/tcp --permanent && sudo firewall-cmd --reload

Traefik-Anpassungen werden nicht übernommen

Die Datei traefik.yaml im Auto-Deploy-Verzeichnis wird bei jedem Start überschrieben. Immer eine separate HelmChartConfig-Datei (z. B. traefik-config.yaml) verwenden – niemals traefik.yaml direkt editieren.

Nodes haben denselben Namen / Konflikte bei VM-Klonen

Jeder Node benötigt einen eindeutigen Hostnamen. Bei geklonten VMs: Hostname vor der k3s-Installation ändern (hostnamectl set-hostname NEUER-NAME) oder die Umgebungsvariable K3S_NODE_NAME beim Installationsaufruf setzen.

k3s startet auf Raspberry Pi nicht korrekt

Auf Raspberry Pi OS müssen cgroups in /boot/cmdline.txt aktiviert sein. Füge folgende Parameter in die bestehende Zeile ein (kein Zeilenumbruch):

cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

Danach Neustart und erneut installieren.

ServiceLB kollidiert mit MetalLB oder Cloud-LoadBalancer

Wer MetalLB oder einen externen Load Balancer betreibt, muss ServiceLB deaktivieren. In /etc/rancher/k3s/config.yaml:

disable:
  - servicelb

SQLite im HA-Betrieb verwenden

SQLite ist ausschließlich für Single-Node-Deployments geeignet. Für Hochverfügbarkeit (mindestens 3 Server-Nodes) muss beim ersten Server-Node das Flag --cluster-init gesetzt werden – alle weiteren Server-Nodes verbinden sich dann über etcd. Nachträglich von SQLite auf etcd wechseln ist nicht möglich, erfordert also eine Neuinstallation.

Häufige Fragen

Brauche ich Docker, um k3s zu betreiben?

Nein. k3s verwendet standardmäßig containerd als Container-Runtime – Docker ist weder erforderlich noch installiert. Containerd ist für nahezu alle Anwendungsfälle vollkommen ausreichend. Docker-Unterstützung lässt sich über das --docker-Flag aktivieren, ist aber nicht empfohlen.

Kann ich meine Docker-Compose-Dateien direkt in k3s nutzen?

Nicht direkt. Kubernetes verwendet eigene Manifest-Formate (Deployment, Service, Ingress). Das Tool Kompose (kompose.io) kann docker-compose.yml-Dateien in Kubernetes-Manifeste umwandeln. Als Einstieg empfiehlt sich das manuelle Umschreiben, um die Konzepte wirklich zu verstehen.

Was ist der Unterschied zwischen k3s, k3d und minikube?

k3d führt k3s in Docker-Containern aus – ausschließlich für lokale Entwicklung und CI gedacht. minikube ist ebenfalls ein lokales Entwicklungstool. k3s hingegen ist eine vollwertige, produktionstaugliche Distribution, die direkt auf einem Linux-Server (Bare Metal oder VM) läuft. Für den eigenen Server oder KMU-Betrieb ist k3s die richtige Wahl.

Wie aktualisiere ich k3s?

Das Installationsskript kann erneut mit einer Zielversion ausgeführt werden:

curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.32.2+k3s1 sh -

Für automatische Updates in Clustern empfiehlt Rancher den System Upgrade Controller.

Ist k3s für den produktiven Betrieb geeignet?

Ja. k3s ist CNCF-zertifiziert und wird von Rancher/SUSE aktiv weiterentwickelt. Es wird in zahlreichen produktiven Edge-, IoT- und On-Premises-Umgebungen eingesetzt. Die SQLite-Datenbank eignet sich nur für Single-Node; für produktive Multi-Node-Szenarien wird HA mit eingebettetem etcd (mindestens 3 Server-Nodes) empfohlen.

Was passiert mit meinen Daten bei einem Node-Ausfall?

Der eingebaute Local-Path-Provisioner speichert PersistentVolumes unter /var/lib/rancher/k3s/storage lokal auf dem Node. Bei einem Node-Ausfall sind diese Daten nicht automatisch verfügbar. Für produktive Daten empfiehlt sich ein verteilter Speicher wie Longhorn (von Rancher, ebenfalls per Helm installierbar) oder NFS.

Fazit

k3s ist der ehrlichste Weg von Docker Compose zu Kubernetes: kein aufgeblähter Installationsprozess, keine externen Abhängigkeiten, volle API-Kompatibilität. Wer einen einzelnen Linux-Server oder eine kleine VM-Gruppe betreibt, bekommt mit k3s einen vollwertigen Cluster, der sich mit denselben Tools und Manifesten bedienen lässt wie jeder andere Kubernetes-Cluster. Traefik v3 als Ingress-Controller und ServiceLB als Cloud-freier Load Balancer decken die gängigsten Anwendungsfälle ab, ohne dass du zusätzliche Komponenten installieren und konfigurieren musst. Der wichtigste Trade-off: Du verlässt das vertraute Docker-Compose-Ökosystem und musst Kubernetes-Konzepte (Deployments, Services, Ingress, PersistentVolumeClaims) aktiv erlernen – was sich aber mittelfristig auszahlt, sobald du mehrere Services verwaltest oder Hochverfügbarkeit brauchst. Für KMU-Admins und ambitionierte Selfhoster, die den nächsten Schritt in der Container-Orchestrierung gehen wollen, gibt es kaum einen niedrigschwelligeren Einstieg als k3s.

Weiterführende Anleitungen und Quellen

  1. Docker Compose: Multi-Container-Stacks aufbauen – die Grundlage vor k3s
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS – Traefik-Konzepte, die auch in k3s gelten
  3. Portainer installieren: Schritt-für-Schritt-Anleitung – Portainer als Management-Oberfläche einrichten
  4. Docker-Images auf Schwachstellen scannen mit Trivy – Container-Sicherheit für den k3s-Cluster
  5. k3s Quick-Start Guide (offizielle Dokumentation)
  6. k3s Systemanforderungen (offizielle Dokumentation)
  7. Portainer Agent auf Kubernetes installieren (offizielle Dokumentation)