Skip to content

Erster Cluster

Eine detaillierte Erläuterung der Konfigurationsdatei cluster.lok8s.yaml.

Voraussetzungen

  • lok8s CLI installiert
  • Ein Hetzner Cloud-Konto mit einem API-Token
  • Ein SSH-Schlüsselpaar (Ed25519 empfohlen)
  • Eine Domain, die dir gehört: API-Endpunkt und Zertifikatsnamen leiten sich daraus ab (als spec.cluster.domain; example.com unten ist ein Platzhalter)

Vollständige Konfigurationsreferenz

Vollständige cluster.lok8s.yaml anzeigen
yaml
# clusters/example.com/cluster.lok8s.yaml
apiVersion: cluster.lok8s.dev/v1beta1
kind: KubeOne
metadata:
  name: my-cluster
spec:
  kubernetes:
    version: "v1.35.5"
  cluster:
    # PFLICHT: eine Domain, die dir gehört; für Ingress und Zertifikate
    domain: example.com
    # Standard-Namespace für Workloads
    namespace: default
  provider:
    name: hetzner
    # Die Maschinen, in Hetzners eigenen Begriffen. Jeder `server`-Eintrag wird
    # zu einem `hcloud server create`; seine Schlüssel sind hcloud-Flags. Lege
    # denselben Inhalt in eine eigene Datei und zeige mit `configRef: hetzner.json`
    # darauf, wenn du eine kürzere Spec bevorzugst.
    config:
      cluster_name: my-cluster
      sshUser: root
      sshPrivateKey: ~/.ssh/id_ed25519
      sshPublicKey: ~/.ssh/id_ed25519.pub
      ssh-key:
        - name: my-cluster
          public-key-from-file: ~/.ssh/id_ed25519.pub
      network:
        - name: my-cluster
          # Bereich des privaten Netzwerks
          ip-range: 10.0.0.0/16
          "#subnets":
            - network-zone: eu-central
              type: cloud
              ip-range: 10.0.0.0/24
      server:
        # 3 Control Planes für HA; 1 reicht für Dev
        - name: cp-1
          type: cx33
          image: ubuntu-24.04
          # fsn1, nbg1 oder hel1
          location: fsn1
          ssh-key: [0]
          network: 0
          label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
        - name: cp-2
          type: cx33
          image: ubuntu-24.04
          location: fsn1
          ssh-key: [0]
          network: 0
          label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
        - name: cp-3
          type: cx33
          image: ubuntu-24.04
          location: fsn1
          ssh-key: [0]
          network: 0
          label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
        - name: worker-1
          type: cpx31
          image: ubuntu-24.04
          location: fsn1
          ssh-key: [0]
          network: 0
          label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=worker
        - name: worker-2
          type: cpx31
          image: ubuntu-24.04
          location: fsn1
          ssh-key: [0]
          network: 0
          label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=worker
  # Cluster-Infra-Addons, in Reihenfolge angewendet
  bootstrap:
    # CNI (Standard, wenn weggelassen)
    - cilium
    # Hetzner cloud-controller-manager
    - ccm
    - cert-manager
    - monitoring
  kubehz:
    # self (du betreibst alles) | hosted (kubehz betreibt die Control Plane)
    # | shared (ein Space auf einer geteilten Control Plane, kind: Kubehz)
    hosting: self
    # none | registered | managed (Supporter+)
    access: registered
    # cronjob (schreibgeschützter Heartbeat) | operator (Managed-Stufe, Live-Ansicht)
    agent: cronjob
    apiUrl: https://api.kubehz.cloud

Wichtige Abschnitte

spec.kubernetes

Legt die Kubernetes-Version fest. kubehz bietet eine kuratierte Liste an, jede Version auf einen Patch-Release gepinnt: heute v1.34.8 und v1.35.5 (die Voreinstellung). Eine Version wird zurückgezogen, sobald Upstream ihre Minor-Version nicht mehr patcht.

spec.provider

