Le Guide Ultime des Pods et Services dans Kubernetes

Kubernetes est une plateforme puissante d’orchestration de conteneurs, mais pour exploiter son plein potentiel, il est important de comprendre ses composants principaux, les pods et les services jouant des rôles fondamentaux. Dans cet article, nous plongerons dans ce qu’ils sont et comment ils travaillent ensemble pour exposer et gérer l’accès aux applications s’exécutant dans un cluster Kubernetes.

Qu’est-ce qu’un Pod?

Les pods sont les plus petites unités déployables de calcul que vous pouvez créer et gérer dans Kubernetes.

Avant de créer un pod, vérifions les ressources API disponibles dans votre cluster Kubernetes; vous pouvez utiliser la commande kubectl api-resources. Cette commande répertorie les ressources API prises en charge par le serveur API Kubernetes, y compris leurs noms courts, les groupes API et s’ils sont namespace ou non. Cela est utile pour comprendre les capacités de votre cluster, surtout lors de la manipulation de ressources personnalisées ou de l’exploration de nouvelles fonctionnalités de Kubernetes. La commande kubectl explain complète cela en fournissant des informations détaillées sur les ressources individuelles.

Créons un fichier de configuration de pod de base pour un pod exécutant un conteneur Nginx simple.

Créez un fichier nommé 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

Voici une brève explication des termes utilisés:

  • apiVersion: v1: Spécifie la version de l’API.
  • kind: Pod: Indique que cette configuration est pour un pod.
  • metadata:name: Le nom du pod.
  • métadonnées: étiquettes: Paires clé-valeur qui peuvent être utilisées pour organiser et sélectionner le pod.
  • spec:containers: Une liste de conteneurs qui s’exécuteront dans le pod.
  • spec:containers:name: Le nom du conteneur.
  • spec:containers:image: L’image du conteneur à utiliser (dans ce cas, la dernière image Nginx).
  • spec:containers:ports: Les ports à exposer depuis le conteneur.

Utilisez kubectl pour appliquer le fichier de configuration et créer le pod:

  • kubectl apply -f nginx-pod.yaml

Vérifiez le statut du pod pour vous assurer qu’il a été créé et qu’il fonctionne:

  • kubectl get pods

Vous devriez voir une sortie similaire à ceci:

Shell

 

NAME         READY   STATUS    RESTARTS    AGE
nginx-pod    1/1     Running   0           10s

Ensuite, supprimez le pod:

  • kubectl delete pod nginx-pod

La sortie devrait ressembler à ce qui suit:

Shell

 

kubectl get pod
No resources found in default namespace.

Qu’est-ce qu’un Service?

Créer un service pour un pod Nginx dans Kubernetes vous permet d’exposer l’application Nginx et de la rendre accessible à l’intérieur ou à l’extérieur du cluster. Voici un guide étape par étape pour créer un Service pour un pod Nginx.

Pour vous assurer que vous avez un pod Nginx en cours d’exécution, si ce n’est pas déjà le cas, créez un fichier YAML nommé 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

Appliquez la configuration du Pod:

Créez un fichier YAML nommé nginx-service.yaml pour définir le Service:

YAML

 

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
       targetPort: 80
  type: ClusterIP

Voici quelques points à noter:

  • sélecteur: Un sélecteur d’étiquette pour faire correspondre le pod Nginx.
  • app: nginx: Cela devrait correspondre à l’étiquette dans le pod Nginx.
  • type: ClusterIP: Le type de Service. ClusterIP rend le Service accessible uniquement à l’intérieur du cluster. Vous pouvez également utiliser NodePort ou LoadBalancer pour exposer le Service à l’extérieur.

Appliquez la configuration du Service en utilisant 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

Étant donné que le Service est de type ClusterIP, il est accessible uniquement à l’intérieur du cluster. Pour y accéder depuis l’extérieur du cluster, vous pouvez modifier le type de Service en NodePort ou LoadBalancer.

Pour exposer le Service à l’extérieur en utilisant NodePort, modifiez le fichier nginx-service.yaml:

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

Appliquez la configuration du Service mise à jour:

  • kubectl apply -f nginx-service.yaml

