# Fichier: python_cheats/cheatsheets/kubernetes.txt
# Cheatsheet Kubernetes (K8s) - Guide Complet pour Débutants


[OK] QU'EST-CE QUE KUBERNETES ? (EXPLICATION SIMPLE)

# Imaginez que vous avez une application web (comme un site e-commerce)
# Cette application doit :
# - Tourner 24/7 sans interruption
# - Gérer des pics de trafic (Black Friday, soldes)
# - Se remettre automatiquement en cas de crash
# - Se mettre à jour sans downtime

# SANS Kubernetes:
# Vous devez manuellement :
# - Démarrer vos serveurs
# - Surveiller leur santé
# - Les redémarrer s'ils plantent
# - Ajouter des serveurs si trafic élevé
# - Gérer les mises à jour une par une

# AVEC Kubernetes:
# Vous dites à Kubernetes ce que vous voulez (ex: "Je veux 5 copies de mon app")
# Et Kubernetes s'occupe de TOUT automatiquement :
# [OK] Lance et maintient 5 copies en permanence
# [OK] Redémarre automatiquement si une copie crash
# [OK] Distribue le trafic entre les copies
# [OK] Peut augmenter/diminuer le nombre de copies selon la charge
# [OK] Met à jour progressivement sans coupure

# ANALOGIE: Kubernetes est comme un chef d'orchestre
# - Vous êtes le compositeur (vous écrivez ce que vous voulez)
# - Kubernetes est le chef d'orchestre (il coordonne tout)
# - Les musiciens sont vos applications (ils jouent la musique)


[OK] CONCEPTS DE BASE (VOCABULAIRE ESSENTIEL)

# === CONTENEUR ===
# Un conteneur = votre application + tout ce dont elle a besoin pour fonctionner
# Pensez à un conteneur Docker : c'est une "boîte" qui contient votre code
# Exemple : votre app Python + Python + bibliothèques + configuration

# === POD ===
# UN POD = La plus petite unité dans Kubernetes
# Un pod contient 1 ou plusieurs conteneurs (généralement 1 seul)
# Analogie : Un pod = un appartement, les conteneurs = les pièces
# Tous les conteneurs d'un pod partagent le même réseau et stockage
# Si le pod meurt, tous ses conteneurs meurent aussi

# Exemple concret :
# Pod "webapp" contient :
# - Conteneur 1 : Votre application web (port 8080)
# - Conteneur 2 : Un agent de logs (optionnel)

# === NODE ===
# UN NODE = Une machine (serveur) qui exécute vos pods
# Peut être :
# - Un serveur physique dans votre datacenter
# - Une VM sur AWS/GCP/Azure
# - Votre ordinateur local (avec Minikube)
# Un cluster a généralement plusieurs nodes pour la redondance

# === CLUSTER ===
# UN CLUSTER = Ensemble de nodes qui travaillent ensemble
# Comme une équipe de serveurs coordonnés par Kubernetes
# Généralement : 1 ou 3 nodes "control plane" + X nodes "worker"

# === CONTROL PLANE (Cerveau du cluster) ===
# Les composants qui GÈRENT le cluster :
# - API Server : Point d'entrée de toutes les commandes (quand vous tapez kubectl)
# - Scheduler : Décide sur quel node placer un nouveau pod
# - Controller Manager : Surveille l'état et corrige si nécessaire
# - etcd : Base de données qui stocke tout l'état du cluster

# === WORKER NODE (Muscles du cluster) ===
# Les machines qui EXÉCUTENT vraiment vos applications
# Composants sur chaque worker node :
# - kubelet : Agent qui reçoit les ordres et gère les pods
# - kube-proxy : Gère le réseau
# - Container Runtime : Docker ou containerd qui lance les conteneurs

# === DEPLOYMENT ===
# UN DEPLOYMENT = Déclaration de "Je veux X copies de mon app"
# Kubernetes va créer et maintenir X pods identiques
# Si un pod meurt, le Deployment en crée automatiquement un nouveau
# C'est ce que vous utiliserez 90% du temps

# Exemple : "Je veux 3 copies de nginx toujours en marche"
# Kubernetes va :
# 1. Créer 3 pods nginx
# 2. Les surveiller en permanence
# 3. Si un pod crash, en recréer un immédiatement
# 4. Si un node meurt, redémarrer les pods sur un autre node

# === SERVICE ===
# UN SERVICE = Point d'accès stable à vos pods
# Problème : Les pods ont des IPs qui changent quand ils redémarrent
# Solution : Le Service a une IP fixe et redirige vers les pods

# Analogie : 
# - Vos pods = des restaurants qui peuvent fermer/rouvrir à différents endroits
# - Le Service = une adresse permanente (comme "pizzeria.com")
# - Même si le restaurant déménage, l'adresse reste la même

# Types de services :
# - ClusterIP : Accessible uniquement DANS le cluster (par défaut)
# - NodePort : Accessible depuis l'extérieur via port du node
# - LoadBalancer : Crée un load balancer cloud (AWS ELB, etc.)

# === NAMESPACE ===
# UN NAMESPACE = Dossier virtuel pour organiser vos ressources
# Comme des dossiers sur votre ordinateur
# Utile pour séparer : dev, staging, production, équipes, etc.
# Par défaut : "default", "kube-system", "kube-public"

# === LABEL ===
# UN LABEL = Étiquette clé-valeur attachée aux ressources
# Exemples : app=nginx, environment=production, version=2.0
# Utilisés pour ORGANISER et SÉLECTIONNER les ressources
# Les Services utilisent les labels pour trouver leurs pods

# === SELECTOR ===
# UN SELECTOR = Filtre pour sélectionner des ressources par labels
# Exemple : "Trouve tous les pods avec label app=nginx"


[OK] COMMENT FONCTIONNE KUBERNETES ? (LE CYCLE COMPLET)

# === VOUS (Développeur) ===
# Vous écrivez un fichier YAML qui décrit ce que vous voulez :
# "Je veux 3 pods nginx qui écoutent sur le port 80"

# === KUBECTL (Votre outil de commande) ===
# Vous tapez : kubectl apply -f mon-fichier.yaml
# kubectl envoie votre demande à l'API Server

# === API SERVER (Portier du cluster) ===
# Reçoit la demande, la valide, la sauvegarde dans etcd
# Annonce : "Il y a un nouveau Deployment à créer !"

# === CONTROLLER MANAGER (Superviseur) ===
# Voit la demande : "Ah ! Il faut créer 3 pods nginx"
# Crée 3 définitions de pods
# Les marque comme "à planifier"

# === SCHEDULER (Planificateur) ===
# Pour chaque pod à créer :
# 1. Regarde tous les nodes disponibles
# 2. Vérifie lequel a assez de ressources (CPU, RAM)
# 3. Vérifie les contraintes (ex: "pas sur le même node")
# 4. Assigne le pod au meilleur node
# Résultat : "Pod 1 va sur node-1, Pod 2 sur node-2, Pod 3 sur node-1"

# === KUBELET (Agent sur chaque node) ===
# Sur node-1, kubelet voit : "J'ai 2 nouveaux pods à lancer"
# 1. Télécharge l'image Docker (ex: nginx:latest)
# 2. Démarre les conteneurs
# 3. Configure le réseau
# 4. Surveille que tout va bien
# 5. Rapporte l'état à l'API Server

# === CONTRÔLE CONTINU ===
# Kubernetes surveille EN PERMANENCE :
# - Si un pod crash -> le redémarre
# - Si un node meurt -> redémarre les pods ailleurs
# - Si vous changez le Deployment -> met à jour progressivement
# - Si vous scalez à 5 pods -> crée 2 pods supplémentaires

# EXEMPLE CONCRET :
# 1. Vous demandez : 3 pods nginx
# 2. Kubernetes crée 3 pods
# 3. Un pod crash
# 4. Kubernetes détecte instantanément
# 5. Kubernetes crée un nouveau pod pour remplacer
# 6. Résultat : TOUJOURS 3 pods en marche (état désiré = état réel)


[OK] POURQUOI UTILISER KUBERNETES ?

# === HAUTE DISPONIBILITÉ ===
# Si un serveur tombe, vos apps continuent sur d'autres serveurs
# Zéro downtime lors des mises à jour

# === SCALABILITÉ AUTOMATIQUE ===
# Beaucoup de trafic ? Kubernetes ajoute automatiquement des pods
# Peu de trafic ? Kubernetes en retire pour économiser

# === SELF-HEALING (Auto-réparation) ===
# Un conteneur crash ? -> Redémarré automatiquement
# Un node meurt ? -> Pods redémarrés ailleurs
# Health check échoue ? -> Pod remplacé

# === DÉPLOIEMENTS ZÉRO-DOWNTIME ===
# Mise à jour progressive : nouveaux pods démarrent avant que les anciens s'arrêtent
# Rollback automatique si problème détecté

# === PORTABILITÉ ===
# Même configuration fonctionne sur :
# - Votre laptop (Minikube)
# - AWS, GCP, Azure
# - Votre datacenter on-premise
# - Même un Raspberry Pi !

# === GESTION DÉCLARATIVE ===
# Vous décrivez CE QUE vous voulez (état désiré)
# Kubernetes s'occupe du COMMENT (état réel)
# Tout est dans des fichiers YAML versionnés (Infrastructure as Code)


[OK] KUBERNETES vs DOCKER : QUELLE DIFFÉRENCE ?

# DOCKER :
# - Crée et lance des conteneurs
# - Fonctionne sur UNE SEULE machine
# - Vous devez gérer manuellement : démarrage, redémarrage, load balancing

# KUBERNETES :
# - ORCHESTRE des conteneurs Docker/containerd sur PLUSIEURS machines
# - Gère automatiquement : scaling, healing, load balancing, updates
# - Utilise Docker (ou autre) pour lancer les conteneurs

# ANALOGIE :
# Docker = Moteur de voiture (lance un conteneur)
# Kubernetes = Système de gestion de flotte (orchestre des milliers de voitures)

# VOUS AVEZ BESOIN DES DEUX :
# Kubernetes UTILISE Docker (ou containerd) pour créer les conteneurs
# Mais Kubernetes ajoute toute l'intelligence de gestion au-dessus


[OK] INSTALLATION DE KUBERNETES

[OK] PRÉREQUIS AVANT DE COMMENCER

# === CE DONT VOUS AVEZ BESOIN ===

# 1. Connaissances de base :
# - Ligne de commande (terminal/cmd)
# - Concepts de base Docker (images, conteneurs)
# - YAML (syntaxe de base)

# 2. Sur votre ordinateur :
# - 4 GB RAM minimum (8 GB recommandé)
# - 20 GB d'espace disque
# - Processeur avec virtualisation activée

# 3. Outils à installer :
# - kubectl : Client pour parler avec Kubernetes
# - Un "cluster local" : Minikube OU Kind OU Docker Desktop
# - Optionnel : Docker (pour créer vos propres images)

# === QUEL OUTIL CHOISIR POUR DÉBUTER ? ===

# MINIKUBE (***** Recommandé pour débuter)
# [OK] Le plus facile pour apprendre
# [OK] Dashboard graphique intégré
# [OK] Plein d'addons (ingress, metrics, etc.)
# [OK] Documentation excellente
# -> Utilisez Minikube si c'est votre première fois !

# KIND (Kubernetes IN Docker)
# [OK] Très léger et rapide
# [OK] Parfait pour tester des configs
# [OK] Utilisé pour tester Kubernetes lui-même
# -> Bon pour CI/CD ou tests rapides

# DOCKER DESKTOP
# [OK] Intégré si vous avez déjà Docker Desktop
# [OK] Un clic pour activer Kubernetes
# [X] Consomme beaucoup de ressources
# -> Pratique si vous utilisez déjà Docker Desktop

# K3S
# [OK] Version ultra-légère de Kubernetes
# [OK] Parfait pour Raspberry Pi, edge computing
# [X] Certaines fonctionnalités simplifiées
# -> Pour production légère ou IoT


[OK] INSTALLATION ÉTAPE PAR ÉTAPE (DÉBUTANTS)

# === ÉTAPE 1 : INSTALLER KUBECTL (Obligatoire) ===