Wer die Maschinen stellt. name: hetzner wählt Hetzner Cloud, den einzigen implementierten Provider. config (oder configRef, ein Pfad zu einer JSON- oder YAML-Datei neben der Spec) ist der Provider-Deskriptor: der SSH-Zugang, den lok8s nutzt (sshUser, sshPrivateKey, sshPublicKey), und je eine Liste pro Hetzner-Ressource (ssh-key, network, server sowie optional volume und load-balancer). Jeder Eintrag wird zu einem hcloud <resource> create, und seine Schlüssel sind die Flags dieses Befehls. ssh-key: [0] und network: 0 an einem Server verweisen per Index auf Einträge dieser Listen.

Das Label lok8s.dev/role entscheidet, was ein Server wird: control-plane oder worker. Drei Control Planes geben dir HA; eine reicht für die Entwicklung. type ist ein Hetzner-Servertyp, location das Rechenzentrum.

Bare Metal. Ein Hetzner Dedicated Server kommt als #cloud.root-Eintrag in denselben Deskriptor (ein Robot-Server, den lok8s neu installiert und aufnimmt). Die Form steht in der lok8s-Provider-Referenz.

Veraltete Form. Ältere Specs trugen spec.ssh, spec.controlPlane und spec.workers. lok8s liest sie weiterhin als Fallback, in neuen Specs sollten sie aber nicht mehr vorkommen: SSH-Zugang und Node-Topologie gehören dem Provider-Deskriptor.

spec.bootstrap

Eine geordnete Liste von Cluster-Infra-Addons (CNI, CCM, cert-manager, Monitoring, …), die beim Provisionieren angewendet werden, bevor Workloads landen. Jeder Eintrag wird angewendet und abgewartet, bevor der nächste folgt. Blanke Namen lösen zu lok8s-Framework-Addons auf; ./pfad-Einträge zeigen auf deine eigenen Kustomize-Verzeichnisse. Wenn weggelassen, ist der Standard cilium: Jeder Cluster braucht ein CNI. Die vollständige Liste steht im lok8s-Addons-Guide.

spec.kubehz

Optionale Integration der kubehz-Plattform. hosting sagt, wer die Control Plane betreibt: self (du, auf deinem eigenen Konto), hosted (kubehz, siehe Gehostet) oder shared (ein Space auf einer Control Plane, die kubehz zwischen Kunden teilt; dieser Wert braucht kind: Kubehz). access sagt, was kubehz sieht: none, registered (schreibgeschützter Zustand) oder managed (ergänzt die Verwaltungsfunktionen: Healing-Richtlinien, Kapazitäts-Überwachung, Verwaltung des gewünschten Zustands; erfordert ein Supporter-Abo oder höher). Das Ausführen ist Pull-basiert: Der clusterinterne Agent holt den gewünschten Zustand von der Plattform ab und wendet ihn mit den eigenen Zugangsdaten deines Clusters an; kubehz hält niemals eingehenden Zugriff.

Die übrigen Schlüssel sind optional:

SchlüsselBedeutung
agentWelcher clusterinterne Agent den Heartbeat besitzt: cronjob (der schreibgeschützte Standard) oder operator (die Live-Ansicht der Managed-Stufe).
apiUrlDie kubehz-API, nur HTTPS. Pflicht, sobald access nicht none ist, sowie für hosted und shared.
connectHcloudTokentrue übergibt der Plattform bei der Registrierung deinen HCLOUD_TOKEN, ausschließlich über HTTPS, damit ein gehosteter Cluster Worker-Pools bereitstellen kann. Standardmäßig aus.
upgradeschannel: none / patch / minor (wie weit die Plattform ungefragt aktualisieren darf, Standard patch) und defer: window / immediate.
maintenanceWindowWann plattformgesteuerte Arbeiten laufen dürfen: daysOfWeek, startTime, durationMinutes, timezone und exclusions (Daten oder Zeiträume, die alles einfrieren).
spaceNur bei hosting: shared: der slug des Space, sein Anzeige-name und die nodes, für die beim Provisionieren Join-Tickets ausgestellt werden.

