Auf dieser Seite werden Kubernetes-Dienste und ihre Verwendung in Google Kubernetes Engine (GKE) beschrieben. Es gibt verschiedene Arten von Services, mit denen Sie eine Reihe von Pod-Endpunkten in einer einzigen Ressource zusammenfassen können. Informationen zum Erstellen eines Diensts finden Sie unter Anwendungen über Dienste freigeben.
Was ist ein Kubernetes-Service?
Ein Dienst wird dazu eingesetzt, eine Gruppe von Pod-Endpunkten in einer einzigen Ressource zu gruppieren. Sie können verschiedene Zugriffsmöglichkeiten für die Gruppierung konfigurieren. Standardmäßig erhalten Sie eine stabile Cluster-IP-Adresse, über die Clients innerhalb des Clusters Pods im Service kontaktieren können. Ein Client sendet eine Anfrage an die stabile IP-Adresse, die anschließend an einen der Pods im Dienst weitergeleitet wird.
Die Mitglieds-Pods eines Diensts werden mithilfe eines Selektors ermittelt. Damit ein Pod Mitglied des Diensts sein kann, muss der Pod über alle im Selektor angegebenen Labels verfügen. Ein Label ist ein beliebiges Schlüssel/Wert-Paar, das an ein Objekt angehängt ist.
Das folgende Dienstmanifest hat einen Selektor, mit dem zwei Labels festgelegt werden. Im Feld selector
wird angegeben, dass jeder Pod mit den beiden Labels app: metrics
und Label department:engineering
ein Mitglied dieses Dienstes ist.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: metrics
department: engineering
ports:
...
Vorteile eines Kubernetes-Service
In einem Kubernetes-Cluster hat jeder Pod eine interne IP-Adresse. Die Pods wechseln jedoch häufig und ihre IP-Adressen ändern sich. Daher ist es nicht sinnvoll, IP-Adressen von Pods direkt zu verwenden. Ein Dienst bietet Ihnen eine stabile IP-Adresse, die für die gesamte Lebensdauer des Diensts gilt, auch wenn sich die IP-Adressen der Mitglieds-Pods ändern.
Außerdem bieten Dienste eine Load-Balancing-Funktion, sodass Clients eine einzelne, stabile IP-Adresse aufrufen und ihre Anfragen auf die Pods verteilt werden, die Mitglieder des Diensts sind.
Arten von Kubernetes-Services
Es gibt fünf Servicetypen:
ClusterIP (Standard): Interne Clients senden Anfragen an eine stabile interne IP-Adresse.
NodePort: Clients senden Anforderungen an die IP-Adresse eines Knotens über einen oder mehrere
nodePort
-Werte, die vom Dienst angegeben werden.LoadBalancer: Clients senden Anfragen an die IP-Adresse eines Netzwerk-Load-Balancers.
ExternalName: Interne Clients verwenden den DNS-Namen eines Diensts als Alias für einen externen DNS-Namen.
Headless: Wenn Sie eine Pod-Gruppierung wünschen, aber keine stabile IP-Adresse benötigen, können Sie einen monitorlosen Dienst verwenden.
Der Typ NodePort
ist eine Erweiterung des Typs ClusterIP
. Ein Dienst des Typs NodePort
hat also eine Cluster-IP-Adresse.
Der Typ LoadBalancer
ist eine Erweiterung des Typs NodePort
. Ein Dienst vom Typ LoadBalancer
hat also eine Cluster-IP-Adresse und einen oder mehrere nodePort
-Werte.
Dienste vom Typ ClusterIP
Wenn Sie einen Dienst vom Typ ClusterIP
erstellen, erstellt Kubernetes eine stabile IP-Adresse, auf die von Knoten im Cluster aus zugegriffen werden kann.
Hier ist ein Manifest für einen Dienst vom Typ ClusterIP:
apiVersion: v1
kind: Service
metadata:
name: my-cip-service
spec:
selector:
app: metrics
department: sales
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 8080
Mithilfe von kubectl apply -f [MANIFEST_FILE]
können Sie den Dienst erstellen. Nachdem Sie den Dienst erstellt haben, können Sie kubectl get service
verwenden, um die stabile IP-Adresse anzuzeigen:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
my-cip-service ClusterIP 10.11.247.213 none 80/TCP
Clients im Cluster rufen den Dienst über die Cluster-IP-Adresse und den TCP-Port auf, der im Feld port
des Dienstmanifests angegeben ist. Die Anfrage wird an einen der Mitglieds-Pods an dem TCP-Port weitergeleitet, der im Feld targetPort
angegeben ist. Im obigen Beispiel ruft ein Client den Dienst unter 10.11.247.213
am TCP-Port 80 auf. Die Anfrage wird über TCP-Port 8080 an einen der Mitglieds-Pods weitergeleitet. Der Mitglieds-Pod muss über einen Container verfügen, der TCP-Port 8080 überwacht. Wenn kein Container Port 8080 überwacht, wird für die Clients die Meldung "Verbindung fehlgeschlagen" oder "Die Website ist nicht erreichbar" angezeigt.
Dienste vom Typ NodePort
Wenn Sie einen Dienst vom Typ NodePort
erstellen, erhalten Sie in Kubernetes den Wert nodePort
. Anschließend kann auf den Dienst zugegriffen werden, indem die IP-Adresse eines beliebigen Knotens zusammen mit dem Wert nodePort
verwendet wird.
Dies ist ein Manifest für einen Dienst vom Typ NodePort
:
apiVersion: v1
kind: Service
metadata:
name: my-np-service
spec:
selector:
app: products
department: sales
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 8080
Nachdem Sie den Dienst erstellt haben, können Sie kubectl get service -o yaml
verwenden, um seine Spezifikation und den Wert nodePort
anzusehen.
spec:
clusterIP: 10.11.254.114
externalTrafficPolicy: Cluster
ports:
- nodePort: 32675
port: 80
protocol: TCP
targetPort: 8080
Externe Clients rufen den Dienst auf, indem sie die externe IP-Adresse eines Knotens zusammen mit dem durch nodePort
angegebenen TCP-Port verwenden. Die Anfrage wird an einen der Mitglieds-Pods am TCP-Port weitergeleitet, der im Feld targetPort
angegeben ist.
Angenommen, die externe IP-Adresse eines der Clusterknotens lautet 203.0.113.2
. Für das obige Beispiel ruft der externe Client den Dienst unter 203.0.113.2
über TCP-Port 32675 auf. Die Anfrage wird über TCP-Port 8080 an einen der Mitglieds-Pods weitergeleitet. Dafür muss der Mitglieds-Pod einen Container haben, der TCP-Port 8080 überwacht.
Der Diensttyp NodePort
ist eine Erweiterung des Diensttyps ClusterIP
. Interne Clients haben also zwei Möglichkeiten, den Service aufzurufen:
clusterIP
undport
verwenden- IP-Adresse eines Knotens und
nodePort
verwenden
Für einige Clusterkonfigurationen verwendet der externe Anwendungs-Load-Balancer einen Dienst vom Typ NodePort
.
Ein externer Anwendungs-Load-Balancer ist ein Proxyserver und unterscheidet sich dadurch grundlegend von einem externen Passthrough-Netzwerk-Load-Balancer. Informationen hierzu finden Sie im Abschnitt Dienst vom Typ LoadBalancer.
Dienst vom Typ LoadBalancer
Weitere Informationen zu Diensten vom Typ LoadBalancer finden Sie unter Konzepte des LoadBalancer-Dienstes.
Dienste vom Typ ExternalName
Ein Dienst vom Typ ExternalName
stellt einen internen Alias für einen externen DNS-Namen bereit. Interne Clients senden Anfragen unter Verwendung des internen DNS-Namens und die Anfragen werden an den externen Namen umgeleitet.
Dies ist ein Manifest für einen Dienst vom Typ ExternalName
:
apiVersion: v1
kind: Service
metadata:
name: my-xn-service
spec:
type: ExternalName
externalName: example.com
Wenn Sie einen Dienst erstellen, erzeugt Kubernetes einen DNS-Namen, den interne Clients verwenden können, um den Dienst aufzurufen. Im obigen Beispiel lautet der DNS-Name "my-xn-service.default.svc.cluster.local". Wenn ein interner Client eine Anfrage an "my-xn-service.default.svc.cluster.local" sendet, wird die Anfrage an "example.com" umgeleitet.
Der Diensttyp ExternalName
unterscheidet sich grundlegend von den anderen Diensttypen. Tatsächlich entspricht ein Dienst des Typs ExternalName
nicht der Definition von Diensten, die zu Beginn dieses Themas angegeben wurde. Ein Dienst vom Typ ExternalName
ist nicht mit einer Gruppe von Pods verknüpft und hat keine stabile IP-Adresse. Stattdessen stellt ein Dienst vom Typ ExternalName
eine Zuordnung von einem internen zu einem externen DNS-Namen dar.
Headless Service
Ein monitorloser (Headless) Service ist ein Kubernetes-Diensttyp, der keine Cluster-IP-Adresse zuweist. Stattdessen verwendet ein Dienst ohne Cluster-IP das DNS, um die IP-Adressen der Pods zu veröffentlichen, die mit dem Dienst verknüpft sind. Auf diese Weise können Sie eine direkte Verbindung zu den Pods herstellen, statt einen Proxy zu verwenden.
Headless-Dienste sind für eine Vielzahl von Szenarien nützlich, z. B.:
Load Balancing über Pods hinweg: Sie können mit headless Services das Load Balancing über Pods hinweg durchführen. Erstellen Sie dazu einen Dienst mit einem Selektor, der mit den Pods übereinstimmt, für die Sie das Load Balancing aktivieren möchten. Der Dienst verteilt den Traffic dann gleichmäßig auf alle Pods, die der Auswahl entsprechen.
Diensterkennung: Sie können einen headless-Dienst verwenden, um die Diensterkennung zu implementieren. Erstellen Sie dazu einen Dienst mit einem Namen und einer Auswahl. Der DNS-Eintrag für den headless-Dienst enthält alle IP-Adressen der Pods, die sich hinter dem Dienst befinden und der Auswahl entsprechen. Clients können diese DNS-Einträge nutzen, um die IP-Adressen der Pods zu finden, die mit dem Dienst verknüpft sind.
Direkter Podzugriff: Clients können eine direkte Verbindung zu den Pods herstellen, die mit einem headless Dienst verknüpft sind. Dies kann für Dienste nützlich sein, die direkten Zugriff auf die zugrunde liegenden Pods erfordern, z. B. Load Balancer und DNS-Server.
Flexibilität: Monitorlose Dienste können zum Erstellen einer Vielzahl verschiedener Topologien, darunter Load-Balancer, DNS-Server und verteilte Datenbanken, verwendet werden.
Wenn Sie spezielle Netzwerkanforderungen für Ihre Arbeitslasten haben, die nicht mit headless-Diensten mit Auswahlen erfüllt werden können, können Sie auch headless-Dienste ohne Auswahlen verwenden. Monitorlose Dienste sind ein nützliches Tool für den Zugriff auf Dienste, die sich nicht im Kubernetes-Cluster selbst befinden, da die Steuerungsebene keine EndpointSlice-Objekte erstellt. Weitere Informationen finden Sie unter Dienst ohne Selektoren.
Das folgende Beispiel ist ein Manifest für einen headless Dienst:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Nachdem Sie einen headless Dienst erstellt haben, können Sie die IP-Adressen der Pods ermitteln, die mit dem Dienst verknüpft sind, indem Sie das DNS abfragen. Der folgende Befehl listet beispielsweise die IP-Adressen der Pods auf, die dem nginx-Dienst zugeordnet sind:
dig +short nginx.default.svc.cluster.local
Weiteres Beispiel für die Kubernetes-Abfrageerweiterung:
dig +short +search nginx
Sie können einen monitorlosen Dienst mit einem einzigen Befehl erstellen. Monitorlose Dienste lassen sich einfach aktualisieren und skalieren.
kubectl create service clusterip my-svc --clusterip="None" --dry-run=client -o yaml > [file.yaml]
Dienstabstraktion
Ein Dienst ist kein Prozess, mit dem eine bestimmte Netzwerkschnittstelle überwacht wird. In diesem Sinne handelt es sich dabei um eine Abstraktion. Ein Teil der Abstraktion ist in den iptables-Regeln der Clusterknoten implementiert. Je nach Diensttyp werden andere Teile der Abstraktion entweder durch einen externen Passthrough-Netzwerk-Load-Balancer oder einen externer Anwendungs-Load-Balancer implementiert.
Beliebige Dienstports
Der Wert des Felds port
in einem Dienstmanifest ist beliebig. Der Wert von targetPort
ist dagegen nicht beliebig. Jeder Mitglieds-Pod muss einen Container haben, der targetPort
überwacht.
Dies ist ein Dienst vom Typ LoadBalancer
mit einem port
-Wert von 50.000:
apiVersion: v1
kind: Service
metadata:
name: my-ap-service
spec:
clusterIP: 10.11.241.93
externalTrafficPolicy: Cluster
ports:
- nodePort: 30641
port: 50000
protocol: TCP
targetPort: 8080
selector:
app: parts
department: engineering
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 203.0.113.200
Ein Client ruft den Dienst unter 203.0.113.200
über TCP-Port 50000 auf. Die Anfrage wird über TCP-Port 8080 an einen der Mitglieds-Pods weitergeleitet.
Mehrere Ports
Das Feld ports
eines Dienstes ist ein Array von ServicePort-Objekten. Das ServicePort-Objekt hat folgende Felder:
name
protocol
port
targetPort
nodePort
Wenn Sie mehr als einen ServicePort haben, muss jeder ServicePort einen eindeutigen Namen haben.
Dies ist ein Dienst vom Typ LoadBalancer
mit zwei ServicePort
-Objekten:
apiVersion: v1
kind: Service
metadata:
name: my-tp-service
spec:
clusterIP: 10.11.242.196
externalTrafficPolicy: Cluster
ports:
- name: my-first-service-port
nodePort: 31233
port: 60000
protocol: TCP
targetPort: 50000
- name: my-second-service-port
nodePort: 31081
port: 60001
protocol: TCP
targetPort: 8080
selector:
app: tests
department: engineering
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 203.0.113.201
Wenn ein Client den Dienst im obigen Beispiel unter 203.0.113.201
über TCP-Port 60000 aufruft, wird die Anfrage über TCP-Port 50000 an einen Mitglieds-Pod weitergeleitet. Erfolgt der Aufruf unter 203.0.113.201
jedoch über TCP-Port 60001, wird die Anfrage über TCP-Port 8080 an einen Mitglieds-Pod weitergeleitet.
Dafür muss jeder Mitglieds-Pod einen Container haben, der TCP-Port 50000 überwacht, und einen Container, der TCP-Port 8080 überwacht. Sie können entweder einen einzelnen Container mit zwei Threads verwenden oder zwei Container auf demselben Pod.
Dienstendpunkte
Wenn Sie einen Dienst erstellen, erzeugt Kubernetes ein Endpoints-Objekt, das denselben Namen wie der Dienst trägt. Kubernetes verwendet das Endpoints-Objekt, um nachzuverfolgen, welche Pods Mitglieder des Diensts sind.
Single-Stack- und Dual-Stack-Dienste
Sie können einen IPv6-Service vom Typ ClusterIP
oder NodePort
erstellen.
GKE unterstützt Dual-Stack-Dienste vom Typ LoadBalancer
während der Vorschau, die kein SLA und keinen technischen Support bietet.
Für jeden dieser Diensttypen können Sie die Felder ipFamilies
und ipFamilyPolicy
entweder als IPv4-, IPv6- oder als Dual-Stack-Dienst definieren.
Nächste Schritte
- Weitere Informationen zu Kubernetes-Services
- Anwendungen über Services freigeben
- StatefulSets
- Weitere Informationen zu Ingress