LoadBalancer Services

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.

Annotations-Referenz

IP- und Netzwerkkonfiguration

AnnotationDefaultBeschreibung
service.beta.kubernetes.io/openstack-internal-load-balancerfalseErstellt einen internen LoadBalancer ohne Floating IP. Zugriff nur aus dem internen Netzwerk.
loadbalancer.openstack.org/keep-floatingipfalseBehält die Floating IP in OpenStack reserviert, auch wenn der Service gelöscht wird.
loadbalancer.openstack.org/hostnameSetzt einen expliziten Hostnamen im Service-Status anstelle der Floating IP.
loadbalancer.openstack.org/load-balancer-addressWird automatisch nach der Erstellung gesetzt. Enthält die Floating IP. Bei gesetztem hostname steht die echte IP nur hier.

Proxy Protocol und Header

AnnotationDefaultBeschreibung
loadbalancer.openstack.org/proxy-protocol ¹falseAktiviert 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

AnnotationDefaultBeschreibung
loadbalancer.openstack.org/lb-methodCCM-KonfigurationLB-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-idBindet den Service an einen bereits existierenden Octavia LoadBalancer. Darf nach der Erstellung nicht geändert werden.

Timeouts

AnnotationDefaultBeschreibung
loadbalancer.openstack.org/timeout-client-data ¹30000 msTimeout 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 msTimeout 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.

Zuletzt geändert 29.04.2026: Resolving last comments (b48501e)