De Ultieme Gids voor Pods en Services in Kubernetes

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:

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:

Shell

 

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:

Shell

 

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:

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:

YAML

 

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
Shell

 

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:

YAML

 

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.

YAML

 

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
YAML

 

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.
YAML

 

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