Zum Inhalt

Kubernetes LoadBalancer und Octavia

Wenn Sie eine Kubernetes-Anwendung ins Internet freigeben, verwenden Sie typischerweise einen Service vom type: LoadBalancer. Auf unserer Plattform erstellt dies automatisch einen echten Octavia-Loadbalancer in Ihrem OpenStack-Projekt. Dieses Integration zu verstehen ist entscheidend für die Fehlersuche bei Netzwerkproblemen und das Quota-Management.

Wie es funktioniert

Wenn Sie einen Service mit type: LoadBalancer in Ihrem Shoot-Cluster erstellen, provisioniert der Cloud-Controller-Manager — der in der Control Plane des Shoots auf dem Seed läuft — einen Octavia-Loadbalancer in OpenStack und verbindet ihn mit Ihren Worker-Nodes.

%%{init: {'themeVariables': {'textColor': '#333333', 'edgeLabelBackground': '#ffffff', 'clusterBkg': 'transparent', 'clusterBorder': '#999999'}}}%%
flowchart LR
    Internet["Internet"]
    FIP["Floating IP<br>(öffentliches Netzwerk)"]

    subgraph OS ["OpenStack"]
        LB["Octavia-Loadbalancer<br>Listener · Pool · Health Monitor"]
    end

    subgraph K8s ["Kubernetes Shoot-Cluster"]
        W1["Worker-Node 1"]
        W2["Worker-Node 2"]
        Pod1["Pod: nginx"]
        Pod2["Pod: nginx"]
    end

    Internet --> FIP
    FIP --> LB
    LB --> W1
    LB --> W2
    W1 --> Pod1
    W2 --> Pod2

    classDef ext fill:#fce4ec,stroke:#c62828,color:#b71c1c;
    classDef fip fill:#e3f2fd,stroke:#1565c0,color:#0d47a1;
    classDef lb fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20;
    classDef worker fill:#fff3e0,stroke:#e65100,color:#bf360c;
    classDef pod fill:#f3e5f5,stroke:#6a1b9a,color:#4a148c;
    class Internet ext;
    class FIP fip;
    class LB lb;
    class W1,W2 worker;
    class Pod1,Pod2 pod;
    linkStyle 0,1 stroke:#c62828,stroke-width:2px;
    linkStyle 2,3 stroke:#2e7d32,stroke-width:2px;
    linkStyle 4,5 stroke:#e65100,stroke-width:2px;
%%{init: {'themeVariables': {'textColor': '#e0e0e0', 'edgeLabelBackground': '#2a2a2a', 'clusterBkg': 'transparent', 'clusterBorder': '#666666'}}}%%
flowchart LR
    Internet["Internet"]
    FIP["Floating IP<br>(öffentliches Netzwerk)"]

    subgraph OS ["OpenStack"]
        LB["Octavia-Loadbalancer<br>Listener · Pool · Health Monitor"]
    end

    subgraph K8s ["Kubernetes Shoot-Cluster"]
        W1["Worker-Node 1"]
        W2["Worker-Node 2"]
        Pod1["Pod: nginx"]
        Pod2["Pod: nginx"]
    end

    Internet --> FIP
    FIP --> LB
    LB --> W1
    LB --> W2
    W1 --> Pod1
    W2 --> Pod2

    classDef ext fill:#3e1e1e,stroke:#ef5350,color:#ffcdd2;
    classDef fip fill:#1a3a5c,stroke:#64b5f6,color:#e3f2fd;
    classDef lb fill:#1b3a2a,stroke:#66bb6a,color:#c8e6c9;
    classDef worker fill:#3e2723,stroke:#ff9800,color:#ffe0b2;
    classDef pod fill:#2a1a3a,stroke:#ab47bc,color:#e1bee7;
    class Internet ext;
    class FIP fip;
    class LB lb;
    class W1,W2 worker;
    class Pod1,Pod2 pod;
    linkStyle 0,1 stroke:#ef5350,stroke-width:2px;
    linkStyle 2,3 stroke:#66bb6a,stroke-width:2px;
    linkStyle 4,5 stroke:#ff9800,stroke-width:2px;