# kubectl = votre "télécommande" pour parler avec Kubernetes
# C'est l'outil que vous utiliserez tout le temps

# VÉRIFIER SI DÉJÀ INSTALLÉ :
kubectl version --client

# SI PAS INSTALLÉ, suivre les instructions ci-dessous selon votre OS

# === ÉTAPE 2 : INSTALLER MINIKUBE (Cluster local) ===

# Minikube crée un cluster Kubernetes sur votre ordinateur
# Parfait pour apprendre et tester sans toucher à un vrai cluster

# APRÈS INSTALLATION, VÉRIFIER :
minikube version

# === PREMIER DÉMARRAGE (LE MOMENT DE VÉRITÉ !) ===

# Démarrer votre premier cluster Kubernetes :
minikube start

# Que se passe-t-il ? Minikube va :
# 1. Télécharger l'image Kubernetes (~1GB, uniquement la 1ère fois)
# 2. Créer une machine virtuelle
# 3. Installer Kubernetes dedans
# 4. Configurer kubectl pour parler avec ce cluster
# [TEMPS]  Durée : 2-5 minutes la première fois

# VOUS DEVRIEZ VOIR :
# [SMILING_FACE_WITH_OPEN_MOUTH_AND_SMILING_EYES]  minikube v1.32.0
# *  Automatically selected the docker driver
# [BIEN]  Starting control plane node minikube in cluster minikube
# [TRACTOR]  Pulling base image ...
# [HOT]  Creating docker container (CPUs=2, Memory=4000MB) ...
# [DOCKER]  Preparing Kubernetes v1.28.3 ...
# [RECHERCHE]  Verifying Kubernetes components...
# *  Enabled addons: storage-provisioner, default-storageclass
# [SURFER]  Done! kubectl is now configured to use "minikube" cluster

# VÉRIFIER QUE ÇA MARCHE :
kubectl get nodes

# VOUS DEVRIEZ VOIR :
# NAME       STATUS   ROLES           AGE   VERSION
# minikube   Ready    control-plane   1m    v1.28.3

# [BRAVO] FÉLICITATIONS ! Vous avez un cluster Kubernetes qui tourne !


[OK] VOS PREMIÈRES COMMANDES (DÉCOUVERTE)

# Maintenant que votre cluster est lancé, explorons-le !

# === VOIR LES INFORMATIONS DU CLUSTER ===

kubectl cluster-info
# Affiche :
# - L'URL du serveur Kubernetes
# - L'URL du dashboard (si activé)
# - Les services système qui tournent

# === VOIR LES PODS QUI TOURNENT ===

kubectl get pods
# Résultat probable : "No resources found in default namespace."
# C'est NORMAL ! Vous n'avez encore rien déployé

# Voir TOUS les pods (y compris système) :
kubectl get pods -A
# Vous verrez des pods Kubernetes système comme :
# - coredns (DNS)
# - etcd (base de données)
# - kube-apiserver (API)
# - kube-proxy (réseau)
# Ces pods font FONCTIONNER Kubernetes lui-même

# === LANCER VOTRE PREMIER POD ===

# Méthode simple (impérative) - juste pour tester :
kubectl run mon-premier-pod --image=nginx

# Que fait cette commande ?
# 1. Télécharge l'image "nginx" depuis Docker Hub
# 2. Crée un pod nommé "mon-premier-pod"
# 3. Lance un conteneur nginx dedans

# Vérifier qu'il existe :
kubectl get pods

# VOUS DEVRIEZ VOIR :
# NAME              READY   STATUS    RESTARTS   AGE
# mon-premier-pod   1/1     Running   0          30s

# Explication des colonnes :
# - NAME : Nom du pod
# - READY : 1/1 = 1 conteneur prêt sur 1 total
# - STATUS : Running = le pod tourne
# - RESTARTS : Nombre de fois que le conteneur a redémarré
# - AGE : Depuis combien de temps il existe

# === VOIR LES DÉTAILS DU POD ===

kubectl describe pod mon-premier-pod

# Cette commande affiche TOUT sur le pod :
# - Sur quel node il tourne
# - Son adresse IP
# - Ses labels
# - Les événements (création, démarrage, etc.)
# - Les ressources utilisées
# - Les volumes montés
# C'est votre outil de DEBUG principal !

# === VOIR LES LOGS DU POD ===

kubectl logs mon-premier-pod

# Affiche ce que le conteneur écrit dans sa sortie standard
# Pour nginx, vous verrez les logs du serveur web

# Suivre les logs en temps réel (comme tail -f) :
kubectl logs mon-premier-pod -f
# Appuyez sur Ctrl+C pour arrêter

# === EXÉCUTER UNE COMMANDE DANS LE POD ===

kubectl exec mon-premier-pod -- ls /
# Exécute "ls /" DANS le conteneur
# Comme faire "docker exec" mais pour Kubernetes

# Ouvrir un shell interactif dans le pod :
kubectl exec -it mon-premier-pod -- /bin/bash
# Vous êtes maintenant DANS le conteneur !
# Tapez "exit" pour sortir

# === ACCÉDER AU POD DEPUIS VOTRE ORDINATEUR ===

kubectl port-forward mon-premier-pod 8080:80

# Que fait cette commande ?
# - Crée un tunnel entre votre ordinateur (port 8080) et le pod (port 80)
# - Ouvrez http://localhost:8080 dans votre navigateur
# - Vous verrez la page d'accueil nginx !
# - Appuyez sur Ctrl+C pour arrêter le tunnel

# === SUPPRIMER LE POD ===

kubectl delete pod mon-premier-pod

# Le pod est supprimé immédiatement (ou presque)
# Vérifier qu'il n'existe plus :
kubectl get pods


[OK] CRÉER VOTRE PREMIER DEPLOYMENT (LA VRAIE FAÇON)

# Les pods seuls ne sont JAMAIS utilisés en production
# Pourquoi ? Si vous supprimez un pod, il ne revient pas !
# Solution : Utiliser un DEPLOYMENT

# === CRÉER UN DEPLOYMENT ===

kubectl create deployment mon-app --image=nginx

# Que fait cette commande ?
# 1. Crée un Deployment nommé "mon-app"
# 2. Le Deployment crée un ReplicaSet
# 3. Le ReplicaSet crée 1 pod nginx

# Voir le deployment :
kubectl get deployments
# Ou : kubectl get deploy

# VOUS DEVRIEZ VOIR :
# NAME      READY   UP-TO-DATE   AVAILABLE   AGE
# mon-app   1/1     1            1           10s

# Explication :
# - READY : 1/1 = 1 pod prêt sur 1 désiré
# - UP-TO-DATE : 1 pod avec la dernière version
# - AVAILABLE : 1 pod accessible

# Voir les pods créés par le deployment :
kubectl get pods

# VOUS DEVRIEZ VOIR un pod avec un nom comme :
# mon-app-7d8f5c4b9d-xk9tz

# Le nom contient :
# - "mon-app" = nom du deployment
# - "7d8f5c4b9d" = ID du ReplicaSet
# - "xk9tz" = ID unique du pod

# === TESTER L'AUTO-HEALING ===

# Supprimons ce pod pour voir ce qui se passe :
kubectl delete pod mon-app-7d8f5c4b9d-xk9tz
# (Remplacez par le vrai nom de votre pod)

# Regardez immédiatement les pods :
kubectl get pods -w
# (-w = watch = rafraîchit automatiquement)

# QUE SE PASSE-T-IL ?
# 1. Le pod que vous avez supprimé passe en "Terminating"
# 2. UN NOUVEAU POD est créé AUTOMATIQUEMENT !
# 3. Le nouveau pod démarre et passe en "Running"
# 4. Résultat : TOUJOURS 1 pod en marche

# [BRAVO] C'est la MAGIE de Kubernetes !
# Le Deployment garantit que vous avez toujours le nombre de pods désiré

# === SCALER LE DEPLOYMENT (Plusieurs copies) ===

kubectl scale deployment mon-app --replicas=3

# Que fait cette commande ?
# Dit au Deployment : "Je veux 3 pods au lieu de 1"

# Regardez en temps réel :
kubectl get pods -w

# VOUS DEVRIEZ VOIR :
# - Le pod existant reste en marche
# - 2 NOUVEAUX pods sont créés
# - Après quelques secondes, 3 pods en "Running"

# Pourquoi faire plusieurs copies ?
# - Haute disponibilité (si un pod crash, 2 restent)
# - Répartition de charge (le trafic est distribué)
# - Mise à jour sans interruption

# === EXPOSER LE DEPLOYMENT (Créer un Service) ===

kubectl expose deployment mon-app --port=80 --type=NodePort

# Que fait cette commande ?
# 1. Crée un Service nommé "mon-app"
# 2. Le Service cible tous les pods avec label "app=mon-app"
# 3. Le Service écoute sur le port 80
# 4. Type NodePort = accessible depuis l'extérieur du cluster

# Voir le service :
kubectl get services
# Ou : kubectl get svc

# VOUS DEVRIEZ VOIR :
# NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
# mon-app   NodePort   10.96.123.45    <none>        80:30123/TCP   5s

# Explication :
# - CLUSTER-IP : IP interne du service (utilisable dans le cluster)
# - PORT(S) : 80:30123 = port 80 du service, port 30123 du node
# - 30123 = port aléatoire entre 30000-32767

# === ACCÉDER À VOTRE APPLICATION ===

# Avec Minikube, obtenir l'URL :
minikube service mon-app --url

# Cette commande vous donne l'URL complète, genre :
# http://192.168.49.2:30123

# Ouvrir dans le navigateur :
minikube service mon-app
# Minikube ouvre automatiquement votre navigateur !

# [BRAVO] Vous voyez la page d'accueil nginx !
# Et cette page est servie par 3 pods différents

# === NETTOYER ===

# Supprimer le service :
kubectl delete service mon-app

# Supprimer le deployment (et tous ses pods) :
kubectl delete deployment mon-app

# Vérifier que tout est supprimé :
kubectl get all


