LoadBalancer Services
4 Minuten Lesezeit
In der PSKE werden Kubernetes Services vom Typ LoadBalancer über den OpenStack Cloud Controller Manager (CCM) bereitgestellt. Der CCM provisioniert automatisch einen Octavia LoadBalancer in OpenStack und weist ihm eine Floating IP zu.
Die Konfiguration erfolgt ausschließlich über Annotations am Service-Objekt.
lb-provider=ovn nicht unterstützt.Annotations-Referenz
IP- und Netzwerkkonfiguration
| Annotation | Default | Beschreibung |
|---|---|---|
service.beta.kubernetes.io/openstack-internal-load-balancer | false | Erstellt einen internen LoadBalancer ohne Floating IP. Zugriff nur aus dem internen Netzwerk. |
loadbalancer.openstack.org/keep-floatingip | false | Behält die Floating IP in OpenStack reserviert, auch wenn der Service gelöscht wird. |
loadbalancer.openstack.org/hostname | — | Setzt einen expliziten Hostnamen im Service-Status anstelle der Floating IP. |
loadbalancer.openstack.org/load-balancer-address | — | Wird automatisch nach der Erstellung gesetzt. Enthält die Floating IP. Bei gesetztem hostname steht die echte IP nur hier. |
Proxy Protocol und Header
| Annotation | Default | Beschreibung |
|---|---|---|
loadbalancer.openstack.org/proxy-protocol ¹ | false | Aktiviert das PROXY Protocol. Überträgt die Original-Client-IP an das Backend. |
loadbalancer.openstack.org/x-forwarded-for ¹ | — | Fügt den X-Forwarded-For-Header hinzu. Erzwingt Listener-Typ HTTP. |
Load-Balancing-Verhalten
| Annotation | Default | Beschreibung |
|---|---|---|
loadbalancer.openstack.org/lb-method | CCM-Konfiguration | LB-Algorithmus. Werte: ROUND_ROBIN, LEAST_CONNECTIONS, SOURCE_IP, SOURCE_IP_PORT. |
loadbalancer.openstack.org/connection-limit | -1 (unbegrenzt) | Maximale Verbindungen pro Sekunde pro Listener. Unterstützt Live-Updates. |
loadbalancer.openstack.org/load-balancer-id | — | Bindet den Service an einen bereits existierenden Octavia LoadBalancer. Darf nach der Erstellung nicht geändert werden. |
Timeouts
| Annotation | Default | Beschreibung |
|---|---|---|
loadbalancer.openstack.org/timeout-client-data ¹ | 30000 ms | Timeout in Millisekunden für inaktive Client-Verbindungen (Frontend). |
loadbalancer.openstack.org/timeout-member-connect ¹ | — | Timeout in Millisekunden für den Verbindungsaufbau zum Backend-Member. |
loadbalancer.openstack.org/timeout-member-data ¹ | 30000 ms | Timeout in Millisekunden für inaktive Verbindungen zum Backend-Member. |
loadbalancer.openstack.org/timeout-tcp-inspect ¹ | — | Wartezeit in Millisekunden auf weitere TCP-Pakete zur Inhaltsbestimmung. |
Anwendungsfälle
Interner LoadBalancer
Ein interner LoadBalancer erhält keine Floating IP und ist nur innerhalb des Cluster-Netzwerks erreichbar. Die interne IP-Adresse kann über spec.loadBalancerIP vorgegeben werden (freie Adresse aus dem Node-Netzwerk, Standard: 10.250.0.0/16).
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
annotations:
service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
spec:
type: LoadBalancer
loadBalancerIP: 10.250.0.10
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
Floating IP reservieren und wiederverwenden
Standardmäßig wird die Floating IP beim Löschen des Services freigegeben. Mit keep-floatingip: "true" bleibt sie in OpenStack reserviert.
Reservierung:
metadata:
annotations:
loadbalancer.openstack.org/keep-floatingip: "true"
Bereits reservierte Floating IP zuweisen:
metadata:
annotations:
loadbalancer.openstack.org/keep-floatingip: "true"
loadbalancer.openstack.org/load-balancer-address: <FloatingIP>
spec:
loadBalancerIP: <FloatingIP>
Floating IP freigeben (vor dem Löschen des Services):
metadata:
annotations:
loadbalancer.openstack.org/keep-floatingip: "false"
loadbalancer.openstack.org/load-balancer-address: <FloatingIP>
spec:
loadBalancerIP: <FloatingIP>
Falls nicht mehr bekannt ist, welche Floating IPs reserviert sind, bitte ein Support-Ticket im Kundenportal eröffnen.
Timeouts anpassen
Der Standard-Timeout für OpenStack LoadBalancer liegt bei 30 Sekunden. Für Anwendungen mit langen Verbindungen (z.B. WebSockets, große Datei-Uploads) sollten die Timeouts angepasst werden:
metadata:
annotations:
loadbalancer.openstack.org/timeout-client-data: "70000"
loadbalancer.openstack.org/timeout-member-data: "70000"
Proxy Protocol — Client-IP weiterleiten
Ohne Proxy Protocol erscheinen alle eingehenden Verbindungen im Backend mit der internen IP des LoadBalancers als Quell-IP. Das Proxy Protocol überträgt die originale Client-IP.
Annotation am LoadBalancer Service:
metadata:
annotations:
loadbalancer.openstack.org/proxy-protocol: "true"
Ingress Controller — NGINX (ConfigMap):
use-proxy-protocol: "true"
use-forwarded-headers: "true"
Ingress Controller — Traefik (Helm values):
Traefik aktiviert Proxy Protocol auf Ebene der EntryPoints. Die Konfiguration gilt sowohl für den klassischen Ingress- als auch für den Gateway-API-Betrieb (Traefik v3):
ports:
web:
proxyProtocol:
trustedIPs:
- "0.0.0.0/0"
websecure:
proxyProtocol:
trustedIPs:
- "0.0.0.0/0"
Gateway API — Traefik v3 (Helm values):
Traefik unterstützt ab v3 nativ die Gateway API. Proxy Protocol wird auf Ebene der EntryPoints konfiguriert — unabhängig davon, ob Ingress- oder Gateway-API-Ressourcen genutzt werden:
ports:
web:
proxyProtocol:
trustedIPs:
- "0.0.0.0/0"
websecure:
proxyProtocol:
trustedIPs:
- "0.0.0.0/0"
Gateway API — Envoy Gateway:
Proxy Protocol wird über eine ClientTrafficPolicy aktiviert, die auf das jeweilige Gateway zeigt:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: proxy-protocol
namespace: <gateway-namespace>
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: <gateway-name>
enableProxyProtocol: true
Proxy Protocol und interne Dienste
Bei aktiviertem Proxy Protocol leitet kube-proxy den Cluster-internen Zugriff auf die externe LoadBalancer-IP direkt an den Ingress Controller weiter — ohne das Proxy Protocol zu sprechen. Das führt zu Verbindungsfehlern, z.B. beim Cert-Manager bei der ACME-Challenge.
Lösung: Die Annotation loadbalancer.openstack.org/hostname setzt einen DNS-Namen im Service-Status. kube-proxy verwendet diesen Namen statt der IP, wodurch der Umweg über den LoadBalancer erhalten bleibt.
metadata:
annotations:
loadbalancer.openstack.org/proxy-protocol: "true"
loadbalancer.openstack.org/hostname: <loadbalancer-ip>.nip.io
Für <loadbalancer-ip>.nip.io — oder einen eigenen DNS-A-Eintrag — muss die IP auf die Floating IP des LoadBalancers zeigen.
Die vollständige upstream Dokumentation findet sich im GitHub-Projekt kubernetes/cloud-provider-openstack — bitte die zur eingesetzten Kubernetes-Version passende Release-Branch verwenden.