Kubernetes is een krachtig platform voor containerorkestratie, maar om het volledige potentieel te benutten, is het belangrijk om de kerncomponenten te begrijpen, waarbij pods en services fundamentele rollen spelen. In dit artikel duiken we in wat ze zijn en hoe ze samenwerken om toegang tot applicaties die draaien binnen een Kubernetes-cluster te exposeren en beheren.
Wat is een Pod?
Pods zijn de kleinste inzetbare eenheden van computing die je kunt creëren en beheren in Kubernetes.
Voordat we een pod creëren, laten we de beschikbare API-resources in je Kubernetes-cluster controleren; je kunt de kubectl api-resources
opdracht gebruiken. Deze opdracht geeft een lijst van de API-resources die door de Kubernetes API-server worden ondersteund, inclusief hun korte namen, API-groepen en of ze namespaced zijn of niet. Dit is nuttig voor het begrijpen van de mogelijkheden van je cluster, vooral wanneer je met aangepaste resources werkt of nieuwe Kubernetes-functies verkent. De kubectl explain
opdracht aanvult dit door gedetailleerde informatie te geven over individuele resources.
Laten we een basis pod-configuratiebestand maken voor een pod die een eenvoudige Nginx-container draait.
Maak een bestand met de naam 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 is een korte uitleg van de gebruikte termen:
- apiVersion: v1: Geeft de API-versie aan.
- kind: Pod: Geeft aan dat deze configuratie voor een pod is.
- metadata:name: De naam van de pod.
- metadata: labels: Sleutel-waardeparen die kunnen worden gebruikt om de pod te organiseren en te selecteren.
- spec:containers: Een lijst van containers die zullen draaien in de pod.
- spec:containers:name: De naam van de container.
- spec:containers:image: De containerafbeelding om te gebruiken (in dit geval, de nieuwste Nginx-afbeelding).
- spec:containers:ports: De poorten om bloot te stellen vanuit de container.
Gebruik kubectl
om het configuratiebestand toe te passen en de pod te maken:
kubectl apply -f nginx-pod.yaml
Controleer de status van de pod om ervoor te zorgen dat deze is aangemaakt en draait:
kubectl get pods
Je zou een uitvoer moeten zien die vergelijkbaar is met deze:
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 10s
Vervolgens, verwijder de pod:
kubectl delete pod nginx-pod
De uitvoer zou er ongeveer zo uit moeten zien:
kubectl get pod
No resources found in default namespace.
Wat is een Service?
Het creëren van een service voor een Nginx-pod in Kubernetes stelt je in staat om de Nginx-toepassing bloot te stellen en toegankelijk te maken binnen of buiten het cluster. Hier is een stapsgewijze handleiding voor het creëren van een Service voor een Nginx-pod.
Om ervoor te zorgen dat je een Nginx-pod draaiende hebt, als je er nog geen hebt, maak een YAML-bestand met de naam nginx-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Pas de Pod-configuratie toe:
Maak een YAML-bestand genaamd nginx-service.yaml
om de Service te definiëren:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Hier zijn een paar dingen om op te letten:
- selector: Een labelselector om de Nginx-pod te matchen.
- app: nginx: Dit moet overeenkomen met het label in de Nginx-pod.
- type: ClusterIP: Het type van de Service. ClusterIP maakt de Service alleen toegankelijk binnen de cluster. Je kunt ook NodePort of LoadBalancer gebruiken om de Service extern bloot te stellen.
Pas de Service-configuratie toe met kubectl
:
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
Aangezien de Service van het type ClusterIP is, is deze alleen toegankelijk binnen de cluster. Om er van buiten de cluster toegang toe te krijgen, kun je het Servicetype wijzigen in NodePort of LoadBalancer.
Om de Service extern bloot te stellen met NodePort
, wijzig het nginx-service.yaml
bestand:
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
Pas de bijgewerkte Service-configuratie toe:
kubectl apply -f nginx-service.yaml
Je kunt nu de Nginx-toepassing openen met het IP-adres van de node en de node-poort (bijv. http://<node-ip>:30007).
Multi-Container Pods
Het gebruik van één container per pod biedt maximale granulariteit en ontkoppeling. Er zijn echter scenario’s waarbij het implementeren van meerdere containers, soms aangeduid als samengestelde containers, binnen één pod voordelig is. Deze secundaire containers kunnen verschillende rollen vervullen: het afhandelen van logging of het verbeteren van de primaire container (sidecar concept), optreden als proxy naar externe systemen (ambassador concept), of gegevens aanpassen om te voldoen aan een extern formaat (adapter concept). Deze secundaire containers vullen de primaire container aan door taken uit te voeren die deze niet afhandelt.
Hieronder volgt een voorbeeld van een Kubernetes Pod-configuratie die een primaire container bevat die een Nginx-server uitvoert en een secundaire container die fungeert als sidecar voor het afhandelen van logging. De sidecar-container maakt gebruik van een eenvoudige logging-container zoals BusyBox om te demonstreren hoe het Nginx toegangslogs kan volgen.
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: {}
Vervolgens zul je het volgende doen:
- Sla de YAML-configuratie op in een bestand, bijvoorbeeld
nginx-with-logging-sidecar.yaml
. - Pas de configuratie toe met
kubectl: kubectl apply -f nginx-with-logging-sidecar.yaml
. - Controleer of de Pod actief is:
kubectl get pods
. - Bekijk de logs van de sidecar-container om de Nginx toegangslogs te zien:
kubectl logs -f <pod-naam> -c log-sidecar
.
Door deze stappen te volgen, zult u de bestaande Pod verwijderen en de nieuwe configuratie toepassen, waarbij een Pod wordt opgezet met een Nginx-container en een sidecar-container voor logging. Dit zorgt ervoor dat de nieuwe configuratie actief is en draait in uw Kubernetes-cluster.
Multi-container pods in Kubernetes bieden verschillende voordelen, waardoor meer flexibele en efficiënte toepassingsimplementatie en -beheer mogelijk zijn.
Multi-Container Pod Patronen
Sidecar-patroon
Sidecar-containers kunnen de primaire toepassing verbeteren door hulpfuncties te bieden zoals logging, configuratiebeheer of doorsturen. Dit patroon helpt de functionaliteit uit te breiden zonder de primaire container te wijzigen. Een sidecar-container kan logging afhandelen door logs van de hoofdtoepassingscontainer te verzamelen en door te sturen.
Ambassador-patroon
Ambassador-containers fungeren als een proxy en beheren communicatie tussen de primaire toepassing en externe services. Dit kan integratie en configuratie vereenvoudigen. Een ambassador-container kan bijvoorbeeld SSL-beëindiging of API-gatewayfuncties afhandelen.
Het Ambassador-patroon houdt in dat een sidecar-container wordt gebruikt om communicatie tussen de primaire toepassing en externe services te beheren. Dit patroon kan taken zoals proxying, load balancing of het beheren van beveiligde verbindingen afhandelen, waardoor de complexiteit wordt geabstraheerd van de primaire toepassingscontainer.
- Primaire Toepassingscontainer: Een eenvoudige webserver die HTTP-verzoeken uitvoert
- Ambassador-container: Envoy-proxy geconfigureerd om verzoeken naar de externe API te beheren
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
Dit voorbeeld toont het Ambassadeur patroon in Kubernetes, waar een Envoy proxy fungeert als tussenpersoon om externe communicatie voor de primaire toepassingscontainer te beheren. Dit patroon helpt bij het abstract maken van communicatiecomplexiteiten en verbetert modulariteit en onderhoudbaarheid.
Adapter Patroon
Adaptercontainers kunnen gegevens tussen de primaire toepassing en externe systemen aanpassen of transformeren, waardoor compatibiliteit en integratie worden gegarandeerd. Bijvoorbeeld kan een adaptercontainer loggegevens herformatteren om te voldoen aan de eisen van een extern loggingservice.
Het Adapter patroon in Kubernetes houdt in dat een sidecar-container wordt gebruikt om gegevens tussen de primaire toepassingscontainer en externe systemen te transformeren. Dit kan handig zijn wanneer de primaire toepassing gegevens nodig heeft in een specifiek formaat dat verschilt van het formaat dat door externe systemen wordt verstrekt of vereist.
Stel dat je een primaire toepassingscontainer hebt die logbestanden genereert in een aangepast formaat. Je moet deze logbestanden naar een extern loggingservice sturen dat logbestanden in een specifiek gestandaardiseerd formaat vereist. Een adaptercontainer kan worden gebruikt om de loggegevens te transformeren naar het vereiste formaat voordat ze naar de externe service worden verzonden.
- Primaire Toepassingscontainer: Een eenvoudige toepassing die logbestanden schrijft in een aangepast formaat.
- Adaptercontainer: Een container die de aangepaste logbestanden leest, deze omzet in JSON-formaat en ze naar een extern loggingservice verzendt.
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: {}
Dit voorbeeld demonstreert het Adapter-patroon in Kubernetes, waarbij een adaptercontainer gegevens van de primaire applicatiecontainer omzet naar het vereiste formaat voordat deze naar een extern systeem wordt verzonden. Dit patroon helpt bij het integreren van applicaties met externe services door gegevensformaten binnen de sidecar-container te verwerken.
Samenvatting
In samenvatting, pods:
- Zijn de kleinste inzetbare eenheden in Kubernetes.
- Stellen een enkele instantie van een draaiend proces voor.
- Kunnen één of meer containers bevatten.
Services:
- Bieden een stabiel IP-adres en DNS-naam voor toegang tot pods.
- Stellen load balancing mogelijk over een set van pods.
- Faciliteren service discovery binnen het cluster.
Source:
https://dzone.com/articles/the-ultimate-guide-to-kubernetes-pods-and-services