Vous pouvez désormais accéder à l’application Nginx en utilisant l’adresse IP du nœud et le port du nœud (par exemple, http://<node-ip>:30007).

Pods multi-conteneurs

L’utilisation d’un seul conteneur par pod offre une granularité et un découplage maximum. Cependant, il existe des scénarios où le déploiement de plusieurs conteneurs, parfois appelés conteneurs composites, au sein d’un seul pod est bénéfique. Ces conteneurs secondaires peuvent remplir divers rôles : gérer les journaux ou améliorer le conteneur principal (concept de sidecar), agir en tant que proxy vers des systèmes externes (concept d’ambassadeur) ou modifier les données pour les adapter à un format externe (concept d’adaptateur). Ces conteneurs secondaires viennent compléter le conteneur principal en effectuant des tâches qu’il ne gère pas.

Voici un exemple de configuration de pod Kubernetes qui inclut un conteneur principal exécutant un serveur Nginx et un conteneur secondaire agissant en tant que sidecar pour gérer les journaux. Le conteneur sidecar utilise un conteneur de journalisation simple comme BusyBox pour démontrer comment il peut suivre les journaux d’accès de Nginx.

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: {}

Vous ferez ensuite ce qui suit :

  • Enregistrez la configuration YAML dans un fichier, par exemple nginx-with-logging-sidecar.yaml
  • Appliquez la configuration en utilisant kubectl:kubectl apply -f nginx-with-logging-sidecar.yaml
  • Vérifiez que le pod est en cours d’exécution : kubectl get pods
  • Vérifiez les journaux du conteneur sidecar pour voir les journaux d’accès de Nginx : kubectl logs -f <nom-du-pod> -c log-sidecar.

En suivant ces étapes, vous supprimerez le Pod existant et appliquerez la nouvelle configuration, en configurant un Pod avec un conteneur Nginx et un conteneur sidecar pour le journalisation. Cela garantira que la nouvelle configuration est active et en cours d’exécution dans votre cluster Kubernetes.

Les pods multi-conteneurs dans Kubernetes offrent plusieurs avantages, permettant un déploiement et une gestion d’application plus flexibles et efficaces.

Modèles de Pod Multi-Conteneurs

Modèle Sidecar

Les conteneurs sidecar peuvent améliorer l’application principale en fournissant des fonctions auxiliaires telles que la journalisation, la gestion de la configuration ou le proxying. Ce modèle aide à étendre les fonctionnalités sans modifier le conteneur principal. Un conteneur sidecar peut gérer la journalisation en collectant et en transmettant les journaux du conteneur d’application principal.

Modèle Ambassadeur

Les conteneurs ambassadeur agissent comme un proxy, gérant la communication entre l’application principale et les services externes. Cela peut simplifier l’intégration et la configuration. Un conteneur ambassadeur peut gérer la terminaison SSL ou les fonctions de passerelle API.

Le modèle Ambassadeur implique l’utilisation d’un conteneur sidecar pour gérer la communication entre l’application principale et les services externes. Ce modèle peut gérer des tâches telles que le proxying, l’équilibrage de charge ou la gestion de connexions sécurisées, en abstrayant ainsi la complexité du conteneur d’application principal.

  • Conteneur d’Application Principale: Un simple serveur web qui effectue des requêtes HTTP
  • Conteneur Ambassadeur: Proxy Envoy configuré pour gérer les requêtes vers l’API externe
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

Cet exemple illustre le modèle Ambassador dans Kubernetes, où un proxy Envoy agit comme un intermédiaire pour gérer la communication externe pour le conteneur d’application principal. Ce modèle aide à abstraire les complexités de la communication et améliore la modularité et la maintenabilité.

Modèle Adaptateur

Les conteneurs adaptateurs peuvent modifier ou transformer des données entre l’application principale et les systèmes externes, garantissant la compatibilité et l’intégration. Par exemple, un conteneur adaptateur peut reformater les données de journalisation pour répondre aux exigences d’un service de journalisation externe.

Le modèle Adaptateur dans Kubernetes implique l’utilisation d’un conteneur sidecar pour transformer les données entre le conteneur d’application principal et les systèmes externes. Cela peut être utile lorsque l’application principale nécessite des données dans un format spécifique qui diffère du format fourni par ou requis par les systèmes externes.

Supposons que vous ayez un conteneur d’application principal qui génère des journaux dans un format personnalisé. Vous devez envoyer ces journaux à un service de journalisation externe qui exige des journaux dans un format standardisé spécifique. Un conteneur adaptateur peut être utilisé pour transformer les données de journalisation dans le format requis avant de les envoyer au service externe.

  • Conteneur d’Application Principal: Une application simple qui écrit des journaux dans un format personnalisé.
  • Conteneur Adaptateur: Un conteneur qui lit les journaux personnalisés, les transforme en format JSON et les envoie à un service de journalisation externe.
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: {}

Cet exemple démontre le modèle Adapter dans Kubernetes, où un conteneur d’adaptateur transforme les données du conteneur d’application principal au format requis avant de les envoyer à un système externe. Ce modèle aide à intégrer les applications avec des services externes en gérant les transformations de format de données au sein du conteneur sidecar.

Résumé

En résumé, les pods:

  • Sont les plus petites unités déployables dans Kubernetes.
  • Représentent une instance unique d’un processus en cours d’exécution.
  • P peuvent contenir un ou plusieurs conteneurs.

Les services:

  • Fournissent une adresse IP stable et un nom DNS pour accéder aux pods.
  • Permettent l’équilibrage de charge entre un ensemble de pods.
  • Facilitent la découverte de services au sein du cluster.

Source:
https://dzone.com/articles/the-ultimate-guide-to-kubernetes-pods-and-services