Heute werden wir untersuchen, wie man auf Anwendungen zugreift, die auf Kubernetes laufen. Insbesondere werden wir uns mit der Funktionalität von Kubernetes-Diensten des Typs LoadBalancer, ihren Anwendungsfällen und ihrer Integration mit Load Balancern von Cloud-Anbietern befassen. Außerdem werden wir das Konzept des Ingress besprechen und wie es mit LoadBalancer-Diensten zusammenhängt.
Außerdem werden wir kurz das Konzept der Finalizer und ihre Rolle bei der Verhinderung der unbeabsichtigten Aktivierung von Cloud-Ressourcen beim Löschen von Load Balancern in Kubernetes untersuchen.
Dienste in Kubernetes
Kubernetes verwendet Pods, die jeweils eine eigene IP-Adresse haben. Wenn Kubernetes jedoch einen Pod erstellt oder beendet, ändert sich seine IP-Adresse, was ein Problem darstellt, wenn man versucht, auf eine Anwendung zuzugreifen, die auf dem Pod läuft. Um dieses Problem zu lösen, bieten die Kubernetes-Dienste eine verlässliche, statische IP-Adresse, über die wir auf die im Pod gehostete Anwendung zugreifen können.

Standardmäßig verwendet Kubernetes ClusterIP als Diensttyp, auf den nur von innerhalb des Clusters zugegriffen werden kann. Die Diensttypen NodePort und LoadBalancer hingegen ermöglichen den Zugriff von außen auf den Cluster.
Ingress vs. Dienstart LoadBalancer
Auf den ersten Blick mag es so aussehen, als würden Kubernetes-Dienste vom Typ LoadBalancer und Ingresses identische Aufgaben erfüllen. Lassen Sie uns jedoch einen genaueren Blick auf sie werfen und diskutieren, ob dies der Fall ist und wie sie sich unterscheiden.
Ein LoadBalancer-Dienst in Kubernetes ist über externe Load Balancer zugänglich, die sich außerhalb Ihres Kubernetes-Clusters befinden. Diese Load Balancer können mit Ihren Pods interagieren, sofern sie von außen zugänglich sind. Diese Funktion ist von Haus aus in Google und AWS verfügbar. Im Falle von AWS ist dieser Dienst direkt mit ELB verknüpft. Beim Betrieb auf AWS (EKS) kann Kubernetes automatisch eine ELB-Instanz für jeden bereitgestellten LoadBalancer-Dienst einrichten und konfigurieren.
Das folgende Beispiel veranschaulicht den Zugriff auf Pods und ihre Anwendungen auf Kubernetes unter Verwendung eines LoadBalancer-Service-Typs mit AWS.

