Aller au contenu

Lab 02 : Premiers Pods, Labels & Sélecteurs

Objectifs Pédagogiques :

  • Comprendre la structure atomique d'un Pod Kubernetes et son cycle de vie.
  • Maîtriser la génération de manifests déclaratifs YAML grâce à --dry-run=client -o yaml.
  • Injecter des variables d'environnement (env) et inspecter l'intérieur du conteneur (kubectl exec, logs).
  • Dimensionner les ressources système avec les Requests et Limits (CPU et mémoire vive).
  • Mettre en œuvre le pattern d'initialisation avec les InitContainers.
  • Exploiter les Labels et Selectors pour organiser et filtrer les composants applicatifs.
  • Constater les limites de résilience d'un Pod isolé (bare pod).

📌 Note Compatibilité OS :
Les commandes kubectl (kubectl apply, kubectl get, kubectl describe, kubectl exec, kubectl label) sont rigoureusement identiques sous Windows (PowerShell), Linux (Ubuntu) et macOS (Terminal).

💡 Modalités d'exécution (Au choix) :
* Option A (Recommandée - Confort DevOps Local) : Exécutez les commandes directement depuis votre terminal local avec votre kubectl et le kubeconfig configuré au Lab 00. Vous modifiez vos YAML directement dans votre IDE sans transfert !
* Option B (Secours - PC d'entreprise verrouillé) : Connectez-vous en SSH sur k8s-control (via MobaXterm ou terminal) : kubectl et tous les dossiers de TP sont déjà pré-déployés dans ~/labs/.


Contexte Métier

Le portail Horizon Stages doit démarrer par la mise en ligne d'une première version de son interface web statique. En tant qu'administrateur, vous devez déployer ce premier conteneur dans un Pod, encadrer ses besoins en ressources CPU/RAM, lui injecter ses paramètres d'exécution et l'étiqueter correctement pour que les équipes d'exploitation puissent l'identifier sans ambiguïté.

  • Image Docker du frontend : regaieg/campus:frontend-1.0.0
  • Port exposé par le conteneur : 8080 (Nginx unprivileged)

Exercice 1 : Déploiement Impératif vs Déclaratif

  1. Lancez un premier pod nommé frontend-test de manière impérative avec l'image regaieg/campus:frontend-1.0.0 sur le port 8080 :
    kubectl run frontend-test --image=regaieg/campus:frontend-1.0.0 --port=8080
    
  2. Observez l'état du pod jusqu'à ce qu'il passe au statut Running :
    kubectl get pods -w
    
  3. Supprimez ce pod de test :
    kubectl delete pod frontend-test
    

Exercice 2 : La Technique DevOps du --dry-run & Manifeste Déclaratif

En production, on n'écrit jamais de YAML à partir d'une page blanche. On utilise la commande kubectl run combinée avec --dry-run=client -o yaml pour générer un squelette propre et valide.

  1. Générez un manifest nommé pod-frontend.yaml sans exécuter la création sur le cluster :

Sous Windows (PowerShell) :

kubectl run campus-frontend --image=regaieg/campus:frontend-1.0.0 --port=8080 --dry-run=client -o yaml | Out-File -Encoding utf8 pod-frontend.yaml

Sous Linux (Ubuntu) / macOS (Bash) :

kubectl run campus-frontend --image=regaieg/campus:frontend-1.0.0 --port=8080 --dry-run=client -o yaml > pod-frontend.yaml
  1. Enrichissez la section metadata.labels de votre fichier YAML pour y inclure les labels d'entreprise :
  2. app: campus
  3. tier: frontend
  4. environment: dev
  5. version: "1.0.0"
💡 Indice 1 : Structure YAML attendue
apiVersion: v1
kind: Pod
metadata:
  name: campus-frontend
  labels:
    app: campus
    tier: frontend
    environment: dev
    version: "1.0.0"
spec:
  containers:
  - name: campus-frontend
    image: regaieg/campus:frontend-1.0.0
    ports:
    - containerPort: 8080
  1. Appliquez le manifest de manière déclarative :
    kubectl apply -f pod-frontend.yaml
    

Exercice 3 : Variables d'Environnement & Inspection Interne

Un Pod ne doit pas être une boîte noire. Vous devez savoir lui injecter des paramètres dynamiques et inspecter son fonctionnement interne.

  1. Modifiez votre fichier pod-frontend.yaml pour injecter deux variables d'environnement dans le conteneur via la section env :
  2. CAMPUS_APP_NAME : "Horizon Stages"
  3. CAMPUS_ENV : "development"
💡 Indice 2 : Exemple d'ajout de variables d'environnement
spec:
  containers:
  - name: campus-frontend
    image: regaieg/campus:frontend-1.0.0
    ports:
    - containerPort: 8080
    env:
    - name: CAMPUS_APP_NAME
      value: "Horizon Stages"
    - name: CAMPUS_ENV
      value: "development"
  1. Réappliquez le manifest :

    kubectl replace --force -f pod-frontend.yaml
    
    (Un Pod existant ne peut pas modifier ses variables à chaud : l'option --force détruit et recrée le pod avec la nouvelle définition).

  2. Exécuter une commande à l'intérieur du conteneur (kubectl exec) : Vérifiez que la variable est bien présente dans le système Linux du conteneur :

    kubectl exec campus-frontend -- env | grep CAMPUS
    

  3. Tester la réponse HTTP locale du serveur web :

    kubectl exec campus-frontend -- wget -qO- http://127.0.0.1:8080 | head -n 15
    

    💡 Précision réseau : Nous ciblons 127.0.0.1:8080 plutôt que localhost:8080 car sous les distributions légères comme Alpine Linux, localhost résout par défaut sur IPv6 (::1), alors que le serveur Nginx écoute sur le socket IPv4 0.0.0.0:8080.

  4. Consulter les journaux d'accès (logs) :

    kubectl logs campus-frontend
    


Exercice 4 : Allocation & Gouvernance des Ressources (Requests & Limits)

En environnement d'entreprise partagé, ne pas borner la mémoire et le CPU d'un conteneur expose le serveur physique à la saturation (phénomène du Noisy Neighbor).

  • requests (demande garantie) : Quantité minimale de CPU et de RAM réservée par le Scheduler sur le nœud worker pour accepter de placer le Pod.
  • limits (plafond absolu) : Plafond maximal autorisé. Si le conteneur dépasse la limite mémoire, le noyau Linux le tue immédiatement (OOMKilled). S'il dépasse la limite CPU, il subit du bridage temporel (CPU Throttling).

  • Complétez la définition du conteneur dans pod-frontend.yaml avec les ressources suivantes :

  • Requests : 100m de CPU (10% d'un cœur vCPU) et 128Mi de RAM.
  • Limits : 250m de CPU (25% d'un cœur vCPU) et 256Mi de RAM.
💡 Indice 3 : Bloc resources dans le manifest
spec:
  containers:
  - name: campus-frontend
    image: regaieg/campus:frontend-1.0.0
    ports:
    - containerPort: 8080
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "250m"
        memory: "256Mi"
  1. Appliquez la mise à jour :

    kubectl replace --force -f pod-frontend.yaml
    

  2. Vérifiez la prise en compte des quotas dans la description officielle de Kubernetes :

    kubectl describe pod campus-frontend | grep -A 8 "Limits:"
    


Exercice 5 : Pattern Avancé d'Initialisation (InitContainers)

Un InitContainer s'exécute et se termine avant que le conteneur applicatif principal ne démarre. C'est le pattern recommandé par la CNCF pour télécharger des dépendances, attendre qu'une base de données réponde ou valider des prérequis réseau.

  1. Ajoutez un bloc initContainers dans votre fichier pod-frontend.yaml :

    spec:
      initContainers:
      - name: init-check-env
        image: busybox:1.36
        command: ['sh', '-c', 'echo "[Init] Verification des prérequis Campus..." && sleep 5 && echo "[Init] Pret!"']
      containers:
      - name: campus-frontend
        image: regaieg/campus:frontend-1.0.0
        ports:
        - containerPort: 8080
    

  2. Appliquez le manifest et observez la transition d'état en direct :

    kubectl replace --force -f pod-frontend.yaml
    kubectl get pods -w
    
    Observez la progression des statuts : Init:0/1 → PodInitializing → Running !

  3. Affichez les logs spécifiques du conteneur d'initialisation :

    kubectl logs campus-frontend -c init-check-env
    


Exercice 6 : Maîtrise des Labels, Annotations & Limites du Pod Isolé

  1. Filtrer avec des sélecteurs stricts :
  2. Filtrer par composant frontend :
    kubectl get pods -l tier=frontend
    
  3. Filtrer par application et environnement :
    kubectl get pods -l app=campus,environment=dev
    
  4. Filtrer par négation (tous les pods qui ne sont pas backend) :

    kubectl get pods -l 'tier!=backend'
    

  5. Labels vs Annotations (Différence Fondamentale) :

  6. Les Labels sont indexés par le Control Plane pour l'ordonnancement, les Services et les sélecteurs (kubectl get -l). Ils obéissent à une syntaxe stricte (alphanumérique, pas d'arobase ni d'espaces).
  7. Les Annotations servent aux métadonnées non sélectionnables (adresses e-mail, numéros de commit Git, payloads JSON, timestamps) :
    kubectl annotate pod campus-frontend contact="devops-team" release-note="initial-deployment-summer-2026" email="equipe-devops@horizon.univ"
    
  8. Tentez de filtrer les pods par le contact annoté :

    kubectl get pods -l contact=devops-team
    
    Constat : Aucune ressource trouvée (No resources found) ! Même avec une syntaxe valide, les annotations ne sont pas indexées par le sélecteur d'etcd.

  9. Le crash-test du Pod isolé : Supprimez le pod campus-frontend :

    kubectl delete pod campus-frontend
    kubectl get pods
    
    Question de réflexion : Le pod est-il réapparu tout seul ?
    Réponse : Non ! Un Pod isolé (bare pod) n'est rattaché à aucun contrôleur. S'il plante, meurt ou est supprimé, il est définitivement perdu.
    👉 C'est la raison d'être des Deployments, étudiés dans le Lab 03 !


Critères de Validation (Checklist)

  • Vous maîtrisez la génération rapide de manifest avec --dry-run=client -o yaml.
  • Vous savez injecter des variables d'environnement (env) et inspecter l'intérieur du conteneur avec kubectl exec.
  • Vous savez encadrer la consommation mémoire et processeur avec resources.requests et resources.limits.
  • Vous avez vu tourner un initContainer et compris son rôle dans le cycle de vie du Pod.
  • Vous savez filtrer les ressources avec le paramètre -l / --selector et faites la distinction entre Label et Annotation.
  • Vous avez constaté par vous-même l'absence de haute disponibilité d'un pod nu.