Siehe Wie es funktioniert für das vollständige Modell und die Vertrauensgrenze sowie Registrierung, um die Sichtbarkeit zu aktivieren.

Datei speichern

lo hält unter clusters/ einen Ordner pro Cluster, benannt nach der Domain, und liest cluster.lok8s.yaml von dort. Lege den Ordner an, speichere die Datei und markiere die Domain dann als aktiv:

bash
mkdir -p clusters/example.com
# füge die obige Referenz in clusters/example.com/cluster.lok8s.yaml ein
lo use example.com

lo use schreibt die aktive Domain nach clusters/.active; --domain <domain> oder DOMAIN_NAME überschreiben sie für einen einzelnen Befehl.

Bearbeite dies vor dem Provisionieren. Die Referenz liefert Platzhalter, keine Standardwerte:

FeldPlatzhalterWas es sein muss
metadata.namemy-clusterder Name deines Clusters
spec.cluster.domain und der Ordnerexample.comeine Domain, die dir gehört (wird für den API-Endpunkt verwendet)
die SSH-Pfade in provider.config~/.ssh/id_ed25519[.pub]der echte Pfad deines Schlüssels, nur falls er nicht den Ed25519-Standardnamen trägt

lok8s deinen Hetzner-Token geben

lo provision erzeugt echte, kostenpflichtige Infrastruktur in deinem Hetzner-Konto und authentifiziert sich mit dem API-Token aus den Voraussetzungen. Exportiere ihn in derselben Shell, aus der du gleich provisionierst. Er wird aus der Umgebung gelesen, nie aus der Konfigurationsdatei, und landet so nie in git:

bash
export HCLOUD_TOKEN="<dein-token>"

Cluster bereitstellen

Führe dies aus deinem Projektverzeichnis aus, mit aktiver Domain:

bash
lo provision

Die Bereitstellung dauert typischerweise 10–15 Minuten. Die kubeconfig wird als .kubeconfig/my-cluster.yaml im Projekt abgelegt, benannt nach metadata.name. Deine ~/.kube/config wird nicht angefasst.

Die Referenzkonfiguration oben fordert bei Hetzner fünf Server an (3 für die Control Plane und 2 Worker), die stündlich zu Hetzners veröffentlichten Preisen für diese Servertypen abgerechnet werden. Nichts davon ist endgültig: lo destroy entfernt jederzeit jeden Server, den lok8s angelegt hat.

Überprüfen

kubectl zeigt weiterhin auf den zuvor genutzten Kontext; wähle den neuen Cluster also explizit aus, sonst antwortet get nodes für deinen vorherigen:

bash
export KUBECONFIG=.kubeconfig/my-cluster.yaml
kubectl get nodes
# (AGE trimmed — STATUS is what to check)
# NAME       STATUS   ROLES           VERSION
# cp-1       Ready    control-plane   v1.35.5
# cp-2       Ready    control-plane   v1.35.5
# cp-3       Ready    control-plane   v1.35.5
# worker-1   Ready    <none>          v1.35.5
# worker-2   Ready    <none>          v1.35.5

kubectl get pods -A

# Listet NUR Pods, die noch nicht bereit sind. Auf einem gesunden Cluster: nichts.
kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded
# No resources found

Jeder Node sollte Ready melden, und die Spalte VERSION sollte zur oben konfigurierten Kubernetes-Version passen.

kubectl get pods -A listet alle System-Pods, viel zum Durchsehen. Der zweite Befehl dreht das um: Er zeigt nur, was nicht Running oder Completed erreicht hat. No resources found ist die gewünschte Antwort. Gib CNI und Cloud-Controller direkt nach dem Provisionieren eine Minute, bevor du dort Gelistetes als Fehler wertest.

Nächste Schritte


Doku-Status

AspektDetail
Zustandaktiv
Zuletzt geprüft2026-09-05