Kubernetes ist eine Open-Source-Plattform zur Automatisierung von Container-Deployments, Skalierungsprozessen und Betriebsabläufen. Anwendungen laufen in Containern, die zu Pods gruppiert sind, den grundlegenden Einheiten, die innerhalb eines Kubernetes-Clusters bereitgestellt und verwaltet werden.
Services in Kubernetes stellen einen zentralen Bestandteil dar, um Anwendungen stabil und zugänglich zu halten. Sie sorgen für konstante Zugriffspunkte zu den transitorischen Pods und sichern so die Kontinuität und Verfügbarkeit von Anwendungen in der volatilen Welt der Container.
In Kubernetes erhält jeder Pod beim Start eine eindeutige IP-Adresse aus dem internen Netzwerk des Clusters. Diese Adresse bleibt während der Lebensdauer des Pods erhalten. Allerdings sind Pods in Kubernetes ephemeral, das bedeutet, sie können häufig erstellt und vernichtet werden, beispielsweise beim Hoch- und Runterfahren von Services, durch Deployments oder wenn sie durch das Cluster-Management zur Heilung oder Skalierung neu platziert werden. Bei jedem Neustart eines Pods wird eine neue IP-Adresse zugewiesen. Dies stellt eine Herausforderung dar, wenn stabile Endpunkte für die Kommunikation mit Services innerhalb oder außerhalb des Clusters benötigt werden.
Um dieses Problem zu adressieren, stellt Kubernetes die Service-Ressource bereit. Ein Kubernetes Service ist eine Abstraktion, die einen stabilen Zugangspunkt zu einer logischen Gruppe von Pods, die denselben Service ausführen, definiert. Services ermöglichen es, Netzwerkverkehr an eine Gruppe von Pods zu routen, ohne die spezifischen internen IP-Adressen der Pods kennen zu müssen!
ClusterIP: Der Standard-Service-Typ, der einen internen
IP-Adressdienst im Cluster bereitstellt. Dieser ist nur innerhalb des
Clusters erreichbar.NodePort: Stellt den Service über einen Port auf jedem
Node im Cluster zur Verfügung. Dies erlaubt den Zugriff von außerhalb
des Clusters.LoadBalancer: Integriert Kubernetes Services mit
unterstützten Cloud-Loadbalancern für den Zugriff von außerhalb des
Clusters.ExternalName: Mapped einen Service zu einem DNS-Namen
und nicht zu einer typischen Selector-basierten Auswahl von Pods. In diesem Diagramm:
Jeder Service hat einen DNS-Namen im Format
service.namespace.svc.cluster.local, der innerhalb des
Clusters aufgelöst werden kann. Der namespace ist der
Namespace, in dem der Service läuft, und würde entsprechend ersetzt
werden.
Ein Kubernetes Service verwendet Labels und
Selectors, um eine Verbindung zu den Pods herzustellen. Der
Service überwacht kontinuierlich das Cluster, um sicherzustellen, dass
die Verkehrsverteilung auf die aktiven Pods erfolgt. Wenn ein Pod
terminiert und ein neuer erstellt wird, aktualisiert der Service
automatisch seine Endpunktliste, sodass der Verkehr zu den verfügbaren
Pods umgeleitet wird. Dadurch können Clients weiterhin über die stabile
Adresse des Services kommunizieren, auch wenn sich die dahinter
liegenden Pods ändern.
Zur Erstellung eines Services wird eine Konfigurationsdatei im YAML-Format benötigt, die die gewünschten Eigenschaften des Services definiert. Diese Konfigurationsdatei wird an die Kubernetes-API übermittelt, welche dann den Service im Cluster erstellt.
apiVersion: v1
kind: Service
metadata:
name: mein-service
spec:
selector:
app: MeineApp
ports:
- protocol: TCP
port: 80
targetPort: 9376Im obigen Beispiel wird ein Service namens mein-service
definiert, der Traffic auf TCP-Port 80 entgegennimmt und an Pods
weiterleitet, die mit app=MeineApp gelabelt sind, auf deren
Port 9376.
Kubernetes Services bieten eine abstrahierte Weise, auf eine Gruppe von Pods, die eine Anwendung ausführen, zuzugreifen. Services in Kubernetes garantieren, dass der Netzwerkverkehr zu den Anwendungen konsequent und zuverlässig weitergeleitet wird, auch wenn die Pods, die die Anwendung ausführen, geändert, aktualisiert oder neu gestartet werden.
Kubernetes Services sind entscheidend für die Netzwerkkommunikation
und den Zugriff auf Anwendungen, die in einem Kubernetes-Cluster laufen.
Durch die verschiedenen Service-Typen bieten sie eine breite Palette an
Möglichkeiten, um Anwendungen sowohl innerhalb des Clusters als auch von
außen zugänglich zu machen und gleichzeitig die Verwaltung und das
Routing des Verkehrs zu vereinfachen. Durch den Einsatz von
ClusterIP, NodePort,
Load Balancer und ExternalName kann ein
einheitlicher Zugriffspunkt für Anwendungen geschaffen werden, der die
Service-Discovery und die Netzwerkkonfiguration stark vereinfacht.
Beginnen wir mit dem Standardtyp eines Services, dem
ClusterIP. Dieser Service-Typ ist ideal für Anwendungen,
die nur innerhalb des Clusters erreichbar sein sollen. Ein typischer
Anwendungsfall könnte ein interner Datenbankdienst sein, der nicht
öffentlich exponiert werden soll.
apiVersion: v1
kind: Service
metadata:
name: datenbank-service
spec:
selector:
app: datenbank
ports:
- protocol: TCP
port: 3306
targetPort: 3306In diesem Beispiel erstellt die Konfiguration einen Service, der auf
TCP-Port 3306 lauscht und den Verkehr an den Port 3306 der Pods
weiterleitet, die mit dem Label app: datenbank markiert
sind.
Um eine Anwendung von außerhalb des Kubernetes-Clusters zugänglich zu
machen, kann ein NodePort-Service verwendet werden. Ein
NodePort-Service macht einen bestimmten Port auf jedem Node des Clusters
verfügbar, und der Verkehr an diesen Port wird an die entsprechenden
Pods weitergeleitet.
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: webapp
ports:
- port: 80
targetPort: 8080
nodePort: 30007In diesem Fall wird der Service web-service auf Port 80
erstellt, der den Verkehr an Pods weiterleitet, die auf Port 8080
lauschen und das Label app: webapp haben. Der Verkehr kann
diesen Service über <Node-IP>:30007 erreichen, wobei
<Node-IP> die IP-Adresse eines beliebigen Knotens im
Cluster ist.
Für Anwendungen, die eine nahtlose Integration mit Cloud-Providern
wie AWS, GCP oder Azure benötigen, bietet sich ein
LoadBalancer-Service an. Dieser Service-Typ weist den
Cloud-Provider an, einen externen Load Balancer zu erstellen, der den
Verkehr an den Kubernetes Service weiterleitet.
apiVersion: v1
kind: Service
metadata:
name: externer-service
spec:
type: LoadBalancer
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 8080Der LoadBalancer-Service wird automatisch eine externe
IP-Adresse vom Cloud-Provider erhalten, die von außerhalb des Clusters
verwendet werden kann, um auf die webapp-Anwendung
zuzugreifen.
Der ExternalName-Service ist ein spezieller Service-Typ,
der es ermöglicht, einen Alias zu definieren, der auf einen DNS-Namen
zeigt. Dies ist nützlich, wenn ein Kubernetes-Service auf einen Dienst
verweisen soll, der außerhalb des Kubernetes-Clusters gehostet wird.
apiVersion: v1
kind: Service
metadata:
name: externer-datenbank-service
spec:
type: ExternalName
externalName: db.beispiel.comHier verweist der externer-datenbank-service auf eine
Datenbank, die unter db.beispiel.com gehostet wird.
Anwendungen innerhalb des Clusters können diesen Service nutzen, um mit
der externen Datenbank zu kommunizieren, als wäre sie Teil des
Clusters.
Services in Kubernetes ermöglichen den Zugriff auf Anwendungen, die in Pods ausgeführt werden. Die Konfiguration eines Services umfasst Selektoren, die festlegen, welche Pods vom Service bedient werden. Im Folgenden wird die Einrichtung von Services zusammen mit den Pods dargestellt, die diese Services erfüllen.
Stellen Sie sich vor, Sie haben eine Anwendung mit einem Backend, das
über einen ClusterIP-Service innerhalb des Clusters
erreichbar sein soll.
apiVersion: v1
kind: Pod
metadata:
name: backend-pod-1
labels:
app: backend
spec:
containers:
- name: backend-container
image: backend-image:1.0
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: backend-pod-2
labels:
app: backend
spec:
containers:
- name: backend-container
image: backend-image:1.0
ports:
- containerPort: 80apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 80In diesem Beispiel wird der backend-service so
konfiguriert, dass er alle Anfragen auf Port 80 an Pods weiterleitet,
die mit app: backend gelabelt sind.
Für den Zugriff auf eine Frontend-Anwendung von außerhalb des
Kubernetes-Clusters verwenden Sie einen
NodePort-Service.
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod-1
labels:
app: frontend
spec:
containers:
- name: frontend-container
image: frontend-image:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod-2
labels:
app: frontend
spec:
containers:
- name: frontend-container
image: frontend-image:1.0
ports:
- containerPort: 8080apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: NodePort
selector:
app: frontend
ports:
- port: 80
targetPort: 8080
nodePort: 30007Hier werden Anfragen an den frontend-service auf Port 80
von jedem Node im Cluster an die Ports 8080 der mit
app: frontend gelabelten Pods weitergeleitet.
Für eine Webanwendung, die öffentlich zugänglich sein soll, kann ein
LoadBalancer-Service konfiguriert werden.
apiVersion: v1
kind: Pod
metadata:
name: webapp-pod-1
labels:
app: webapp
spec:
containers:
- name: webapp-container
image: webapp-image:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: webapp-pod-2
labels:
app: webapp
spec:
containers:
- name: webapp-container
image: webapp-image:1.0
ports:
- containerPort: 8080apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: LoadBalancer
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 8080Der webapp-service nutzt den Typ
LoadBalancer, um eine öffentliche IP-Adresse
bereitzustellen, unter der die mit app: webapp gelabelten
Pods auf Port 8080 erreichbar sind.
In allen diesen Beispielen bilden die Services eine Brücke zwischen den Anforderungen der Nutzer und den dynamisch verwalteten Pods. Sie bieten einen stabilen Zugangspunkt, selbst wenn sich die hinter den Services liegenden Pods verändern, da die Services die Anfragen nahtlos an die aktuellen Pod-Instanzen weiterleiten. Durch die Verwendung von Services wird sichergestellt, dass die Kommunikation zu den Anwendungen auch dann bestehen bleibt, wenn die Pods neu gestartet werden und dadurch neue IP-Adressen erhalten. Services stellen somit die zentrale Komponente in der Netzwerkarchitektur von Kubernetes dar, indem sie einen stabilen und zuverlässigen Mechanismus für die Service-Discovery und Lastverteilung bieten.
Ein ClusterIP Service kann verwendet werden, um einen
Nginx-Webserver innerhalb eines Kubernetes-Clusters erreichbar zu
machen. Hier ist ein konkretes Beispiel für die Konfiguration eines
solchen Szenarios:
Erstellen Sie zunächst die Definition für einen Nginx Pod. Dieser Pod wird über ein Label verfügen, das vom Service-Selektor verwendet wird, um den Traffic an diesen Pod weiterzuleiten.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80Nachdem der Pod definiert ist, wird ein ClusterIP
Service erstellt, der Netzwerkzugriff auf den Nginx Pod über einen
stabilen internen Cluster-IP ermöglicht.
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80Dieser Service leitet Anfragen, die an den ClusterIP auf Port 80
eingehen, an den Port 80 des Nginx Pods, der durch den Selektor
app: nginx identifiziert wird, weiter. Der Service ist
innerhalb des Clusters über den Namen nginx-service
erreichbar, welcher durch den DNS-Dienst von Kubernetes aufgelöst
wird.