Kubernetes ist eine leistungsstarke Container-Orchestrierungsplattform, aber um ihr volles Potenzial zu nutzen, ist es wichtig, ihre Kernkomponenten zu verstehen, wobei Pods und Services grundlegende Rollen spielen. In diesem Artikel werden wir darauf eingehen, was sie sind und wie sie zusammenarbeiten, um den Zugriff auf Anwendungen innerhalb eines Kubernetes-Clusters freizulegen und zu verwalten.
Was ist ein Pod?
Pods sind die kleinsten bereitstellbaren Recheneinheiten, die Sie in Kubernetes erstellen und verwalten können.
Bevor wir einen Pod erstellen, überprüfen wir die verfügbaren API-Ressourcen in Ihrem Kubernetes-Cluster; Sie können den Befehl kubectl api-resources
verwenden. Dieser Befehl listet die von dem Kubernetes-API-Server unterstützten API-Ressourcen auf, einschließlich ihrer Kurznamen, API-Gruppen und ob sie einem Namespace zugeordnet sind oder nicht. Dies ist nützlich, um die Fähigkeiten Ihres Clusters zu verstehen, insbesondere wenn Sie mit benutzerdefinierten Ressourcen arbeiten oder neue Kubernetes-Funktionen erkunden. Der Befehl kubectl explain
ergänzt dies, indem er detaillierte Informationen zu einzelnen Ressourcen bereitstellt.
Erstellen wir eine grundlegende Pod-Konfigurationsdatei für einen Pod, der einen einfachen Nginx-Container ausführt.
Erstellen Sie eine Datei mit dem Namen nginx-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Hier ist eine kurze Erklärung der verwendeten Begriffe:
- apiVersion: v1: Gibt die API-Version an.
- kind: Pod: Zeigt an, dass es sich bei dieser Konfiguration um einen Pod handelt.
- metadata:name: Der Name des Pods.
- Metadaten: Labels: Schlüssel-Wert-Paare, die zur Organisation und Auswahl des Pods verwendet werden können.
- Spezifikation:Container: Eine Liste von Containern, die im Pod ausgeführt werden sollen.
- Spezifikation:Container:Name: Der Name des Containers.
- Spezifikation:Container:Abbildung: Das Container-Abbild, das verwendet werden soll (in diesem Fall das neueste Nginx-Abbild).
- Spezifikation:Container:Ports: Die Ports, die vom Container freigegeben werden sollen.
Verwenden Sie kubectl
, um die Konfigurationsdatei anzuwenden und den Pod zu erstellen:
kubectl apply -f nginx-pod.yaml
Überprüfen Sie den Status des Pods, um sicherzustellen, dass er erstellt wurde und läuft:
kubectl get pods
Sie sollten eine Ausgabe sehen, die ähnlich aussieht wie diese:
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 10s
Als nächstes löschen Sie den Pod:
kubectl delete pod nginx-pod
Die Ausgabe sollte ähnlich aussehen wie folgt:
kubectl get pod
No resources found in default namespace.
Was ist ein Dienst?
Das Erstellen eines Dienstes für einen Nginx-Pod in Kubernetes ermöglicht es Ihnen, die Nginx-Anwendung freizugeben und innerhalb oder außerhalb des Clusters zugänglich zu machen. Hier ist eine schrittweise Anleitung zur Erstellung eines Dienstes für einen Nginx-Pod.
Um sicherzustellen, dass ein Nginx-Pod ausgeführt wird, erstellen Sie, falls nicht bereits vorhanden, eine YAML-Datei mit dem Namen nginx-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Wenden Sie die Pod-Konfiguration an:
kubectl apply -f nginx-pod.yaml
Erstellen Sie eine YAML-Datei mit dem Namen nginx-service.yaml
, um den Service zu definieren:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Hier sind einige Dinge zu beachten:
- selector: Ein Label-Selektor zum Abgleichen des Nginx-Pods.
- app: nginx: Dies sollte dem Label im Nginx-Pod entsprechen.
- type: ClusterIP: Der Typ des Services. ClusterIP macht den Service nur innerhalb des Clusters zugänglich. Sie können auch NodePort oder LoadBalancer verwenden, um den Service extern verfügbar zu machen.
Wenden Sie die Service-Konfiguration mit kubectl
an:
kubectl apply -f nginx-service.yaml
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.96.0.1 <none> 80/TCP 10s
Da der Service vom Typ ClusterIP ist, ist er nur innerhalb des Clusters zugänglich. Um von außerhalb des Clusters darauf zuzugreifen, können Sie den Servicetyp in NodePort oder LoadBalancer ändern.
Um den Service extern über NodePort
verfügbar zu machen, ändern Sie die nginx-service.yaml
-Datei:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007 # Specify a node port in the range 30000-32767 (optional)
type: NodePort
Wenden Sie die aktualisierte Service-Konfiguration an:
kubectl apply -f nginx-service.yaml
Sie können nun auf die Nginx-Anwendung über die IP-Adresse des Knotens und den Knotenport zugreifen (z.B. http://<knoten-ip>:30007).
Multi-Container-Pods
Die Verwendung eines einzelnen Containers pro Pod bietet maximale Granularität und Entkopplung. Es gibt jedoch Szenarien, in denen es vorteilhaft ist, mehrere Container, manchmal als Composite-Container bezeichnet, innerhalb eines einzelnen Pods bereitzustellen. Diese sekundären Container können verschiedene Aufgaben übernehmen: das Handling von Protokollen oder die Verbesserung des primären Containers (Sidecar-Konzept), das Agieren als Proxy für externe Systeme (Ambassador-Konzept) oder das Anpassen von Daten an ein externes Format (Adapter-Konzept). Diese sekundären Container ergänzen den primären Container, indem sie Aufgaben ausführen, die er nicht übernimmt.
Im Folgenden finden Sie ein Beispiel für eine Kubernetes-Pod-Konfiguration, die einen primären Container enthält, der einen Nginx-Server ausführt, und einen sekundären Container, der als Sidecar für das Protokollieren dient. Der Sidecar-Container verwendet einen einfachen Protokollcontainer wie BusyBox, um zu demonstrieren, wie er die Nginx-Zugriffsprotokolle verfolgen kann.
apiVersion: v1
kind: Pod
metadata:
name: nginx-with-logging-sidecar
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
- name: log-sidecar
image: busybox:latest
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}
Dann werden Sie Folgendes tun:
- Speichern Sie die YAML-Konfiguration in einer Datei, z. B.
nginx-with-logging-sidecar.yaml
. - Wenden Sie die Konfiguration mit
kubectl:kubectl apply -f nginx-with-logging-sidecar.yaml
an. - Überprüfen Sie, ob der Pod läuft:
kubectl get pods
. - Überprüfen Sie die Protokolle des Sidecar-Containers, um die Nginx-Zugriffsprotokolle zu sehen:
kubectl logs -f <pod-name> -c log-sidecar
.
Indem Sie diesen Schritten folgen, werden Sie das vorhandene Pod löschen und die neue Konfiguration anwenden, um ein Pod mit einem Nginx-Container und einem Sidecar-Container für das Logging einzurichten. Dadurch wird sichergestellt, dass die neue Konfiguration aktiv ist und in Ihrem Kubernetes-Cluster läuft.
Mehrcontainer-Pods in Kubernetes bieten mehrere Vorteile, die eine flexiblere und effizientere Bereitstellung und Verwaltung von Anwendungen ermöglichen.
Mehrcontainer-Pod-Muster
Sidecar-Muster
Sidecar-Container können die primäre Anwendung verbessern, indem sie Hilfsfunktionen wie Logging, Konfigurationsverwaltung oder Proxying bereitstellen. Dieses Muster hilft dabei, die Funktionalität zu erweitern, ohne den primären Container zu ändern. Ein Sidecar-Container kann das Logging übernehmen, indem er Protokolle von dem Hauptanwendungscontainer sammelt und weiterleitet.
Ambassador-Muster
Ambassador-Container fungieren als Proxy, der die Kommunikation zwischen der primären Anwendung und externen Diensten verwaltet. Dadurch kann die Integration und Konfiguration vereinfacht werden. Ein Ambassador-Container könnte die SSL-Terminierung oder API-Gateway-Funktionen übernehmen.
Das Ambassador-Muster beinhaltet die Verwendung eines Sidecar-Containers zur Verwaltung der Kommunikation zwischen der primären Anwendung und externen Diensten. Dieses Muster kann Aufgaben wie Proxying, Lastverteilung oder das Verwalten sicherer Verbindungen übernehmen und damit die Komplexität vom primären Anwendungscontainer abstrahieren.
- Primärer Anwendungscontainer: Ein einfacher Webserver, der HTTP-Anfragen stellt
- Ambassador-Container: Envoy-Proxy konfiguriert zur Verwaltung von Anfragen an die externe API
apiVersion: v1
kind: Pod
metadata:
name: app-with-ambassador
spec:
containers:
- name: web-app
image: python:3.8-slim
command: ["python", "-m", "http.server", "8000"]
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
- name: envoy-proxy
image: envoyproxy/envoy:v1.18.3
args: ["-c", "/etc/envoy/envoy.yaml"]
ports:
- containerPort: 8080
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
volumes:
- name: config-volume
configMap:
name: envoy-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-config
data:
envoy.yaml: |
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: external_service
http_filters:
- name: envoy.filters.http.router
clusters:
- name: external_service
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: external_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.example.com
port_value: 80
Dieses Beispiel demonstriert das Botschafter-Muster in Kubernetes, bei dem ein Envoy-Proxy als Vermittler fungiert, um die externe Kommunikation für den primären Anwendungscontainer zu verwalten. Dieses Muster hilft dabei, Kommunikationskomplexitäten zu abstrahieren und die Modularität sowie die Wartbarkeit zu verbessern.
Adapter-Muster
Adaptercontainer können Daten zwischen der primären Anwendung und externen Systemen modifizieren oder transformieren, um Kompatibilität und Integration sicherzustellen. Zum Beispiel kann ein Adaptercontainer Logdaten neu formatieren, um den Anforderungen eines externen Protokollierungsdienstes zu entsprechen.
Das Adaptermuster in Kubernetes beinhaltet die Verwendung eines Sidecar-Containers zur Datenübertragung zwischen dem primären Anwendungscontainer und externen Systemen. Dies kann nützlich sein, wenn die primäre Anwendung Daten in einem spezifischen Format benötigt, das sich vom bereitgestellten Format externer Systeme unterscheidet.
Angenommen, Sie haben einen primären Anwendungscontainer, der Protokolle in einem benutzerdefinierten Format generiert. Diese Protokolle müssen an einen externen Protokollierungsdienst gesendet werden, der Protokolle in einem spezifischen standardisierten Format erfordert. Ein Adaptercontainer kann verwendet werden, um die Protokolldaten in das erforderliche Format zu transformieren, bevor sie an den externen Dienst gesendet werden.
- Primärer Anwendungscontainer: Eine einfache Anwendung, die Protokolle in einem benutzerdefinierten Format schreibt.
- Adaptercontainer: Ein Container, der die benutzerdefinierten Protokolle liest, sie in JSON-Format umwandelt und an einen externen Protokollierungsdienst sendet.
apiVersion: v1
kind: Pod
metadata:
name: app-with-adapter
spec:
containers:
- name: log-writer
image: busybox
command: ["sh", "-c", "while true; do echo \"$(date) - Custom log entry\" >> /var/log/custom/app.log; sleep 5; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: log-adapter
image: busybox
command: ["sh", "-c", "tail -f /var/log/custom/app.log | while read line; do echo \"$(echo $line | sed 's/ - / - {\"timestamp\": \"/;s/$/\"}/')\" >> /var/log/json/app.json; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: json-logs
mountPath: /var/log/json
- name: log-sender
image: busybox
command: ["sh", "-c", "while true; do cat /var/log/json/app.json | grep -v '^$' | while read line; do echo \"Sending log to external service: $line\"; done; sleep 10; done"]
volumeMounts:
- name: json-logs
mountPath: /var/log/json
volumes:
- name: shared-logs
emptyDir: {}
- name: json-logs
emptyDir: {}
Dieses Beispiel demonstriert das Adapter-Muster in Kubernetes, bei dem ein Adapter-Container Daten vom primären Anwendungscontainer in das erforderliche Format umwandelt, bevor er sie an ein externes System sendet. Dieses Muster hilft dabei, Anwendungen mit externen Diensten zu integrieren, indem Datenformat-Transformationen im Sidecar-Container behandelt werden.
Zusammenfassung
Zusammenfassend, Pods:
- Sind die kleinsten bereitstellbaren Einheiten in Kubernetes.
- Stellen eine einzelne Instanz eines laufenden Prozesses dar.
- Können einen oder mehrere Container enthalten.
Services:
- Stellen eine stabile IP-Adresse und DNS-Namen für den Zugriff auf Pods bereit.
- Ermöglichen Lastenausgleich über eine Gruppe von Pods.
- Erleichtern die Dienstsuche innerhalb des Clusters.
Source:
https://dzone.com/articles/the-ultimate-guide-to-kubernetes-pods-and-services