[OK] COMPRENDRE LES FICHIERS YAML (L'approche professionnelle)

# Jusqu'ici, nous avons utilisé des commandes impératives :
# kubectl run, kubectl create, kubectl expose
# C'est bien pour APPRENDRE, mais en production, on utilise du YAML

# === POURQUOI YAML ? ===

# AVANTAGES :
# [OK] Reproductible : même fichier = même résultat
# [OK] Versionnable : commit dans Git
# [OK] Documenté : le fichier explique ce que vous avez
# [OK] Partageable : envoyez le fichier à votre équipe
# [OK] Infrastructure as Code : tout est dans des fichiers

# COMMANDES vs YAML :
# Commande : "Fais ça maintenant"
# YAML : "Voilà ce que je veux, fais-en sorte que ça existe"

# === STRUCTURE D'UN FICHIER YAML K8S ===

# TOUS les fichiers Kubernetes ont ces 4 sections :

apiVersion: v1                         # Quelle version de l'API utiliser
kind: Pod                              # Quel TYPE de ressource (Pod, Deployment, Service...)
metadata:                              # Informations sur la ressource
  name: mon-pod                        # Nom unique
  labels:                              # Étiquettes pour organiser
    app: mon-app
spec:                                  # SPÉCIFICATION : ce que vous voulez
  containers:                          # Liste des conteneurs
  - name: nginx                        # Nom du conteneur
    image: nginx:1.25                  # Image Docker à utiliser

# === VOTRE PREMIER FICHIER YAML ===

# Créez un fichier "mon-pod.yaml" :

# --- mon-pod.yaml ---
apiVersion: v1
kind: Pod
metadata:
  name: mon-premier-pod-yaml
  labels:
    app: nginx
    environnement: test
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
# --- fin du fichier ---

# APPLIQUER le fichier :
kubectl apply -f mon-pod.yaml

# Que fait cette commande ?
# 1. Lit le fichier YAML
# 2. Envoie la configuration à Kubernetes
# 3. Kubernetes crée le pod selon la spec

# Vérifier :
kubectl get pods

# VOUS DEVRIEZ VOIR :
# NAME                     READY   STATUS    RESTARTS   AGE
# mon-premier-pod-yaml     1/1     Running   0          5s

# MODIFIER le fichier :
# Changez "nginx:1.25" en "nginx:1.26"
# Réappliquez :
kubectl apply -f mon-pod.yaml

# Kubernetes voit la différence et met à jour le pod !

# === VOTRE PREMIER DEPLOYMENT EN YAML ===

# Créez un fichier "mon-deployment.yaml" :

# --- mon-deployment.yaml ---
apiVersion: apps/v1                    # API pour Deployments
kind: Deployment
metadata:
  name: mon-app
  labels:
    app: mon-app
spec:
  replicas: 3                          # JE VEUX 3 PODS
  selector:                            # Comment trouver mes pods
    matchLabels:
      app: mon-app
  template:                            # Modèle de pod à créer
    metadata:
      labels:
        app: mon-app                   # Labels des pods
    spec:                              # Spec du pod
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
# --- fin du fichier ---

# APPLIQUER :
kubectl apply -f mon-deployment.yaml

# Vérifier :
kubectl get deployments
kubectl get pods

# VOUS DEVRIEZ VOIR 3 pods !

# === COMPRENDRE LE TEMPLATE ===

# Le Deployment a DEUX specs :
# 1. spec du Deployment (replicas, selector)
# 2. spec du Pod (dans template)

# Analogie :
# - Le Deployment est une PHOTOCOPIEUSE
# - Le template est le DOCUMENT ORIGINAL
# - replicas=3 signifie "fais 3 copies"

# === SERVICE EN YAML ===

# Créez un fichier "mon-service.yaml" :

# --- mon-service.yaml ---
apiVersion: v1
kind: Service
metadata:
  name: mon-app-service
spec:
  type: NodePort                       # Type de service
  selector:
    app: mon-app                       # Cible les pods avec ce label
  ports:
  - protocol: TCP
    port: 80                           # Port du service
    targetPort: 80                     # Port du conteneur
    nodePort: 30080                    # Port sur le node (optionnel)
# --- fin du fichier ---

# APPLIQUER :
kubectl apply -f mon-service.yaml

# ACCÉDER (Minikube) :
minikube service mon-app-service

# === TOUT DANS UN SEUL FICHIER ===

# Vous pouvez mettre plusieurs ressources dans un fichier
# Séparez-les par "---"

# --- app-complete.yaml ---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mon-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mon-app
  template:
    metadata:
      labels:
        app: mon-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: mon-app-service
spec:
  type: NodePort
  selector:
    app: mon-app
  ports:
  - port: 80
    targetPort: 80
# --- fin du fichier ---

# APPLIQUER TOUT :
kubectl apply -f app-complete.yaml

# Kubernetes crée le Deployment ET le Service !


[OK] CONCEPTS INTERMÉDIAIRES EXPLIQUÉS SIMPLEMENT

# === LABELS ET SELECTORS (Le Système de Liaison) ===

# PROBLÈME : Comment un Service trouve-t-il ses pods ?
# SOLUTION : Les LABELS et SELECTORS

# LABELS = Étiquettes sur les ressources
# Exemples :
# - app=nginx
# - environment=production
# - version=2.0
# - team=backend

# SELECTORS = Filtres pour trouver des ressources
# Exemple :
# Service dit : "Je veux tous les pods avec app=nginx"
# Kubernetes trouve tous les pods ayant ce label

# ANALOGIE :
# - Labels = Badges sur des t-shirts (type: sport, couleur: rouge, taille: L)
# - Selectors = "Trouve-moi tous les t-shirts rouges de type sport"

# === MINIKUBE (Développement local - Recommandé pour débuter) ===

# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# macOS (Intel)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64
sudo install minikube-darwin-amd64 /usr/local/bin/minikube

# macOS (Apple Silicon)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-arm64
sudo install minikube-darwin-arm64 /usr/local/bin/minikube

# macOS (Homebrew)
brew install minikube

# Windows (Chocolatey)
choco install minikube

# Windows (Direct download)
# Télécharger depuis: https://minikube.sigs.k8s.io/docs/start/

# Vérifier installation
minikube version

# === KIND (Kubernetes IN Docker) ===

# Linux/macOS
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# macOS (Homebrew)
brew install kind

# Windows (Chocolatey)
choco install kind

# Windows (PowerShell)
curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.20.0/kind-windows-amd64
Move-Item .\kind-windows-amd64.exe c:\windows\system32\kind.exe

# === K3S (Kubernetes léger) ===

# Linux
curl -sfL https://get.k3s.io | sh -

# Vérifier
sudo k3s kubectl get nodes

# === KUBECTL (Client en ligne de commande - ESSENTIEL) ===

# Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# macOS (Homebrew)
brew install kubectl

# macOS (Direct)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# Windows (Chocolatey)
choco install kubernetes-cli

# Vérifier installation
kubectl version --client
kubectl version --client --output=yaml


[OK] DÉMARRAGE RAPIDE AVEC MINIKUBE

# Démarrer un cluster local
minikube start

# Démarrer avec configuration spécifique
minikube start --driver=docker          # Utiliser Docker comme driver
minikube start --driver=virtualbox      # Utiliser VirtualBox
minikube start --driver=hyperv          # Windows Hyper-V
minikube start --driver=kvm2            # Linux KVM
minikube start --cpus=4 --memory=8192   # 4 CPUs, 8GB RAM
minikube start --kubernetes-version=v1.28.0
minikube start --nodes=3                # Cluster multi-nodes

# Vérifier le statut
minikube status

# Arrêter le cluster
minikube stop

# Supprimer le cluster
minikube delete

# Supprimer tous les clusters
minikube delete --all

# Pause/Resume
minikube pause                          # Met en pause
minikube unpause                        # Reprend

# Accéder au dashboard Kubernetes
minikube dashboard

# SSH dans le node minikube
minikube ssh

# Obtenir l'IP du cluster
minikube ip

# Lister les addons disponibles
minikube addons list

# Activer un addon
minikube addons enable ingress
minikube addons enable metrics-server
minikube addons enable dashboard

# Désactiver un addon
minikube addons disable ingress


[OK] DÉMARRAGE AVEC KIND

# Créer un cluster
kind create cluster

# Créer avec nom personnalisé
kind create cluster --name mon-cluster

# Créer cluster multi-nodes
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF

# Lister les clusters
kind get clusters

# Supprimer un cluster
kind delete cluster
kind delete cluster --name mon-cluster

# Obtenir kubeconfig
kind get kubeconfig --name mon-cluster


[OK] CONFIGURATION DE KUBECTL

# Voir la configuration actuelle
kubectl config view

# Voir configuration avec secrets
kubectl config view --raw

# Obtenir le contexte actuel
kubectl config current-context

# Lister tous les contextes
kubectl config get-contexts

# Changer de contexte
kubectl config use-context minikube
kubectl config use-context kind-kind

# Définir un namespace par défaut
kubectl config set-context --current --namespace=mon-namespace

# Créer un nouveau contexte
kubectl config set-context mon-contexte \
  --cluster=mon-cluster \
  --user=mon-user \
  --namespace=default

# Renommer un contexte
kubectl config rename-context ancien-nom nouveau-nom

# Supprimer un contexte
kubectl config delete-context mon-contexte


[OK] COMMANDES KUBECTL ESSENTIELLES

# === INFORMATIONS CLUSTER ===

# Informations sur le cluster
kubectl cluster-info
kubectl cluster-info dump              # Diagnostic complet

# Version de Kubernetes
kubectl version
kubectl version --short

# Lister les nodes
kubectl get nodes
kubectl get nodes -o wide              # Plus de détails

# Détails d'un node
kubectl describe node nom-du-node

# Ressources disponibles sur les nodes
kubectl top nodes                      # Nécessite metrics-server

# === NAMESPACES ===

# Lister les namespaces
kubectl get namespaces
kubectl get ns                         # Abréviation

# Créer un namespace
kubectl create namespace mon-namespace
kubectl create ns dev

# Supprimer un namespace
kubectl delete namespace mon-namespace

# Décrire un namespace
kubectl describe namespace mon-namespace

# Travailler dans un namespace spécifique
kubectl get pods -n mon-namespace
kubectl get pods --namespace=mon-namespace
kubectl get pods --all-namespaces      # Tous les namespaces
kubectl get pods -A                    # Abréviation

# === PODS (l'unité de base) ===

# Lister les pods
kubectl get pods
kubectl get pods -o wide               # Plus de détails
kubectl get pods -A                    # Tous les namespaces
kubectl get pods --show-labels         # Avec labels
kubectl get pods -w                    # Mode watch (suivi en temps réel)

# Créer un pod simple (impératif)
kubectl run nginx --image=nginx
kubectl run nginx --image=nginx:1.25
kubectl run busybox --image=busybox --rm -it -- sh    # Pod interactif temporaire

# Détails d'un pod
kubectl describe pod nom-du-pod

# Logs d'un pod
kubectl logs nom-du-pod
kubectl logs nom-du-pod -f             # Suivre les logs (follow)
kubectl logs nom-du-pod --tail=50      # 50 dernières lignes
kubectl logs nom-du-pod --since=1h     # Logs de la dernière heure
kubectl logs nom-du-pod -c nom-conteneur  # Conteneur spécifique (si multiple)
kubectl logs nom-du-pod --previous     # Logs du conteneur précédent (après crash)

# Exécuter une commande dans un pod
kubectl exec nom-du-pod -- ls /
kubectl exec nom-du-pod -- env
kubectl exec nom-du-pod -c nom-conteneur -- commande

# Shell interactif dans un pod
kubectl exec -it nom-du-pod -- /bin/bash
kubectl exec -it nom-du-pod -- /bin/sh

# Copier fichiers vers/depuis un pod
kubectl cp fichier-local.txt nom-du-pod:/chemin/dans/pod
kubectl cp nom-du-pod:/chemin/fichier.txt ./fichier-local.txt

# Supprimer un pod
kubectl delete pod nom-du-pod
kubectl delete pod nom-du-pod --force --grace-period=0   # Force (attention!)

# Port forwarding (accéder à un pod localement)
kubectl port-forward nom-du-pod 8080:80    # Local:8080 -> Pod:80
kubectl port-forward nom-du-pod 3000:3000

# Redémarrer un pod (via son deployment)
kubectl rollout restart deployment nom-deployment


[OK] DÉPLOIEMENTS (DEPLOYMENTS)

# Les Deployments gèrent les ReplicaSets et les Pods
# Ils permettent la mise à l'échelle, les mises à jour, et les rollbacks

# Créer un deployment (impératif)
kubectl create deployment nginx --image=nginx
kubectl create deployment nginx --image=nginx:1.25 --replicas=3

# Lister les deployments
kubectl get deployments
kubectl get deploy                     # Abréviation
kubectl get deploy -o wide

# Détails d'un deployment
kubectl describe deployment nom-deployment

# Scaler un deployment (changer nombre de replicas)
kubectl scale deployment nginx --replicas=5
kubectl scale deployment nginx --replicas=1

# Autoscaling (HPA - Horizontal Pod Autoscaler)
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80

# Mettre à jour l'image d'un deployment
kubectl set image deployment/nginx nginx=nginx:1.26
kubectl set image deployment/nginx nginx=nginx:latest

# Éditer un deployment
kubectl edit deployment nginx

# Voir l'historique des rollouts
kubectl rollout history deployment nginx

# Voir détails d'une révision spécifique
kubectl rollout history deployment nginx --revision=2

# Rollback vers la version précédente
kubectl rollout undo deployment nginx

# Rollback vers une révision spécifique
kubectl rollout undo deployment nginx --to-revision=2

# Voir le statut d'un rollout
kubectl rollout status deployment nginx

# Pause/Resume d'un rollout
kubectl rollout pause deployment nginx
kubectl rollout resume deployment nginx

# Supprimer un deployment
kubectl delete deployment nginx


[OK] SERVICES (EXPOSITION DES APPLICATIONS)

# Les Services permettent d'exposer les pods en réseau
# Types: ClusterIP (défaut), NodePort, LoadBalancer, ExternalName

# Exposer un deployment (créer un service)
kubectl expose deployment nginx --port=80 --type=ClusterIP
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl expose deployment nginx --port=80 --type=LoadBalancer

# Créer un service impérativement
kubectl create service clusterip nginx --tcp=80:80
kubectl create service nodeport nginx --tcp=80:80

# Lister les services
kubectl get services
kubectl get svc                        # Abréviation
kubectl get svc -o wide

# Détails d'un service
kubectl describe service nginx

# Obtenir l'URL d'un service (Minikube)
minikube service nginx --url
minikube service nginx                 # Ouvre dans le navigateur

# Supprimer un service
kubectl delete service nginx

# Port forwarding vers un service
kubectl port-forward service/nginx 8080:80


[OK] CONFIGMAPS ET SECRETS

# === CONFIGMAPS (Configuration non-sensible) ===

# QU'EST-CE QU'UN CONFIGMAP ?
# Un ConfigMap stocke des données de CONFIGURATION (non-secrètes)
# Comme : URLs, paramètres d'app, fichiers de config, etc.

# POURQUOI ?
# [OK] Séparer la config du code
# [OK] Même image Docker, différentes configs (dev, prod)
# [OK] Changer la config sans rebuilder l'image
# [OK] Réutiliser la même config entre plusieurs pods

# ANALOGIE :
# ConfigMap = Fichier de réglages d'un jeu vidéo
# Vous pouvez changer les réglages sans réinstaller le jeu

# EXEMPLES DE DONNÉES POUR CONFIGMAP :
# - DATABASE_URL=postgres://db.example.com
# - LOG_LEVEL=debug
# - API_ENDPOINT=https://api.example.com
# - Fichier nginx.conf complet

# === CRÉER UN CONFIGMAP ===

# Créer un ConfigMap depuis des literals
kubectl create configmap app-config \
  --from-literal=APP_ENV=production \
  --from-literal=APP_DEBUG=false

# Créer depuis un fichier
kubectl create configmap app-config --from-file=config.properties
kubectl create configmap app-config --from-file=configs/

# Créer depuis un fichier env
kubectl create configmap app-config --from-env-file=.env

# Lister les ConfigMaps
kubectl get configmaps
kubectl get cm                         # Abréviation

# Voir le contenu d'un ConfigMap
kubectl describe configmap app-config
kubectl get configmap app-config -o yaml

# Éditer un ConfigMap
kubectl edit configmap app-config

# Supprimer un ConfigMap
kubectl delete configmap app-config

# === SECRETS (Données sensibles) ===

# QU'EST-CE QU'UN SECRET ?
# Un Secret stocke des données SENSIBLES (mots de passe, clés API, tokens)
# Comme ConfigMap, mais pour des données qu'il faut protéger

# POURQUOI UN SECRET ET PAS CONFIGMAP ?
# [OK] Données encodées en base64 (pas du vrai chiffrement, juste encodage)
# [OK] Peut être chiffré au repos (avec config cluster)
# [OK] Accès contrôlé par RBAC
# [OK] Pas affiché dans les logs
# [OK] Conventions de sécurité

# [ATTENTION] IMPORTANT : base64 n'est PAS du chiffrement !
# C'est juste de l'encodage. Tout le monde peut le décoder.
# Pour du vrai chiffrement, utilisez des outils comme :
# - Sealed Secrets
# - HashiCorp Vault
# - Cloud KMS (AWS/GCP/Azure)

# ANALOGIE :
# ConfigMap = Post-it sur votre frigo (tout le monde peut voir)
# Secret = Coffre-fort (accès contrôlé, mais pas inviolable)

# EXEMPLES DE DONNÉES POUR SECRET :
# - Mot de passe base de données
# - Clés API (Stripe, AWS, etc.)
# - Certificats TLS
# - Tokens d'authentification
# - SSH keys

# === CRÉER UN SECRET ===

# Créer un Secret générique
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=motdepasse123

# Créer depuis un fichier
kubectl create secret generic db-secret --from-file=./password.txt

# Créer un secret TLS
kubectl create secret tls tls-secret \
  --cert=cert.crt \
  --key=cert.key

# Créer un secret Docker registry
kubectl create secret docker-registry regcred \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=monuser \
  --docker-password=monpassword \
  --docker-email=email@example.com

# Lister les secrets
kubectl get secrets

# Voir un secret (encodé en base64)
kubectl get secret db-secret -o yaml

# Décoder un secret
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 --decode

# Supprimer un secret
kubectl delete secret db-secret


[OK] VOLUMES ET PERSISTENTSTORAGE

# === VOLUMES (Stockage éphémère ou persistant) ===

# LE PROBLÈME DU STOCKAGE DANS KUBERNETES :
# Par défaut, les données dans un conteneur DISPARAISSENT quand il meurt
# Exemple : Votre pod crash -> toutes les données uploadées sont PERDUES

# SOLUTION : LES VOLUMES
# Un volume = espace de stockage attaché à un pod
# Les données survivent aux redémarrages du conteneur

# TYPES DE VOLUMES (simplifiés) :

# 1. emptyDir (Volume temporaire)
# - Créé quand le pod démarre
# - SUPPRIMÉ quand le pod meurt
# - Partagé entre conteneurs du MÊME pod
# Usage : Cache, fichiers temporaires, logs
# Analogie : Post-it qui part à la poubelle en fin de journée

# 2. hostPath (Dossier du node)
# - Monte un dossier du node dans le pod
# - Données PERSISTENT sur le node
# - [ATTENTION] Dangereux ! Pod peut accéder au filesystem du node
# Usage : Tests locaux uniquement
# Analogie : Accéder au disque dur de votre ordinateur

# 3. PersistentVolume (Stockage vraiment persistant)
# - Stockage qui existe INDÉPENDAMMENT des pods
# - Peut être monté/démonté sur différents pods
# - Les données SURVIVENT à la suppression du pod
# Usage : Bases de données, uploads utilisateurs, fichiers importants
# Analogie : Disque dur externe que vous branchez/débranchez

# === PERSISTENTVOLUMES (PV) et PERSISTENTVOLUMECLAIMS (PVC) ===

# C'EST QUOI LA DIFFÉRENCE ?
# C'est un système à 2 niveaux (comme locataire/propriétaire)

# PERSISTENTVOLUME (PV) :
# - Créé par l'ADMIN du cluster
# - C'est le stockage PHYSIQUE (SSD, NFS, cloud storage)
# - Définit : taille, type, performance
# Analogie : Appartement disponible sur le marché

# PERSISTENTVOLUMECLAIM (PVC) :
# - Créé par le DÉVELOPPEUR
# - Demande de stockage ("Je veux 10GB")
# - Kubernetes trouve un PV qui correspond
# - Le PVC "réserve" le PV
# Analogie : Demande de location d'appartement

# WORKFLOW :
# 1. Admin crée des PVs (stockage disponible)
# 2. Vous créez un PVC (demande de stockage)
# 3. Kubernetes "lie" votre PVC à un PV compatible
# 4. Vous montez le PVC dans votre pod
# 5. Votre pod écrit/lit sur le stockage

# EXEMPLE CONCRET :
# Vous avez une app de blog avec uploads d'images
# Sans PV : Images perdues si pod redémarre
# Avec PV : Images persistent, même si pod meurt et redémarre

# === STORAGECLASSES ===

# QU'EST-CE QU'UNE STORAGECLASS ?
# Un "modèle" de stockage avec des caractéristiques
# Permet le provisionnement DYNAMIQUE (auto-création de PVs)

# SANS StorageClass :
# Admin doit créer manuellement chaque PV
# Vous créez PVC -> espérez qu'un PV existe

# AVEC StorageClass :
# Vous créez PVC -> Kubernetes crée AUTOMATIQUEMENT un PV !

# TYPES COMMUNS :
# - standard : HDD classique (lent, pas cher)
# - fast : SSD (rapide, cher)
# - slow : Stockage froid (très lent, très pas cher)
# - replicated : Données répliquées (haute dispo)

# ANALOGIE :
# StorageClass = Catégories d'hôtels
# - standard = Hôtel 2 étoiles
# - fast = Hôtel 5 étoiles
# Vous réservez, l'hôtel est créé automatiquement

# Lister les PersistentVolumes
kubectl get persistentvolumes
kubectl get pv                         # Abréviation

# Lister les PersistentVolumeClaims
kubectl get persistentvolumeclaims
kubectl get pvc                        # Abréviation

# Détails d'un PVC
kubectl describe pvc mon-pvc

# Supprimer un PVC
kubectl delete pvc mon-pvc

# === STORAGECLASSES ===

# Lister les StorageClasses disponibles
kubectl get storageclasses
kubectl get sc                         # Abréviation

# Détails d'une StorageClass
kubectl describe storageclass standard


[OK] FICHIERS YAML (Approche déclarative)

# Kubernetes utilise des fichiers YAML pour définir les ressources
# C'est la méthode RECOMMANDÉE (Infrastructure as Code)

# === Structure d'un fichier YAML K8s ===

# Tous les fichiers K8s ont cette structure de base:
apiVersion: v1                         # Version de l'API
kind: Pod                              # Type de ressource
metadata:                              # Métadonnées
  name: mon-pod
  labels:
    app: mon-app
spec:                                  # Spécification de la ressource
  # ... configuration spécifique

# === EXEMPLE: POD ===

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80

# === EXEMPLE: DEPLOYMENT ===

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3                          # Nombre de pods
  selector:
    matchLabels:
      app: nginx
  template:                            # Template de pod
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:                    # Ressources minimales
            memory: "64Mi"
            cpu: "250m"
          limits:                      # Ressources maximales
            memory: "128Mi"
            cpu: "500m"

# === EXEMPLE: SERVICE ===

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP                      # ClusterIP, NodePort, ou LoadBalancer
  selector:
    app: nginx                         # Cible les pods avec ce label
  ports:
  - protocol: TCP
    port: 80                           # Port du service
    targetPort: 80                     # Port du conteneur

# === EXEMPLE: SERVICE NODEPORT ===

# service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080                    # Port exposé sur le node (30000-32767)

# === EXEMPLE: CONFIGMAP ===

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  APP_DEBUG: "false"
  config.properties: |
    database.host=localhost
    database.port=5432

# === EXEMPLE: SECRET ===

# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=                   # "admin" encodé en base64
  password: bW90ZGVwYXNzZTEyMw==       # "motdepasse123" encodé en base64

# Pour encoder en base64:
echo -n "admin" | base64
echo -n "motdepasse123" | base64

# === EXEMPLE: PERSISTENTVOLUMECLAIM ===

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
  - ReadWriteOnce                      # RWO, ROX, ou RWX
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard

# === EXEMPLE: INGRESS ===

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: monapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

# === EXEMPLE: NAMESPACE ===

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: development

# === EXEMPLE: POD avec Variables d'environnement ===

# pod-with-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    env:
    - name: DATABASE_HOST                      # Variable simple
      value: "postgres.default.svc.cluster.local"
    - name: DATABASE_USER                      # Depuis ConfigMap
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: db_user
    - name: DATABASE_PASSWORD                  # Depuis Secret
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    envFrom:                                   # Toutes les variables d'un ConfigMap
    - configMapRef:
        name: app-config

# === EXEMPLE: POD avec Volume ===

# pod-with-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-storage
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: data
      mountPath: /data                         # Où monter dans le conteneur
    - name: config
      mountPath: /etc/config
  volumes:
  - name: data                                 # Volume PersistentVolumeClaim
    persistentVolumeClaim:
      claimName: data-pvc
  - name: config                               # Volume ConfigMap
    configMap:
      name: app-config

# === EXEMPLE: DEPLOYMENT avec Health Checks ===

# deployment-with-probes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:1.0
        ports:
        - containerPort: 8080
        livenessProbe:                         # Vérifie si le conteneur est vivant
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:                        # Vérifie si le conteneur est prêt
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            memory: "128Mi"
            cpu: "500m"
          limits:
            memory: "256Mi"
            cpu: "1000m"


[OK] MANIPULATION DE FICHIERS YAML

# Appliquer un fichier YAML (créer ou mettre à jour)
kubectl apply -f pod.yaml
kubectl apply -f deployment.yaml

# Appliquer un dossier entier
kubectl apply -f ./manifests/
kubectl apply -f ./k8s/

# Appliquer récursivement
kubectl apply -f ./k8s/ -R

# Appliquer depuis une URL
kubectl apply -f https://example.com/deployment.yaml

# Créer depuis YAML (échoue si existe déjà)
kubectl create -f deployment.yaml

# Supprimer via YAML
kubectl delete -f deployment.yaml
kubectl delete -f ./k8s/

# Remplacer (supprime et recrée)
kubectl replace -f deployment.yaml
kubectl replace --force -f deployment.yaml

# Dry-run (tester sans appliquer)
kubectl apply -f deployment.yaml --dry-run=client
kubectl apply -f deployment.yaml --dry-run=server

# Voir le diff avant d'appliquer
kubectl diff -f deployment.yaml

# Valider un fichier YAML
kubectl apply -f deployment.yaml --dry-run=client --validate=true

# Exporter une ressource existante en YAML
kubectl get deployment nginx -o yaml > deployment.yaml
kubectl get deployment nginx -o yaml --export > deployment.yaml  # Sans metadata cluster

# Générer un YAML sans le créer
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > deployment.yaml

# Générer un Service en YAML
kubectl create service clusterip nginx --tcp=80:80 --dry-run=client -o yaml

# Éditer une ressource en YAML
kubectl edit deployment nginx
kubectl edit service nginx


[OK] LABELS ET SELECTORS

# Les labels sont des paires clé-valeur qui identifient les ressources
# Les selectors permettent de filtrer les ressources par labels

# === LABELS ===

# Voir les labels
kubectl get pods --show-labels
kubectl get pods -L app,environment    # Colonnes spécifiques

# Ajouter un label
kubectl label pod nginx-pod version=1.0
kubectl label pod nginx-pod env=prod

# Modifier un label existant
kubectl label pod nginx-pod version=2.0 --overwrite

# Supprimer un label
kubectl label pod nginx-pod version-

# === SELECTORS ===

# Filtrer par égalité
kubectl get pods -l app=nginx
kubectl get pods -l environment=production

# Filtrer par inégalité
kubectl get pods -l app!=nginx

# Filtrer plusieurs labels (ET)
kubectl get pods -l app=nginx,environment=production

# Filtrer par ensemble
kubectl get pods -l 'environment in (production,staging)'
kubectl get pods -l 'environment notin (development)'

# Filtrer par existence de label
kubectl get pods -l environment
kubectl get pods -l '!environment'     # N'a PAS le label

# Supprimer toutes les ressources avec un label
kubectl delete pods -l app=nginx


[OK] ANNOTATIONS

# Les annotations sont des métadonnées non-identifiantes (plus de détails que labels)

# Ajouter une annotation
kubectl annotate pod nginx-pod description="Mon pod nginx"
kubectl annotate pod nginx-pod managed-by="terraform"

# Voir les annotations
kubectl describe pod nginx-pod
kubectl get pod nginx-pod -o jsonpath='{.metadata.annotations}'

# Supprimer une annotation
kubectl annotate pod nginx-pod description-


[OK] DEBUGGING ET DÉPANNAGE

# === INFORMATIONS DÉTAILLÉES ===

# Événements du cluster
kubectl get events
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl get events -w                  # Watch mode
kubectl get events -n mon-namespace

# Événements d'une ressource spécifique
kubectl describe pod nom-du-pod        # Inclut les événements

# === LOGS ===

# Logs avec horodatage
kubectl logs nom-du-pod --timestamps

# Logs de tous les pods d'un deployment
kubectl logs -l app=nginx

# Logs de tous les conteneurs d'un pod
kubectl logs nom-du-pod --all-containers=true

# === STATUT DES RESSOURCES ===

# Pourquoi un pod ne démarre pas ?
kubectl describe pod nom-du-pod
kubectl get pod nom-du-pod -o yaml

# États possibles des pods:
# - Pending: En attente de scheduling
# - Running: En cours d'exécution
# - Succeeded: Terminé avec succès
# - Failed: Terminé avec erreur
# - Unknown: État inconnu
# - CrashLoopBackOff: Redémarre en boucle après crash
# - ImagePullBackOff: Impossible de télécharger l'image

# === DEBUGGING INTERACTIF ===

# Pod de debug temporaire
kubectl run debug --image=busybox -it --rm -- sh
kubectl run debug --image=nicolaka/netshoot -it --rm -- bash  # Outils réseau

# Debug d'un pod existant (Kubernetes 1.18+)
kubectl debug nom-du-pod -it --image=busybox
kubectl debug nom-du-pod -it --image=busybox --copy-to=debug-pod

# Debug d'un node
kubectl debug node/nom-du-node -it --image=busybox

# === RESSOURCES ET PERFORMANCES ===

# Utilisation CPU/Mémoire des pods
kubectl top pods
kubectl top pods -n mon-namespace
kubectl top pods --all-namespaces

# Utilisation des nodes
kubectl top nodes

# Quota de ressources
kubectl get resourcequota
kubectl describe resourcequota

# LimitRange
kubectl get limitrange
kubectl describe limitrange

# === RÉSEAU ===

# Tester la connectivité réseau
kubectl run test-pod --image=busybox -it --rm -- wget -O- http://nginx-service

# DNS debugging
kubectl run dnsutils --image=tutum/dnsutils -it --rm -- nslookup nginx-service

# === CONFIGURATION ===

# Vérifier la configuration
kubectl config view

# Tester l'authentification
kubectl auth can-i create deployments
kubectl auth can-i create deployments --as=autre-user
kubectl auth can-i '*' '*'             # Tout faire ?


[OK] MISE À L'ÉCHELLE ET AUTOSCALING

# === SCALING MANUEL ===

# Scaler un deployment
kubectl scale deployment nginx --replicas=5

# Scaler un replicaset
kubectl scale rs nginx-replicaset --replicas=3

# Scaler un statefulset
kubectl scale statefulset postgres --replicas=3

# === HORIZONTAL POD AUTOSCALER (HPA) ===

# Créer un HPA basé sur CPU
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80

# Créer un HPA basé sur mémoire (nécessite metrics-server)
kubectl autoscale deployment nginx --min=2 --max=10 --memory-percent=70

# Lister les HPAs
kubectl get hpa

# Détails d'un HPA
kubectl describe hpa nginx

# Supprimer un HPA
kubectl delete hpa nginx

# === VERTICAL POD AUTOSCALER (VPA) ===
# Note: Nécessite installation séparée du VPA

# === CLUSTER AUTOSCALER ===
# Note: Dépend du fournisseur cloud (AWS, GCP, Azure)


[OK] STRATÉGIES DE DÉPLOIEMENT

# === ROLLING UPDATE (par défaut) ===
# Met à jour progressivement les pods

# deployment.yaml avec stratégie
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1                      # Pods en plus pendant update
      maxUnavailable: 1                # Pods indisponibles pendant update
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.25

# === RECREATE ===
# Supprime tous les pods avant d'en créer de nouveaux

# deployment.yaml
spec:
  strategy:
    type: Recreate

# === BLUE-GREEN DEPLOYMENT ===
# Deux environnements (blue et green), switch via Service

# 1. Déployer version green
kubectl apply -f deployment-green.yaml

# 2. Tester green
kubectl port-forward deployment/app-green 8080:80

# 3. Switcher le Service vers green
kubectl patch service app -p '{"spec":{"selector":{"version":"green"}}}'

# 4. Supprimer blue
kubectl delete deployment app-blue

# === CANARY DEPLOYMENT ===
# Déployer nouvelle version progressivement à un sous-ensemble d'utilisateurs

# 1. Version stable (90% du trafic)
kubectl apply -f deployment-stable.yaml    # 9 replicas

# 2. Version canary (10% du trafic)
kubectl apply -f deployment-canary.yaml    # 1 replica

# 3. Si OK, augmenter progressivement le canary
kubectl scale deployment app-canary --replicas=5
kubectl scale deployment app-stable --replicas=5

# 4. Si problème, rollback canary
kubectl delete deployment app-canary


[OK] JOBS ET CRONJOBS

# === JOBS (Tâches ponctuelles) ===

# QU'EST-CE QU'UN JOB ?
# Un Job = Tâche qui s'exécute jusqu'à COMPLÉTION puis s'arrête
# Contrairement à un Deployment qui tourne en continu

# QUAND UTILISER UN JOB ?
# [OK] Traitement de données (ETL, import CSV)
# [OK] Backup de base de données
# [OK] Envoi d'emails en masse
# [OK] Calculs scientifiques
# [OK] Migration de données
# [OK] Génération de rapports

# ANALOGIE :
# Deployment = Lumière qui reste allumée 24/7
# Job = Minuteur qui s'éteint automatiquement après la tâche

# === DIFFÉRENCES Job vs Deployment ===

# ┌────────────────────────────────────────────────────┐
# │ Aspect          │ Deployment      │ Job            │
# ├─────────────────┼─────────────────┼────────────────┤
# │ Durée           │ Infini          │ Jusqu'à succès │
# │ Redémarrage     │ Toujours        │ Si échec       │
# │ restartPolicy   │ Always          │ Never/OnFailure│
# │ Suppression pod │ Recrée          │ Ne recrée pas  │
# │ Cas d'usage     │ Web app, API    │ Batch, scripts │
# └────────────────────────────────────────────────────┘

# === COMPORTEMENTS DES JOBS ===

# completions : Nombre d'exécutions RÉUSSIES nécessaires
# completions: 1 -> Exécuter 1 fois avec succès
# completions: 10 -> Exécuter 10 fois avec succès

# parallelism : Nombre d'exécutions SIMULTANÉES
# parallelism: 1 -> Une à la fois (séquentiel)
# parallelism: 3 -> Trois en même temps (parallèle)

# backoffLimit : Nombre de TENTATIVES en cas d'échec
# backoffLimit: 4 -> Essayer 4 fois max avant d'abandonner

# EXEMPLE CONCRET :
# Vous devez traiter 100 fichiers
# completions: 100 -> Traiter les 100 fichiers
# parallelism: 10 -> 10 à la fois
# Résultat : 10 pods tournent en parallèle jusqu'à ce que les 100 soient faits

# === STRATÉGIES DE RETRY ===

# Quand un Job échoue, Kubernetes attend avant de réessayer :
# - 1ère tentative : immédiatement
# - 2ème tentative : 10 secondes
# - 3ème tentative : 20 secondes
# - 4ème tentative : 40 secondes
# - etc. (backoff exponentiel)

# Maximum : 6 minutes entre les tentatives

# === NETTOYAGE DES JOBS ===

# Les pods d'un Job terminé restent (pour voir les logs)
# Pour nettoyer automatiquement :
# ttlSecondsAfterFinished: 100 -> Supprimer 100s après fin

# === CRONJOBS (Tâches planifiées) ===

# QU'EST-CE QU'UN CRONJOB ?
# CronJob = Job qui s'exécute AUTOMATIQUEMENT selon un planning
# Comme cron Linux, mais dans Kubernetes

# QUAND UTILISER UN CRONJOB ?
# [OK] Backup quotidien (tous les jours à 2h)
# [OK] Nettoyage de fichiers temporaires (toutes les heures)
# [OK] Envoi de newsletter hebdomadaire (chaque lundi)
# [OK] Récupération de données d'API (toutes les 5 min)
# [OK] Génération de rapports mensuels (le 1er de chaque mois)

# ANALOGIE :
# Job = Alarme ponctuelle (une fois)
# CronJob = Alarme répétitive (tous les jours à 7h)

# === FORMAT CRON ===

# Syntaxe : "minute heure jour mois jour-semaine"
# Champs :
# ┌───────────── minute (0 - 59)
# │ ┌───────────── heure (0 - 23)
# │ │ ┌───────────── jour du mois (1 - 31)
# │ │ │ ┌───────────── mois (1 - 12)
# │ │ │ │ ┌───────────── jour de la semaine (0 - 6) (Dimanche=0)
# │ │ │ │ │
# * * * * *

# EXEMPLES COURANTS :
# "0 2 * * *"      -> Tous les jours à 2h00
# "*/5 * * * *"    -> Toutes les 5 minutes
# "0 */2 * * *"    -> Toutes les 2 heures (0h, 2h, 4h...)
# "0 9-17 * * 1-5" -> Heures de bureau (9h-17h, Lun-Ven)
# "0 0 1 * *"      -> Le 1er de chaque mois à minuit
# "0 0 * * 0"      -> Tous les dimanches à minuit
# "30 3 * * 6"     -> Tous les samedis à 3h30

# === POLITIQUES DE CONCURRENCE ===

# Que faire si un Job précédent n'est pas terminé ?

# Allow (défaut) :
# - Lance le nouveau Job MÊME si l'ancien tourne encore
# - Peut avoir plusieurs Jobs en parallèle
# Risque : Surcharge si Jobs trop lents

# Forbid :
# - SAUTE le nouveau Job si l'ancien tourne
# - Attend que l'ancien soit fini
# Usage : Éviter doublons (backup, envoi email)

# Replace :
# - ANNULE l'ancien Job
# - Lance le nouveau à la place
# Usage : Seul le dernier compte (fetch données API)

# === HISTORIQUE DES JOBS ===

# successfulJobsHistoryLimit: 3
# Garde les 3 derniers Jobs réussis (pour les logs)

# failedJobsHistoryLimit: 1
# Garde le dernier Job échoué (pour debug)

# Pourquoi pas plus ? Économiser les ressources
# Les pods des anciens Jobs prennent de la place

# Créer un job simple
kubectl create job hello --image=busybox -- echo "Hello World"

# Lister les jobs
kubectl get jobs

# Détails d'un job
kubectl describe job hello

# Logs d'un job
kubectl logs job/hello

# Supprimer un job (et ses pods)
kubectl delete job hello

# === Exemple Job YAML ===

# job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-calculation
spec:
  completions: 1                       # Nombre d'exécutions réussies
  parallelism: 1                       # Nombre d'exécutions parallèles
  backoffLimit: 4                      # Nombre de tentatives en cas d'échec
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never             # Never ou OnFailure pour Jobs

# Job parallèle avec queue
apiVersion: batch/v1
kind: Job
metadata:
  name: process-queue
spec:
  completions: 10                      # 10 tâches à compléter
  parallelism: 3                       # 3 à la fois
  template:
    spec:
      containers:
      - name: worker
        image: myapp:1.0
      restartPolicy: OnFailure

# === CRONJOBS (Tâches planifiées) ===

# Créer un cronjob
kubectl create cronjob hello --image=busybox --schedule="*/1 * * * *" -- echo "Hello"

# Lister les cronjobs
kubectl get cronjobs
kubectl get cj                         # Abréviation

# Détails d'un cronjob
kubectl describe cronjob hello

# Suspendre un cronjob
kubectl patch cronjob hello -p '{"spec":{"suspend":true}}'

# Reprendre un cronjob
kubectl patch cronjob hello -p '{"spec":{"suspend":false}}'

# Déclencher manuellement un cronjob
kubectl create job --from=cronjob/hello hello-manual-01

# Supprimer un cronjob
kubectl delete cronjob hello

# === Exemple CronJob YAML ===

# cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: backup-db
spec:
  schedule: "0 2 * * *"                # Tous les jours à 2h (format cron)
  successfulJobsHistoryLimit: 3        # Garder 3 jobs réussis
  failedJobsHistoryLimit: 1            # Garder 1 job échoué
  concurrencyPolicy: Forbid            # Allow, Forbid, ou Replace
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: backup-tool:1.0
            command:
            - /bin/sh
            - -c
            - "backup-script.sh"
          restartPolicy: OnFailure

# Formats schedule (cron):
# "*/5 * * * *"    - Toutes les 5 minutes
# "0 * * * *"      - Toutes les heures
# "0 0 * * *"      - Tous les jours à minuit
# "0 0 * * 0"      - Tous les dimanches à minuit
# "0 0 1 * *"      - Le 1er de chaque mois
# "0 9-17 * * 1-5" - Heures de bureau (9h-17h, Lun-Ven)


[OK] DAEMONSETS

# Les DaemonSets déploient un pod sur chaque node du cluster
# Utilisés pour: monitoring, logging, storage, networking

# Lister les daemonsets
kubectl get daemonsets
kubectl get ds                         # Abréviation

# Détails d'un daemonset
kubectl describe daemonset nom-ds

# === Exemple DaemonSet YAML ===

# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluentd:v1.14
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

# Supprimer un daemonset
kubectl delete daemonset fluentd


[OK] STATEFULSETS

# StatefulSets gèrent des applications stateful (bases de données, etc.)
# Fournissent: identité réseau stable, stockage persistant, déploiement ordonné

# Lister les statefulsets
kubectl get statefulsets
kubectl get sts                        # Abréviation

# Détails d'un statefulset
kubectl describe statefulset postgres

# Scaler un statefulset
kubectl scale statefulset postgres --replicas=3

# === Exemple StatefulSet YAML ===

# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres                # Service headless requis
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        ports:
        - containerPort: 5432
          name: postgres
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:                # PVC créé automatiquement pour chaque pod
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

# Service Headless pour StatefulSet
# service-headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  clusterIP: None                      # Headless service
  selector:
    app: postgres
  ports:
  - port: 5432
    name: postgres

# Supprimer un statefulset
kubectl delete statefulset postgres

# Supprimer statefulset mais garder les pods
kubectl delete statefulset postgres --cascade=orphan


[OK] INGRESS (Routage HTTP/HTTPS)

# Ingress expose les services HTTP/HTTPS à l'extérieur du cluster
# Nécessite un Ingress Controller (nginx, traefik, etc.)

# Activer ingress dans Minikube
minikube addons enable ingress

# Lister les ingress
kubectl get ingress
kubectl get ing                        # Abréviation

# Détails d'un ingress
kubectl describe ingress mon-ingress

# === Exemple Ingress Simple ===

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

# === Ingress avec plusieurs chemins ===

# ingress-multi-path.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-path-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

# === Ingress avec TLS ===

# ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: tls-secret               # Secret contenant cert et key
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

# === Ingress avec plusieurs hôtes ===

# ingress-multi-host.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

# Supprimer un ingress
kubectl delete ingress mon-ingress


[OK] NETWORKPOLICIES (Sécurité réseau)

# NetworkPolicies contrôlent le trafic réseau entre les pods
# Note: Nécessite un plugin CNI compatible (Calico, Cilium, etc.)

# Lister les network policies
kubectl get networkpolicies
kubectl get netpol                     # Abréviation

# === Exemple: Bloquer tout le trafic ===

# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}                      # Sélectionne tous les pods
  policyTypes:
  - Ingress
  - Egress

# === Exemple: Autoriser trafic spécifique ===

# allow-api.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api
spec:
  podSelector:
    matchLabels:
      app: api                         # S'applique aux pods "api"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend                # Autorise depuis pods "frontend"
    ports:
    - protocol: TCP
      port: 8080

# === Exemple: Autoriser DNS ===

# allow-dns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53

# Supprimer une network policy
kubectl delete networkpolicy deny-all


[OK] RBAC (Role-Based Access Control)

# RBAC contrôle qui peut faire quoi dans le cluster

# === ROLES (Permissions dans un namespace) ===

# Lister les roles
kubectl get roles
kubectl get roles -A                   # Tous les namespaces

# Détails d'un role
kubectl describe role mon-role

# === Exemple Role ===

# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]                      # "" = core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

# === ROLEBINDINGS (Attribuer un Role) ===

# Lister les rolebindings
kubectl get rolebindings
kubectl get rolebindings -A

# === Exemple RoleBinding ===

# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

# === CLUSTERROLES (Permissions cluster-wide) ===

# Lister les clusterroles
kubectl get clusterroles

# === Exemple ClusterRole ===

# clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

# === CLUSTERROLEBINDINGS ===

# Lister les clusterrolebindings
kubectl get clusterrolebindings

# === Exemple ClusterRoleBinding ===

# clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

# === SERVICE ACCOUNTS ===

# Créer un service account
kubectl create serviceaccount mon-sa

# Lister les service accounts
kubectl get serviceaccounts
kubectl get sa                         # Abréviation

# Lier un role à un service account
kubectl create rolebinding mon-binding \
  --role=pod-reader \
  --serviceaccount=default:mon-sa

# Utiliser un service account dans un pod
# pod-with-sa.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: mon-sa
  containers:
  - name: app
    image: myapp:1.0

# Vérifier permissions
kubectl auth can-i get pods --as=system:serviceaccount:default:mon-sa


[OK] RESSOURCES ET LIMITES

# Kubernetes gère les ressources CPU et mémoire pour chaque conteneur

# === CPU ===
# Unités:
# - 1 CPU = 1000m (millicores)
# - 500m = 0.5 CPU
# - 100m = 0.1 CPU

# === MÉMOIRE ===
# Unités:
# - Ki (kibibyte), Mi (mebibyte), Gi (gibibyte)
# - 128974848, 129e6, 129M, 123Mi

# === Exemple avec requests et limits ===

# deployment-resources.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:1.0
        resources:
          requests:                    # Minimum garanti
            memory: "64Mi"
            cpu: "250m"
          limits:                      # Maximum autorisé
            memory: "128Mi"
            cpu: "500m"

# === RESOURCEQUOTA (Limites par namespace) ===

# resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "10"                 # Total requests CPU
    requests.memory: 20Gi              # Total requests mémoire
    limits.cpu: "20"                   # Total limits CPU
    limits.memory: 40Gi                # Total limits mémoire
    pods: "20"                         # Nombre max de pods
    services: "10"                     # Nombre max de services
    persistentvolumeclaims: "5"        # Nombre max de PVCs

# Lister les quotas
kubectl get resourcequota
kubectl describe resourcequota compute-quota

# === LIMITRANGE (Limites par défaut) ===

# limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-cpu-limit
  namespace: development
spec:
  limits:
  - max:                               # Maximum par conteneur
      memory: "1Gi"
      cpu: "1"
    min:                               # Minimum par conteneur
      memory: "64Mi"
      cpu: "100m"
    default:                           # Limite par défaut
      memory: "512Mi"
      cpu: "500m"
    defaultRequest:                    # Request par défaut
      memory: "256Mi"
      cpu: "250m"
    type: Container

# Lister les limitranges
kubectl get limitrange
kubectl describe limitrange mem-cpu-limit


[OK] HEALTH CHECKS (PROBES)

# Kubernetes vérifie la santé des conteneurs avec des probes

# === TYPES DE PROBES ===

# 1. livenessProbe: Vérifie si le conteneur est vivant
#    Si échec: Kubernetes redémarre le conteneur

# 2. readinessProbe: Vérifie si le conteneur est prêt à recevoir du trafic
#    Si échec: Retire le pod du service

# 3. startupProbe: Vérifie le démarrage initial (apps lentes)
#    Si échec après délai: Tue le conteneur

# === TYPES DE CHECKS ===

# 1. HTTP GET
# 2. TCP Socket
# 3. Exec Command

# === Exemple avec HTTP GET ===

# deployment-probes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: app
        image: myapp:1.0
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30      # Attendre 30s avant première vérif
          periodSeconds: 10            # Vérifier toutes les 10s
          timeoutSeconds: 5            # Timeout après 5s
          successThreshold: 1          # 1 succès = OK
          failureThreshold: 3          # 3 échecs = KO
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        startupProbe:
          httpGet:
            path: /startup
            port: 8080
          initialDelaySeconds: 0
          periodSeconds: 10
          failureThreshold: 30         # 30*10s = 5min max pour démarrer

# === Exemple avec TCP Socket ===

# deployment-tcp-probe.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
spec:
  template:
    spec:
      containers:
      - name: postgres
        image: postgres:15
        livenessProbe:
          tcpSocket:
            port: 5432
          initialDelaySeconds: 15
          periodSeconds: 20
        readinessProbe:
          tcpSocket:
            port: 5432
          initialDelaySeconds: 5
          periodSeconds: 10

# === Exemple avec Exec Command ===

# deployment-exec-probe.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:1.0
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - "pg_isready -U postgres"
          initialDelaySeconds: 5
          periodSeconds: 10


[OK] INIT CONTAINERS

# Init containers s'exécutent AVANT les conteneurs principaux
# Utilisés pour: initialisation, attente de dépendances, configuration

# === Exemple Init Container ===

# pod-with-init.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  initContainers:
  - name: init-db
    image: busybox:1.35
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done']
  - name: init-config
    image: busybox:1.35
    command: ['sh', '-c', 'echo "Config ready" > /work-dir/config.txt']
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: workdir
      mountPath: /config
  volumes:
  - name: workdir
    emptyDir: {}

# Voir les logs d'un init container
kubectl logs mon-pod -c init-db


[OK] TAINTS ET TOLERATIONS

# Taints: Marquent les nodes pour repousser certains pods
# Tolerations: Permettent aux pods de tolérer certains taints

# === TAINTS ===

# Ajouter un taint à un node
kubectl taint nodes node1 key=value:NoSchedule
kubectl taint nodes node1 key=value:NoExecute
kubectl taint nodes node1 key=value:PreferNoSchedule

# Effets:
# - NoSchedule: Nouveaux pods ne sont pas schedulés
# - NoExecute: Pods existants sont évincés
# - PreferNoSchedule: Essayer d'éviter mais pas strict

# Lister les taints d'un node
kubectl describe node node1 | grep Taints

# Supprimer un taint
kubectl taint nodes node1 key=value:NoSchedule-

# === TOLERATIONS ===

# pod-with-toleration.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: app
    image: myapp:1.0

# Tolération avec operator Exists
spec:
  tolerations:
  - key: "key"
    operator: "Exists"
    effect: "NoSchedule"

# Tolérer tous les taints
spec:
  tolerations:
  - operator: "Exists"


[OK] NODE AFFINITY ET POD AFFINITY

# === NODE AFFINITY (Planifier pods sur nodes spécifiques) ===

# pod-node-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:    # REQUIS
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:   # PRÉFÉRÉ
      - weight: 1
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values:
            - us-west-1a
  containers:
  - name: app
    image: myapp:1.0

# Opérateurs: In, NotIn, Exists, DoesNotExist, Gt, Lt

# === POD AFFINITY (Co-location de pods) ===

# pod-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: backend
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - frontend
        topologyKey: kubernetes.io/hostname
  containers:
  - name: backend
    image: backend:1.0

# === POD ANTI-AFFINITY (Séparation de pods) ===

# deployment-anti-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - webapp
            topologyKey: kubernetes.io/hostname    # Pas 2 pods sur même node
      containers:
      - name: app
        image: webapp:1.0


[OK] HELM (Gestionnaire de packages K8s)

# Helm est le gestionnaire de packages pour Kubernetes
# Charts = packages Helm (ensemble de fichiers YAML)

# === INSTALLATION DE HELM ===

# Linux/macOS
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# macOS (Homebrew)
brew install helm

# Windows (Chocolatey)
choco install kubernetes-helm

# Vérifier installation
helm version

# === UTILISATION DE HELM ===

# Ajouter un repository
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami

# Lister les repos
helm repo list

# Mettre à jour les repos
helm repo update

# Rechercher un chart
helm search repo nginx
helm search repo wordpress

# Inspecter un chart
helm show chart bitnami/nginx
helm show values bitnami/nginx           # Voir les valeurs par défaut

# Installer un chart
helm install mon-nginx bitnami/nginx
helm install mon-wp bitnami/wordpress --namespace wp --create-namespace

# Installer avec valeurs personnalisées
helm install mon-nginx bitnami/nginx --set service.type=LoadBalancer
helm install mon-nginx bitnami/nginx -f values.yaml

# values.yaml
replicaCount: 3
service:
  type: NodePort
  port: 8080

# Lister les releases
helm list
helm list -A                             # Tous les namespaces

# Voir le statut d'une release
helm status mon-nginx

# Mettre à jour une release
helm upgrade mon-nginx bitnami/nginx --set replicaCount=5
helm upgrade mon-nginx bitnami/nginx -f values.yaml

# Rollback d'une release
helm rollback mon-nginx
helm rollback mon-nginx 1                # Vers révision spécifique

# Voir l'historique
helm history mon-nginx

# Désinstaller une release
helm uninstall mon-nginx
helm uninstall mon-nginx --keep-history  # Garder l'historique

# === CRÉER UN CHART HELM ===

# Créer un nouveau chart
helm create mon-app

# Structure créée:
# mon-app/
#   Chart.yaml           # Métadonnées du chart
#   values.yaml          # Valeurs par défaut
#   charts/              # Dépendances
#   templates/           # Templates K8s
#     deployment.yaml
#     service.yaml
#     ingress.yaml
#     _helpers.tpl

# Valider un chart
helm lint mon-app

# Packager un chart
helm package mon-app

# Installer un chart local
helm install mon-app ./mon-app

# Dry-run (tester sans installer)
helm install mon-app ./mon-app --dry-run --debug

# Voir le YAML qui sera appliqué
helm template mon-app ./mon-app


[OK] KUSTOMIZE (Gestion de configuration)

# Kustomize permet de personnaliser les manifests K8s sans les modifier
# Intégré dans kubectl depuis v1.14

# === Structure de base ===

# base/
#   deployment.yaml
#   service.yaml
#   kustomization.yaml
# overlays/
#   dev/
#     kustomization.yaml
#   prod/
#     kustomization.yaml

# === base/kustomization.yaml ===
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

# === overlays/dev/kustomization.yaml ===
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
namePrefix: dev-
namespace: development
replicas:
- name: myapp
  count: 1

# === overlays/prod/kustomization.yaml ===
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
namePrefix: prod-
namespace: production
replicas:
- name: myapp
  count: 5
images:
- name: myapp
  newTag: v2.0.0

# Appliquer avec kustomize
kubectl apply -k overlays/dev/
kubectl apply -k overlays/prod/

# Voir le YAML généré
kubectl kustomize overlays/dev/
kubectl kustomize overlays/prod/


[OK] MONITORING ET OBSERVABILITÉ

# === METRICS SERVER ===

# Installer metrics-server (Minikube)
minikube addons enable metrics-server

# Installer metrics-server (Cluster)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Voir les métriques
kubectl top nodes
kubectl top pods
kubectl top pods -A

# === DASHBOARD KUBERNETES ===

# Installer dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# Créer un user admin pour le dashboard
# dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

# Obtenir le token
kubectl -n kubernetes-dashboard create token admin-user

# Accéder au dashboard (proxy)
kubectl proxy

# URL: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

# Minikube dashboard
minikube dashboard

# === PROMETHEUS ET GRAFANA ===

# Installer avec Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack

# Port-forward Grafana
kubectl port-forward -n default svc/prometheus-grafana 3000:80

# Credentials par défaut:
# Username: admin
# Password: prom-operator


[OK] BACKUP ET RESTORE

# === VELERO (Backup complet du cluster) ===

# Installer Velero CLI
# https://velero.io/docs/main/basic-install/

# Installer Velero dans le cluster (exemple AWS)
velero install \
  --provider aws \
  --plugins velero/velero-plugin-for-aws:v1.8.0 \
  --bucket velero-backups \
  --backup-location-config region=us-west-2 \
  --snapshot-location-config region=us-west-2 \
  --secret-file ./credentials-velero

# Créer un backup
velero backup create mon-backup
velero backup create mon-backup --include-namespaces=production

# Lister les backups
velero backup get

# Restaurer un backup
velero restore create --from-backup mon-backup

# Backup planifié
velero schedule create daily-backup --schedule="0 2 * * *"

# === ETCD BACKUP (Control Plane) ===

# Backup etcd
ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# Vérifier snapshot
ETCDCTL_API=3 etcdctl snapshot status snapshot.db

# Restaurer etcd
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
  --data-dir=/var/lib/etcd-restore


[OK] SÉCURITÉ

# === SECURITY CONTEXTS ===

# pod-security.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsUser: 1000                    # UID utilisateur
    runAsGroup: 3000                   # GID groupe
    fsGroup: 2000                      # Groupe filesystem
  containers:
  - name: app
    image: myapp:1.0
    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

# === POD SECURITY STANDARDS (PSS) ===

# Appliquer au namespace
kubectl label namespace mon-ns \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

# Niveaux: privileged, baseline, restricted

# === POD SECURITY POLICIES (PSP) - Deprecated ===
# Remplacé par Pod Security Admission depuis K8s 1.25

# === NETWORK POLICIES (Voir section précédente) ===

# === SECRETS ENCRYPTION AT REST ===

# Vérifier si les secrets sont chiffrés
kubectl get secret -o yaml | grep "encryption"

# === IMAGE SCANNING ===

# Trivy (scanner de vulnérabilités)
trivy image myapp:1.0
trivy image --severity HIGH,CRITICAL nginx:latest


[OK] KUBECTL PLUGINS ET OUTILS

# === KREW (Gestionnaire de plugins kubectl) ===

# Installer Krew
# https://krew.sigs.k8s.io/docs/user-guide/setup/install/

# Lister les plugins disponibles
kubectl krew search

# Installer un plugin
kubectl krew install ctx
kubectl krew install ns
kubectl krew install tree

# Mettre à jour les plugins
kubectl krew upgrade

# === KUBECTX (Changer de contexte facilement) ===

# Installer
kubectl krew install ctx

# Utiliser
kubectl ctx                            # Lister contextes
kubectl ctx minikube                   # Changer de contexte
kubectl ctx -                          # Contexte précédent

# === KUBENS (Changer de namespace facilement) ===

# Installer
kubectl krew install ns

# Utiliser
kubectl ns                             # Lister namespaces
kubectl ns development                 # Changer de namespace
kubectl ns -                           # Namespace précédent

# === K9S (Interface TUI pour Kubernetes) ===

# Installer
brew install derailed/k9s/k9s         # macOS
choco install k9s                      # Windows

# Lancer
k9s

# Raccourcis dans k9s:
# :pod     - Voir pods
# :svc     - Voir services
# :deploy  - Voir deployments
# /        - Filtrer
# l        - Logs
# d        - Describe
# e        - Edit
# Ctrl-d   - Supprimer

# === KUBECTL ALIASES ===

# Ajouter à ~/.bashrc ou ~/.zshrc
alias k='kubectl'
alias kg='kubectl get'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kd='kubectl describe'
alias kdp='kubectl describe pod'
alias kl='kubectl logs'
alias klf='kubectl logs -f'
alias ke='kubectl exec -it'
alias ka='kubectl apply -f'
alias kdel='kubectl delete'

# Avec completion
source <(kubectl completion bash)
complete -F __start_kubectl k

# === STERN (Logs multi-pods) ===

# Installer
brew install stern                     # macOS

# Voir logs de plusieurs pods
stern app                              # Tous les pods contenant "app"
stern --namespace production app
stern --selector app=nginx


[OK] CI/CD AVEC KUBERNETES

# === FLUX CD (GitOps) ===

# Installer Flux CLI
brew install fluxcd/tap/flux          # macOS

# Bootstrap Flux
flux bootstrap github \
  --owner=mon-org \
  --repository=mon-repo \
  --path=clusters/production

# Créer une source Git
flux create source git mon-app \
  --url=https://github.com/mon-org/mon-app \
  --branch=main

# Créer un Kustomization
flux create kustomization mon-app \
  --source=mon-app \
  --path="./deploy" \
  --prune=true

# === ARGOCD (GitOps) ===

# Installer ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Accéder à l'UI
kubectl port-forward svc/argocd-server -n argocd 8080:443

# Obtenir le mot de passe admin
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# Installer ArgoCD CLI
brew install argocd                    # macOS

# Login
argocd login localhost:8080

# Créer une application
argocd app create mon-app \
  --repo https://github.com/mon-org/mon-app.git \
  --path deploy \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace default

# Sync
argocd app sync mon-app

# === JENKINS X ===

# Installer jx CLI
brew install jenkins-x/jx/jx         # macOS

# Créer un cluster Jenkins X
jx boot


[OK] MULTI-CLUSTER

# === KUBEFED (Federation) ===

# Fédération de plusieurs clusters K8s
# https://github.com/kubernetes-sigs/kubefed

# === RANCHER (Gestion multi-cluster) ===

# Interface web pour gérer plusieurs clusters
# https://rancher.com/

# === CONTEXTES MULTIPLES ===

# Ajouter un cluster au kubeconfig
kubectl config set-cluster cluster2 \
  --server=https://cluster2.example.com \
  --certificate-authority=ca.crt

# Ajouter user
kubectl config set-credentials user2 \
  --client-certificate=client.crt \
  --client-key=client.key

# Créer contexte
kubectl config set-context cluster2-context \
  --cluster=cluster2 \
  --user=user2 \
  --namespace=default

# Fusionner plusieurs kubeconfig
KUBECONFIG=~/.kube/config:~/.kube/config2 kubectl config view --flatten > ~/.kube/merged
cp ~/.kube/merged ~/.kube/config


[OK] TROUBLESHOOTING AVANCÉ

# === POD NE DÉMARRE PAS ===

# 1. Vérifier statut
kubectl get pod nom-pod -o wide
kubectl describe pod nom-pod

# 2. Vérifier events
kubectl get events --sort-by=.metadata.creationTimestamp

# 3. Erreurs communes:
# - ImagePullBackOff: Image introuvable ou credentials invalides
# - CrashLoopBackOff: Conteneur crash au démarrage
# - Pending: Ressources insuffisantes ou contraintes non satisfaites
# - Error: Commande du conteneur a échoué

# 4. Vérifier les logs
kubectl logs nom-pod
kubectl logs nom-pod --previous        # Logs avant crash

# 5. Débugger interactivement
kubectl debug nom-pod -it --image=busybox --copy-to=debug-pod

# === SERVICE N'EST PAS ACCESSIBLE ===

# 1. Vérifier le service
kubectl get svc nom-service
kubectl describe svc nom-service

# 2. Vérifier les endpoints
kubectl get endpoints nom-service

# 3. Tester depuis un pod
kubectl run test --image=busybox -it --rm -- wget -O- http://nom-service

# 4. Vérifier les labels
kubectl get pods --show-labels
kubectl get svc nom-service -o yaml    # Vérifier selector

# 5. Tester le pod directement
kubectl port-forward pod/nom-pod 8080:80

# === DNS NE FONCTIONNE PAS ===

# 1. Vérifier CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 2. Tester DNS
kubectl run dnsutils --image=tutum/dnsutils -it --rm -- nslookup kubernetes.default

# 3. Vérifier la config CoreDNS
kubectl get configmap coredns -n kube-system -o yaml

# === NODES INDISPONIBLES ===

# 1. Vérifier statut des nodes
kubectl get nodes

# 2. Détails du node
kubectl describe node nom-node

# 3. Drainer un node (maintenance)
kubectl drain nom-node --ignore-daemonsets --delete-emptydir-data

# 4. Marquer un node comme non-schedulable
kubectl cordon nom-node

# 5. Remettre en service
kubectl uncordon nom-node

# === PROBLÈMES DE CERTIFICATS ===

# Vérifier expiration des certificats
kubeadm certs check-expiration

# Renouveler les certificats
kubeadm certs renew all

# === NETTOYAGE RESSOURCES ===

# Supprimer pods en état Evicted
kubectl get pods -A | grep Evicted | awk '{print $2 " -n " $1}' | xargs -L1 kubectl delete pod

# Supprimer pods Completed
kubectl delete pods --field-selector=status.phase==Succeeded -A

# Forcer suppression d'un pod
kubectl delete pod nom-pod --grace-period=0 --force

# === AUDIT LOGS ===

# Activer audit logging (à configurer sur l'API server)
# /etc/kubernetes/manifests/kube-apiserver.yaml


[OK] PERFORMANCE ET OPTIMISATION

# === HORIZONTAL POD AUTOSCALER (HPA) ===

# Basé sur CPU
kubectl autoscale deployment mon-app --cpu-percent=50 --min=1 --max=10

# Basé sur mémoire (avec metrics custom)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mon-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mon-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 70

# === VERTICAL POD AUTOSCALER (VPA) ===

# Installer VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh

# vpa.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: mon-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mon-app
  updatePolicy:
    updateMode: "Auto"                 # Auto, Recreate, Initial, Off

# === POD PRIORITY ===

# priorityclass.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "High priority pods"

# Utiliser dans un pod
spec:
  priorityClassName: high-priority
  containers:
  - name: app
    image: myapp:1.0

# === POD DISRUPTION BUDGET (PDB) ===

# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mon-app-pdb
spec:
  minAvailable: 2                      # Min 2 pods disponibles
  # OU
  maxUnavailable: 1                    # Max 1 pod indisponible
  selector:
    matchLabels:
      app: mon-app


[OK] PATTERNS ET BEST PRACTICES

# === SIDECAR PATTERN ===

# Conteneur auxiliaire aux côtés du conteneur principal
# Exemple: logging, monitoring, proxy

# pod-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: logs
      mountPath: /var/log
  - name: log-shipper
    image: fluentd:latest
    volumeMounts:
    - name: logs
      mountPath: /var/log
  volumes:
  - name: logs
    emptyDir: {}

# === AMBASSADOR PATTERN ===

# Proxy qui masque la complexité réseau

# === ADAPTER PATTERN ===

# Standardise l'output d'un conteneur

# === BLUE-GREEN DEPLOYMENT ===

# Deux environnements identiques, switch instantané

# 1. Déployer version green
kubectl apply -f deployment-green.yaml

# 2. Service pointe vers blue
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
    version: blue                      # Pointe vers blue
  ports:
  - port: 80

# 3. Switcher vers green
kubectl patch service app-service -p '{"spec":{"selector":{"version":"green"}}}'

# === IMMUTABLE INFRASTRUCTURE ===

# Ne jamais modifier pods en cours d'exécution
# Toujours créer nouveaux pods avec nouvelles images

# === 12-FACTOR APP ===

# 1. Codebase: Un repo, plusieurs déploiements
# 2. Dependencies: Déclarer explicitement
# 3. Config: Stocker dans l'environnement (ConfigMaps/Secrets)
# 4. Backing services: Traiter comme ressources attachées
# 5. Build/Release/Run: Séparer strictement
# 6. Processes: Stateless et share-nothing
# 7. Port binding: Exporter services via port
# 8. Concurrency: Scale via process model
# 9. Disposability: Fast startup et graceful shutdown
# 10. Dev/Prod parity: Garder similaires
# 11. Logs: Traiter comme event streams
# 12. Admin processes: One-off via Jobs


[OK] COMMANDES UTILES ET RACCOURCIS

# === COMPLETION ET ALIASES ===

# Bash completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

# Zsh completion
source <(kubectl completion zsh)
echo "source <(kubectl completion zsh)" >> ~/.zshrc

# Alias k
alias k=kubectl
complete -F __start_kubectl k

# === JSONPATH ===

# Extraire des valeurs spécifiques
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o jsonpath='{.items[*].status.podIP}'
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'

# === OUTPUT FORMATS ===

kubectl get pods -o wide              # Plus de colonnes
kubectl get pods -o yaml              # Format YAML
kubectl get pods -o json              # Format JSON
kubectl get pods -o name              # Juste les noms
kubectl get pods -o json | jq '.items[0].spec.containers[0].image'

# === WATCH MODE ===

kubectl get pods -w                   # Watch changes
watch kubectl get pods                # Rafraîchir toutes les 2s

# === FIELD SELECTORS ===

kubectl get pods --field-selector status.phase=Running
kubectl get pods --field-selector status.phase!=Running
kubectl get services --field-selector metadata.namespace=default

# === EXPORT YAML PROPRE ===

kubectl get deployment nginx -o yaml --export > deployment.yaml

# Ou nettoyer manuellement
kubectl get deployment nginx -o yaml | \
  yq eval 'del(.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .status)' - > deployment.yaml

# === FORCER RECRÉATION ===

kubectl replace --force -f pod.yaml

# === ATTENDRE QU'UNE RESSOURCE SOIT READY ===

kubectl wait --for=condition=ready pod -l app=nginx --timeout=60s
kubectl wait --for=condition=available deployment/nginx --timeout=120s

# === COMPARER RESSOURCES ===

kubectl diff -f deployment.yaml


[OK] EXEMPLES COMPLETS D'APPLICATIONS

# === APPLICATION WEB COMPLÈTE ===

# 1. Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: webapp

---
# 2. ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: webapp
data:
  APP_ENV: production
  LOG_LEVEL: info

---
# 3. Secret
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: webapp
type: Opaque
data:
  db-password: cGFzc3dvcmQxMjM=        # password123

---
# 4. PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
  namespace: webapp
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

---
# 5. Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: app
        image: myapp:2.0
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: db-password
        resources:
          requests:
            memory: "128Mi"
            cpu: "250m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: app-pvc

---
# 6. Service
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
  namespace: webapp
spec:
  type: ClusterIP
  selector:
    app: webapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

---
# 7. Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webapp-ingress
  namespace: webapp
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: webapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp-service
            port:
              number: 80

---
# 8. HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: webapp-hpa
  namespace: webapp
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: webapp
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

# Appliquer tout
kubectl apply -f webapp-complete.yaml


[OK] RESSOURCES ET DOCUMENTATION

# Documentation officielle
# https://kubernetes.io/docs/

# Tutoriels interactifs
# https://kubernetes.io/docs/tutorials/

# Playground gratuit
# https://labs.play-with-k8s.com/

# Certifications
# CKA - Certified Kubernetes Administrator
# CKAD - Certified Kubernetes Application Developer
# CKS - Certified Kubernetes Security Specialist

# Cheat Sheet officiel
# https://kubernetes.io/docs/reference/kubectl/cheatsheet/

# Awesome Kubernetes
# https://github.com/ramitsurana/awesome-kubernetes

# CNCF Landscape
# https://landscape.cncf.io/


[OK] GLOSSAIRE

# API Server: Point d'entrée de toutes les commandes
# Control Plane: Composants de gestion du cluster
# CNI: Container Network Interface
# CSI: Container Storage Interface
# CRI: Container Runtime Interface
# etcd: Base de données clé-valeur du cluster
# kubelet: Agent sur chaque node
# kube-proxy: Gestion réseau sur chaque node
# Controller Manager: Gère les controllers
# Scheduler: Assigne les pods aux nodes
# Manifest: Fichier YAML de configuration
# Reconciliation: Processus de convergence vers l'état désiré
# Declarative: Décrire l'état désiré (vs impératif)
# Imperative: Commandes directes
# Operator: Extension qui automatise tâches opérationnelles
# CRD: Custom Resource Definition
# Finalizer: Logique de nettoyage avant suppression
# Admission Controller: Intercepte requêtes API
# Webhook: Callback HTTP pour admission control


[OK] COMMANDES PAR FRÉQUENCE D'UTILISATION

# === TRÈS FRÉQUENT ===
kubectl get pods
kubectl get pods -A
kubectl logs nom-pod -f
kubectl describe pod nom-pod
kubectl exec -it nom-pod -- /bin/bash
kubectl apply -f fichier.yaml
kubectl delete pod nom-pod
kubectl get services
kubectl get deployments

# === FRÉQUENT ===
kubectl scale deployment nom --replicas=3
kubectl rollout restart deployment nom
kubectl port-forward pod/nom 8080:80
kubectl top pods
kubectl get events
kubectl edit deployment nom
kubectl create namespace nom
kubectl config get-contexts
kubectl config use-context nom

# === OCCASIONNEL ===
kubectl rollout history deployment nom
kubectl rollout undo deployment nom
kubectl autoscale deployment nom --min=2 --max=10 --cpu-percent=80
kubectl drain node-name
kubectl cordon node-name
kubectl taint nodes node-name key=value:NoSchedule
kubectl label pod nom key=value
kubectl annotate pod nom key=value

# === RARE / ADMINISTRATION ===
kubectl cluster-info
kubectl api-resources
kubectl api-versions
kubectl certificate approve csr-name
kubectl auth can-i create deployments
kubectl create clusterrolebinding nom --clusterrole=role --user=user