Ajouter un conteneur Sidecar

KubernetesBeginner
Pratiquer maintenant

Introduction

Un conteneur sidecar s'exécute dans le même Pod qu'un conteneur d'application et assiste cette dernière pendant son exécution. Cela diffère d'un conteneur d'initialisation (init container), qui doit impérativement se terminer avant le démarrage de l'application. Les sidecars sont couramment utilisés pour l'expédition de journaux (log shipping), le proxying, la synchronisation ou toute autre tâche auxiliaire devant partager le cycle de vie du Pod.

Dans ce laboratoire, vous allez créer un Pod multi-conteneurs composé d'un conteneur applicatif qui écrit des lignes de journal dans un volume partagé emptyDir, et d'un conteneur sidecar qui suit ce fichier. Vous inspecterez les deux conteneurs, lirez les journaux du sidecar, puis intégrerez ce même modèle de sidecar dans un modèle de déploiement (Deployment).

Préparer un espace de noms pour le Sidecar

Dans cette étape, vous allez préparer un espace de noms (namespace) propre pour pratiquer l'utilisation des sidecars.

Commencez dans /home/labex/project. Vous rédigerez un manifeste de Pod et un manifeste de déploiement dans ce répertoire.

mkdir -p /home/labex/project
cd /home/labex/project

Vérifiez que le serveur d'API Kubernetes est accessible. Si la machine virtuelle vient de démarrer et que le nœud n'est pas encore prêt, attendez quelques secondes et relancez la commande.

kubectl get nodes --request-timeout=5s

La sortie attendue inclut :

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Attendez que le Pod réseau du cluster soit prêt avant de créer des charges de travail.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Sortie attendue :

pod/calico-node-... condition met

Créez un espace de noms nommé ckad-prep-sidecar :

kubectl create namespace ckad-prep-sidecar

Définissez cet espace de noms comme contexte actuel :

kubectl config set-context --current --namespace=ckad-prep-sidecar

Confirmez l'espace de noms actuel :

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Sortie attendue :

ckad-prep-sidecar

Créer un Pod multi-conteneurs

Dans cette étape, vous allez créer un Pod contenant un conteneur d'application et un conteneur sidecar.

Les deux conteneurs montent le même volume emptyDir sur /var/log/shared. Le conteneur d'application écrit des lignes de journal dans /var/log/shared/app.log. Le conteneur sidecar s'exécute simultanément et utilise tail -f pour diffuser ce fichier. La commande touch crée le fichier avant que tail -f ne démarre, permettant ainsi au sidecar d'attendre en toute sécurité, même si l'application n'a pas encore écrit sa première ligne.

Créez sidecar-pod.yaml :

cat > sidecar-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
  labels:
    app: sidecar-demo
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: shared-logs
    emptyDir: {}
  containers:
  - name: app
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'i=1; while true; do echo "app-line-${i}" >> /var/log/shared/app.log; i=$((i+1)); sleep 2; done'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
  - name: log-sidecar
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'touch /var/log/shared/app.log; tail -n +1 -f /var/log/shared/app.log'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
EOF

Appliquez le manifeste :

kubectl apply -f sidecar-pod.yaml

Sortie attendue :

pod/sidecar-demo created

Attendez que le Pod soit prêt. Un Pod multi-conteneurs n'est considéré comme prêt que lorsque tous ses conteneurs sont prêts.

kubectl wait --for=condition=Ready pod/sidecar-demo --timeout=120s

Sortie attendue :

pod/sidecar-demo condition met

Listez les noms des conteneurs dans le Pod :

kubectl get pod sidecar-demo -o 'jsonpath={.spec.containers[*].name}{"\n"}'

Sortie attendue :

app log-sidecar

Inspecter la collaboration du Sidecar

Dans cette étape, vous allez confirmer que les deux conteneurs sont en cours d'exécution et que le sidecar diffuse bien le fichier journal de l'application.

Vérifiez d'abord l'état de préparation des conteneurs. La sortie affiche le nom de chaque conteneur et son état de préparation.

kubectl get pod sidecar-demo -o 'jsonpath={range .status.containerStatuses[*]}{.name}{" "}{.ready}{"\n"}{end}'

La sortie attendue inclut :

app true
log-sidecar true

Lisez les journaux du conteneur d'application. L'application n'écrit sur la sortie standard (stdout) que lorsque la commande shell démarre ; ses lignes répétées sont dirigées vers le fichier partagé.

kubectl logs sidecar-demo -c app --tail=5

Le conteneur d'application peut ne pas afficher les lignes répétées sur stdout. La preuve importante se trouve dans le fichier partagé et dans les journaux du sidecar.

Lisez le fichier partagé via le conteneur d'application :

kubectl exec sidecar-demo -c app -- sh -c 'tail -n 3 /var/log/shared/app.log'

La sortie attendue inclut les lignes de journal de l'application :

app-line-...
app-line-...
app-line-...

Lisez maintenant les journaux du sidecar. Comme le sidecar suit le même fichier, ses journaux doivent inclure le même type de lignes.

kubectl logs sidecar-demo -c log-sidecar --tail=3

La sortie attendue inclut :

app-line-...
app-line-...
app-line-...

Ajouter le modèle Sidecar à un déploiement

Dans cette étape, vous allez intégrer le modèle de sidecar dans un modèle de déploiement (Deployment).

Les Pods isolés sont utiles pour l'apprentissage, mais les applications s'exécutent généralement via des contrôleurs. Un déploiement peut créer des Pods de remplacement, et chaque Pod de remplacement inclura à la fois le conteneur d'application et le conteneur sidecar définis dans le modèle.

Créez sidecar-deployment.yaml :

cat > sidecar-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sidecar-worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sidecar-worker
  template:
    metadata:
      labels:
        app: sidecar-worker
    spec:
      terminationGracePeriodSeconds: 0
      volumes:
      - name: shared-logs
        emptyDir: {}
      containers:
      - name: app
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'i=1; while true; do echo "worker-line-${i}" >> /var/log/shared/worker.log; i=$((i+1)); sleep 2; done'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
      - name: log-sidecar
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'touch /var/log/shared/worker.log; tail -n +1 -f /var/log/shared/worker.log'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
EOF

Appliquez le déploiement :

kubectl apply -f sidecar-deployment.yaml

Sortie attendue :

deployment.apps/sidecar-worker created

Attendez que le déploiement soit disponible :

kubectl wait --for=condition=Available deployment/sidecar-worker --timeout=120s

Sortie attendue :

deployment.apps/sidecar-worker condition met

Recherchez le Pod créé par le déploiement :

worker_pod="$(kubectl get pods -l app=sidecar-worker -o 'jsonpath={.items[0].metadata.name}')"
echo "$worker_pod"

La sortie attendue affiche un nom de Pod généré :

sidecar-worker-...

Lisez les journaux du sidecar depuis le Pod créé par le déploiement :

kubectl logs "$worker_pod" -c log-sidecar --tail=3

La sortie attendue inclut :

worker-line-...
worker-line-...
worker-line-...

Résumé

Vous avez créé un Pod multi-conteneurs avec un conteneur d'application et un conteneur sidecar, utilisé un volume emptyDir pour partager un fichier journal, confirmé que les deux conteneurs fonctionnent ensemble, et déplacé ce même modèle de sidecar dans un modèle de déploiement. Vous savez désormais quand utiliser un sidecar : il sert à assister l'application pendant que celle-ci est en cours d'exécution.