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
- Sie erstellen einen
Servicemittype: LoadBalancerin Ihrem Shoot-Cluster. - Der Cloud-Controller-Manager (CCM) erkennt den neuen Service.
- 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.
- Eine Floating IP wird im öffentlichen Netzwerk erstellt und mit der Loadbalancer-VIP verknüpft.
- Der CCM schreibt die Floating IP als
EXTERNAL-IPin den Service-Status zurück. kubectl get svczeigt 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.