Der Provisioning-Ablauf

  1. Sie erstellen einen Service mit type: LoadBalancer in Ihrem Shoot-Cluster.
  2. Der Cloud-Controller-Manager (CCM) erkennt den neuen Service.
  3. Der CCM ruft die OpenStack-Octavia-API auf und provisioniert:
    • Einen Loadbalancer mit einer VIP im Worker-Node-Netzwerk.
    • Einen Listener für den im K8s-Service angegebenen Port.
    • Einen Pool mit den Worker-Nodes als Members.
    • Einen Health Monitor zur Überwachung der Worker-Node-Gesundheit.
  4. Eine Floating IP wird im öffentlichen Netzwerk erstellt und mit der Loadbalancer-VIP verknüpft.
  5. Der CCM schreibt die Floating IP als EXTERNAL-IP in den Service-Status zurück.
  6. kubectl get svc zeigt nun die externe IP — Ihre Anwendung ist aus dem Internet erreichbar.

Was in OpenStack erscheint

Der Octavia-Loadbalancer ist eine echte OpenStack-Ressource in Ihrem Projekt. Sie sehen ihn in:

  • OpenStack Horizon → Network → Load Balancers
  • OpenStack CLI: openstack loadbalancer list

Jeder K8s-LoadBalancer-Service erstellt:

Octavia-Ressource Zweck
Load Balancer Das übergeordnete LB-Objekt mit einer VIP im Worker-Netzwerk
Listener Lauscht auf dem im K8s-Service angegebenen Port
Pool Enthält die Worker-Nodes als Members
Members Einer pro Worker-Node, leitet an den NodePort weiter
Health Monitor Prüft die Worker-Node-Gesundheit über den NodePort

Praktisches Beispiel

Deployen Sie nginx mit einem LoadBalancer-Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

Anwenden und den Service prüfen:

kubectl apply -f nginx.yaml
kubectl get svc nginx

Während Octavia provisioniert, wird die externe IP als <pending> angezeigt:

NAME    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx   LoadBalancer   10.97.246.12   <pending>     80:31234/TCP   5s

Sobald Octavia bereit ist (in der Regel 30–60 Sekunden):

NAME    TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
nginx   LoadBalancer   10.97.246.12   192.0.2.50     80:31234/TCP   45s

Die EXTERNAL-IP ist die von Octavia zugewiesene Floating IP. Ihre Anwendung ist nun unter http://192.0.2.50 erreichbar.

In OpenStack verifizieren

Der Loadbalancer und die Floating IP sind in OpenStack sichtbar:

openstack loadbalancer list
openstack floating ip list

Floating-IP-Lebenszyklus

Die Floating IP gehört immer zum LoadBalancer-Service — nicht zum Ingress-Objekt. Daraus ergibt sich folgendes Verhalten:

Aktion Was mit der Floating IP passiert
LoadBalancer-Service löschen Floating IP wird gelöscht und verlässt Ihr Projekt
Nur das Ingress-Objekt löschen Floating IP bleibt erhalten — sie gehört zum Service des Ingress-Controllers
Ingress-Controller deinstallieren (z. B. helm uninstall) Floating IP wird gelöscht, da der Controller-Service mit entfernt wird
LoadBalancer-Service löschen und neu erstellen Neue Floating IP mit anderer Adresse — IP-Adressen sind nicht „klebrig"

Floating IP dauerhaft behalten

Mit der Annotation loadbalancer.openstack.org/keep-floatingip: "true" bleibt die Floating IP beim Löschen des Services in Ihrem Projekt erhalten. Sie ist danach keinem Port mehr zugeordnet (openstack floating ip list zeigt sie ohne Port) und kann später wiederverwendet werden:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    loadbalancer.openstack.org/keep-floatingip: "true"
spec:
  type: LoadBalancer
  loadBalancerIP: 192.0.2.50   # freie Floating IP aus Ihrem Projekt
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