In Situationen, in denen Sie Kubernetes vor Ort betreiben, ist es möglicherweise nicht wünschenswert, sich beim Lastausgleich auf einen Cloud-Anbieter zu verlassen. In solchen Fällen gibt es Alternativen wie MetalLB. MetalDB ist eine Netzwerk-Lastausgleichslösung, die speziell für Kubernetes-Cluster entwickelt wurde, die auf einer Bare-Metal-Infrastruktur laufen. MetalDB hilft bei der Zuweisung von IP-Adressen an Kubernetes-Dienste und verwaltet die Netzwerktopologie, führt aber keinen Lastausgleich durch. Eine mögliche Lösung ist die Verwendung von MetalLB (eine beliebte Implementierung von MetalDB) mit HAProxy als externem Load Balancer. MetalLB kann den Diensten innerhalb des Kubernetes-Clusters IP-Adressen zuweisen, und HAProxy kann dann diese IP-Adressen verwenden, um den Datenverkehr an die entsprechenden Backend-Pods zu leiten.
Auf der anderen Seite ist Ingress im Wesentlichen eine Sammlung von Regeln, die an einen Controller weitergeleitet werden müssen, der speziell dafür ausgelegt ist, sie zu empfangen - einen Ingress-Controller. Es ist möglich, zahlreiche Ingress-Regeln zu implementieren, aber ohne einen Controller, der sie verarbeitet, bleiben sie inaktiv. Wenn er richtig konfiguriert ist, kann ein LoadBalancer-Dienst als Listener für Ingress-Regeln dienen.
Betrachten wir ein Beispiel für eine Ingress-Ressource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: itgix-ingress-example
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "bar.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
Jede Ingress-Regel besteht aus den folgenden Komponenten:
- Gastgeber
- Pfade
- Backend
In diesem Beispiel wird der Host für beide Ingress-Regeln angegeben, so dass sie für eingehenden HTTP-Verkehr gelten, wobei der Host-Header entweder foo.bar.com oder bar.foo.com lautet.
Der Abschnitt Pfade enthält eine Liste von Pfaden, wobei jede Ingress-Regel einen Pfad in ihrer Liste von Pfaden hat. Jeder Pfad ist mit einem Backend verbunden.
Das Backend definiert einen Dienst, der den Datenverkehr empfangen soll. HTTP(S)-Anfragen, die mit dem Host und dem Pfad der Regel übereinstimmen, werden an das angegebene Backend weitergeleitet.
Werfen wir einen Blick auf eine zweite Ingress-Ressource und eine visuelle Darstellung davon. Diesmal besteht der Ingress aus drei Regeln, die sich alle auf denselben Host, nämlich example.com, beziehen. Die Regeln unterscheiden sich durch den Pfad, was bedeutet, dass eine eingehende Anforderung mit dem Host-Header example.com und dem Pfad s1 an den Dienst service1 weitergeleitet wird:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-example
spec:
rules:
- host: "example.com"
http:
paths:
- pathType: Prefix
path: "/s1"
backend:
service:
name: service1
port:
number: 80
- host: "example.com"
http:
paths:
- pathType: Prefix
path: "/s2"
backend:
service:
name: service2
port:
number: 80
- host: "example.com"
http:
paths:
- pathType: Prefix
path: "/s3"
backend:
service:
name: service3
port:
number: 80
Aber wie wählt man die richtige Methode?
Werfen wir zunächst einen Blick auf den Diensttyp LoadBalancer, da dies die Standardmethode für die direkte Bereitstellung eines Dienstes ist. Der gesamte Verkehr am angegebenen Port wird ohne Filterung oder Routing an den Dienst weitergeleitet. Das bedeutet, dass nahezu jede Art von Datenverkehr, wie HTTP, TCP, UDP, Websockets, gRPC usw., an ihn gesendet werden kann.
Der Hauptnachteil des Diensttyps LoadBalancer besteht darin, dass jeder exponierte Dienst eine eigene IP-Adresse erhält und für jeden exponierten Dienst ein LoadBalancer bezahlt werden muss, was kostspielig werden kann.
Der Übergang zu Ingress ist wahrscheinlich die leistungsstärkste Methode zur Bereitstellung von Diensten, kann aber auch die komplexeste sein. Es sind verschiedene Arten von Ingress-Controllern verfügbar, darunter Google Cloud Load Balancer, Nginx, Istio und andere. Darüber hinaus gibt es Plugins für Ingress-Controller, wie z. B. cert-manager, die automatisch SSL-Zertifikate für Dienste bereitstellen können.
Ingress ist am vorteilhaftesten, wenn mehrere Dienste unter derselben IP-Adresse bereitgestellt werden müssen und wenn diese Dienste dasselbe L7-Protokoll verwenden (normalerweise HTTP). Bei Verwendung der nativen GCP-Integration muss nur ein Load Balancer bezahlt werden, und da Ingress "intelligent" ist, sind viele Funktionen von Haus aus enthalten (wie SSL, Auth, Routing usw.).
Werfen wir abschließend noch einen Blick auf AWS Load Balancer Controller. Wie bereits erwähnt, benötigt der Servicetyp LoadBalancer für den Betrieb einen externen Load Balancer, der in der Regel von einem Cloud-Anbieter bereitgestellt wird.
Der Einrichtungsprozess hierfür variiert je nach verwendetem Cloud-Anbieter. Wenn Sie zum Beispiel AWS verwenden, müssen Sie den AWS Load Balancer Controller verwenden.
Dieser Controller ist für die Erstellung eines ELB (Elastic Load Balancer) auf AWS verantwortlich, sobald ein LoadBalancer-Service in Ihrem Kubernetes-Cluster erstellt wird.

Wenn ein Service vom Typ LoadBalancer erstellt wird, kommuniziert der AWS Load Balancer Controller mit AWS, um sicherzustellen, dass der entsprechende ELB erstellt wird
Wenn wir einen Dienst des Typs LoadBalancer löschen, würden wir idealerweise auch den eigentlichen Load Balancer in der Cloud löschen wollen, da er ohne den Dienst keinen Zweck erfüllt.
Die gute Nachricht ist, dass genau dies geschieht, wenn der AWS Load Balancer Controller in Ihrem Kubernetes-Cluster bereitgestellt wird. Sie werden feststellen, dass allen Services des Typs LoadBalancer ein Metadatenabschnitt hinzugefügt wurde, der wie folgt aussieht:
finalizer:
- service.k8s.aws/resources
Ebenso enthalten alle Ingresses in Ihrem Cluster auch einen Finalizer-Abschnitt:
finalizer:
- ingress.k8s.aws/resources
Die oben erwähnten Finalizer stellen sicher, dass die zugehörigen Cloud-Ressourcen nicht gelöscht werden, bis der AWS Load Balancer Controller seinen Bereinigungsprozess abgeschlossen hat. Obwohl der Name des Finalizers, z. B. service.k8s.aws/resources, in Kubernetes nur ein String ist, wird er vom Load Balancer Controller verstanden.
Wenn Sie einen Finalizer mit einer Zeichenfolge hinzufügen, die von keinem Controller erkannt wird:
finalizer:
- my.random.itgix.string/doesnotexist
dann kann die Ressource nicht unbegrenzt gelöscht werden. In solchen Fällen müssen Sie den Finalizer manuell aus der Ressourcendefinition entfernen, um sie zu löschen.
Weitere fachkundige Inhalte finden Sie auf unserer Blog-Seite, und vergessen Sie nicht, sich für unseren Newsletter anzumelden!