Die Wiederverwendung läuft über spec.loadBalancerIP: Der neue Service übernimmt die vorhandene Adresse, sobald sie frei (nicht zugeordnet) ist.

Annotation auf jedem Service setzen

Die Annotation wirkt pro Service und hängt nicht an der IP-Adresse selbst. Ein neuer Service, der eine vorhandene Floating IP über spec.loadBalancerIP übernimmt, muss die Annotation ebenfalls setzen — andernfalls wird die IP beim Löschen dieses Services mitgelöscht.

Reservierte Adressen sind nicht wiederherstellbar

Wenn Sie eine bestimmte IP-Adresse behalten möchten (z. B. wegen DNS-Einträgen oder Firewall-Freigaben bei Gegenstellen), ist das Parken mit der Annotation der einzige zuverlässige Weg. Eine gelöschte Floating IP kann nicht erneut unter derselben Adresse bezogen werden.

NodePort vs LoadBalancer vs Ingress

NodePort LoadBalancer Ingress
Gibt frei Einen einzelnen Service auf einem hohen Port (30000–32767) Einen einzelnen Service auf einem Standardport Mehrere Services via HTTP(S)-Routing
Externe IP Worker-Node-IP + Node-Port Dedizierte Floating IP Hängt vom Service-Typ des Ingress-Controllers ab
Octavia-LB Nein Ja — einer pro Service Nur wenn der Ingress-Controller LoadBalancer verwendet
TLS-Terminierung Nein Mit Annotations möglich Ja (Ingress-Controller übernimmt TLS)
Quota Keine 1 Octavia-LB + 1 Floating IP pro Service 1 Octavia-LB (für den Ingress-Controller)
Am besten für Interner / Debug-Zugriff Einzelner Service ins Internet Mehrere HTTP(S)-Services auf einer IP

Empfehlung

Für mehrere HTTP(S)-Services verwenden Sie einen Ingress-Controller (z.B. nginx-ingress) mit einem einzigen LoadBalancer-Service. Dies verbraucht nur einen Octavia-LB und bietet TLS-Terminierung und pfadbasiertes Routing.

Quota-Überlegungen

Jeder Service vom Typ LoadBalancer erstellt einen Octavia-Loadbalancer in Ihrem OpenStack-Projekt. Dies verbraucht:

  • Octavia-Loadbalancer — prüfen Sie Ihre Projekt-Quota.
  • Floating IPs — eine pro LoadBalancer-Service.
  • Ports — im Worker-Node-Netzwerk.

Wenn Sie das Quota-Limit erreichen, bleiben neue LoadBalancer-Services im Status <pending>. Prüfen Sie Ihre Quota im Cloud Services Portal oder mit:

openstack quota show

Aufräumen

Wenn Sie einen Kubernetes-Service vom Typ LoadBalancer löschen, löscht der Cloud-Controller-Manager automatisch den entsprechenden Octavia-Loadbalancer und gibt die Floating IP frei:

Möchten Sie die Floating IP behalten (z. B. für einen späteren Service oder feste DNS-Einträge), setzen Sie vor dem Löschen die Annotation loadbalancer.openstack.org/keep-floatingip: "true" — siehe Floating-IP-Lebenszyklus.

kubectl delete svc nginx

Warning

Löschen Sie immer zuerst den K8s-Service. Wenn Sie den Octavia-Loadbalancer manuell in OpenStack löschen, kann der CCM möglicherweise nicht mehr sauber aufräumen, was zu verwaisten Ressourcen führt.

Manuelle Octavia-Loadbalancer

Sie können Octavia-Loadbalancer auch manuell für Nicht-Kubernetes-Workloads erstellen (z.B. OpenStack-VMs). Siehe den OpenStack-Loadbalancer-Leitfaden für CLI-Beispiele inklusive HTTP, HTTPS-Terminierung und Health Monitors.

Nächster Schritt

Erfahren Sie, wie Sie persistente Service-Accounts erstellen oder kehren Sie zur Cluster-Verwaltung zurück.