kubernetes-user

Concernant les supports de cours

Supports de cours

Les cours sont maintenus et donnés par : https://www.alterway.fr/cloud-consulting

Licence Creative Commons BY-SA 4.0
Licence Creative Commons BY-SA 4.0

KUBERNETES : Projet, Gouvernance et Communauté

  • Initialement développé par Google (Borg), devenu open source en 2014
  • 1.0 le 10 Juillet 2015
  • Adapté à tout type d'environnement
  • Devenu populaire en très peu de temps
  • Premier projet de la CNCF

CNCF

The Foundation’s mission is to create and drive the adoption of a new computing paradigm that is optimized for modern distributed systems environments capable of scaling to tens of thousands of self healing multi-tenant nodes.

Avoir son projet porté par la CNCF

  • Alignement avec les Objectifs de la CNCF
    • Technologies Cloud Natives: Votre projet doit être étroitement lié aux technologies cloud natives, telles que les conteneurs, les orchestrateurs de conteneurs (Kubernetes), les services de réseau, les systèmes de stockage distribués, et les outils de gestion du cycle de vie des applications cloud natives.
    • Open Source: Le projet doit être open source sous une licence approuvée par la CNCF (comme Apache 2.0 ou MIT).
    • Communauté Active: Il est essentiel de démontrer l'existence d'une communauté active autour du projet, avec des contributions régulières de développeurs et des utilisateurs.
  • Maturation du Projet
    • Code de Qualité: Le code source doit être bien structuré, documenté et suivre les meilleures pratiques de développement.
    • Tests Unitaires et d'Intégration: Une couverture de tests solide est nécessaire pour garantir la qualité et la stabilité du projet.
    • Documentation Complète: Une documentation claire et complète est indispensable pour permettre aux autres développeurs de comprendre et d'utiliser le projet.

CNCF : Les rôles

  • Hébergement de Projets Open Source:
    • La CNCF héberge un grand nombre de projets open source populaires, tels que Kubernetes, Prometheus, Envoy, et bien d'autres. Ces projets sont au cœur de l'infrastructure cloud native moderne.
    • Elle fournit un cadre de gouvernance et un environnement de collaboration pour ces projets.
  • Définition de Standards:
    • La CNCF travaille à la définition de standards et de meilleures pratiques pour les technologies cloud natives.
    • Elle favorise l'interopérabilité entre les différents projets et outils.
  • Promotion de l'Écosystème:
    • La CNCF organise des événements, des conférences et des meetups pour promouvoir les technologies cloud natives et rassembler la communauté.
    • Elle favorise l'adoption de ces technologies par les entreprises et les développeurs.
  • Incubation de Nouveaux Projets:
    • La CNCF offre un programme d'incubation pour les nouveaux projets qui répondent à ses critères.
    • Elle aide ces projets à se développer et à atteindre la maturité nécessaire pour rejoindre la CNCF en tant que projet hébergé.
  • Collaboration avec l'Industrie:
    • La CNCF travaille en étroite collaboration avec les principaux acteurs de l'industrie du cloud, tels que les fournisseurs de cloud public, les entreprises technologiques et les universités.
  • Elle contribue à façonner l'avenir du cloud computing.

OCI

  • Créé sous la Linux Fondation
  • Standardisation : Le but principal de l'OCI est de créer des standards ouverts pour les formats de conteneurs et leurs runtimes. Cela permet d'assurer l'interopérabilité entre différentes plateformes et outils.
  • Portabilité : En établissant des spécifications communes, l'OCI vise à rendre les conteneurs portables entre différents environnements d'exécution, clouds et systèmes d'exploitation.
  • Compatibilité : L'initiative cherche à garantir que les conteneurs créés selon ses spécifications fonctionneront de manière cohérente, quel que soit l'outil utilisé pour les créer ou les exécuter.
  • Innovation : Tout en maintenant des standards, l'OCI encourage l'innovation dans l'écosystème des conteneurs en fournissant une base commune sur laquelle les entreprises et les développeurs peuvent construire.
  • Sécurité : L'OCI travaille également sur des spécifications liées à la sécurité des conteneurs, visant à améliorer la sécurité globale de l'écosystème.
  • Collaboration industrielle : L'initiative favorise la collaboration entre de nombreuses entreprises et acteurs majeurs du secteur technologique pour définir ces standards.
  • runC a été donné par Docker à l'OCI comme implémentions de base

Kubernetes : Projet

De nombreuses sources d'informations et de contributions disponibles :

Kubernetes : Projet (suite)

Kubernetes : Cycle de développement 1/3

  • Chaque release a son propre planning, pour exemple : https://github.com/kubernetes/sig-release/tree/master/releases/release-1.30#timeline

  • Fréquence des releases :
    • Kubernetes suit généralement un cycle de release trimestriel
    • Il y a habituellement 3 releases majeures par an
  • Structure de versionnage :
    • Format : vX.Y.Z (par exemple, v1.26.0)
    • X : Version majeure (rarement changée)
    • Y : Version mineure (mise à jour trimestrielle)
    • Z : Version de patch (mises à jour de sécurité et corrections de bugs)
  • Phases du cycle de release :
    • Planification
    • Développement
    • Code Freeze
    • Tests et stabilisation
    • Release

Kubernetes : Cycle de développement 2/3

  • Durée du cycle :
    • Environ 12 à 14 semaines pour une release complète
  • Support des versions :
    • Les 3 dernières versions mineures sont généralement supportées
    • Chaque version est supportée pendant environ 9 mois
  • Types de fonctionnalités :
    • Alpha : Expérimentales, peuvent être instables
    • Beta : Plus stables, mais pas garanties pour la production
    • Stable : Prêtes pour la production

Kubernetes : Cycle de développement 3/3

  • Processus communautaire :
    • Développement piloté par la communauté open-source
    • Implication de divers Special Interest Groups (SIGs)
  • Compatibilité :
    • Effort pour maintenir une compatibilité ascendante entre les versions
  • Documentation :
    • Mise à jour avec chaque nouvelle release
  • Communication :
    • Annonces anticipées des dates de release et des changements majeurs
    • Publication de notes de release détaillée

Kubernetes : Communauté

SIG Description
API Machinery Frameworks extensibles pour les API
Architecture Architecture globale et conception du projet
Autoscaling Mise à l'échelle automatique des clusters et workloads
Auth Authentification et autorisation
CLI kubectl et outils en ligne de commande
Cloud Provider Intégration avec les fournisseurs de cloud
Cluster Lifecycle Outils pour la gestion du cycle de vie des clusters
Contributor Experience Amélioration de l'expérience des contributeurs
Docs Documentation et site web de Kubernetes
Instrumentation Métriques, logging, et monitoring

Kubernetes : Sig (suite)

SIG Description
Multicluster Gestion de multiples clusters
Network Réseautage dans Kubernetes
Node Composants au niveau du nœud
Release Coordination des releases
Scalability Performance et scalabilité
Scheduling Planification des pods
Security Sécurité du projet
Storage Stockage et volumes
Testing Tests et infrastructure de test
UI Interface utilisateur et tableaux de bord
Windows Support de Windows dans Kubernetes

Kubernetes : KubeCon

La CNCF organise 3 KubeCon par an :

  • Amérique du Nord (San Diego, Seattle, etc)
  • Europe (Berlin, Barcelone, Amsterdam etc)
  • Chine

Thèmes abordés :

  • Les Kubecon couvrent un large éventail de sujets liés à Kubernetes, tels que :
  • Les dernières fonctionnalités et évolutions de Kubernetes
  • Les meilleures pratiques pour déployer et gérer des applications conteneurisées
  • L'intégration de Kubernetes avec d'autres technologies cloud-native (Istio, Helm, etc.)
  • Les cas d'utilisation de Kubernetes dans différents secteurs (finance, retail, etc.)
  • Les défis et les solutions liés à la sécurité, la performance et la scalabilité des clusters Kubernetes

Pour plus d'informations, Consulter le site officiel de la Cloud Native Computing Foundation (CNCF), l'organisation à l'origine de Kubernetes : https://www.cncf.io/

KUBERNETES : Architecture

Kubernetes : Composants

  • Kubernetes est écrit en Go, compilé statiquement.

  • Un ensemble de binaires sans dépendances

  • Faciles à conteneuriser et à packager

  • Peut se déployer uniquement avec des conteneurs sans dépendance d'OS

  • k3d, kind, minikube, docker...

Kubernetes : Les noeuds (Nodes)

  • Les noeuds qui exécutent les conteneurs embarquent :

    • Un "container Engine" (Docker, CRI-O, containerd...)

    • Une "kubelet" (node agent)

    • Un kube-proxy (un composant réseau nécessaire mais pas suffisant)

  • Ancien nom des noeuds : Minions

Kubernetes : Architecture

Synthèse architecture
Synthèse architecture

Kubernetes : Composants du Control Plane

  • etcd: magasin de données clé-valeur open source cohérent et distribué

  • kube-apiserver : L'API Server est un composant qui expose l'API Kubernetes, l'API server qui permet la configuration d'objets Kubernetes (Pod, Service, Deployment, etc.)

  • core services :

    • kube-scheduler : Implémente les fonctionnalités de scheduling
    • kube-controller-manager : Responsable de l'état du cluster, boucle infinie qui régule l'état du cluster afin d'atteindre un état désiré
    • kube-cloud-controller-manager : Est un composant important du plan de contrôle (control plane) de Kubernetes, spécifiquement conçu pour interagir avec l'infrastructure cloud sous-jacente
    • kube-proxy : Permet le forwarding TCP/UDP et le load balancing entre les services et les backends (Pods)
  • Le control plane est aussi appelé "Master"

Kubernetes : etcd

  • Site : https://etcd.io
  • Code : https://github.com/etcd-io/etcd
  • Base de données de type Clé/Valeur distribuée (Distributed Key Value Store)
  • Haute disponibilité: etcd est conçu pour être hautement disponible, même en cas de panne de certains nœuds
  • Cohérence forte: etcd garantit que toutes les données sont cohérentes entre tous les nœuds.
  • API simple: etcd offre une API simple et facile à utiliser pour interagir avec les données.
  • Surveillance: etcd fournit des outils de surveillance pour suivre l'état du cluster.
  • Stocke l'état d'un cluster Kubernetes
  • Point sensible (stateful) d'un cluster Kubernetes
  • Projet intégré à la CNCF (https://github.com/etcd-io)

Kubernetes : kube-apiserver

Sans le kube-apiserver le cluster ne sert à rien. De plus, il est LE SEUL à interagir avec le cluster etcd, que ce soit en écriture ou en lecture.

  • Les configurations d'objets (Pods, Service, RC, etc.) se font via l'API server
  • Un point d'accès à l'état du cluster aux autres composants via une API REST
  • Tous les composants sont reliés à l'API server
  • Roles :
    • Reçoit les requêtes API faites au cluster
    • Authentifie les requêtes
    • Valide les requêtes
    • Récupère, Met à jour les données dans etcd
    • Transmet les réponses aux clients
    • Intéragit avec le kube-scheduler, le controller-manager, le kubelet, etc...
    • C'est une API donc utilisable via des composants externes (kubectl, curl, lens, ...)

Kubernetes : kube-scheduler

Le kube-scheduler est le composant responsable d'assigner les pods aux nœuds "worker" du cluster. Il choisit alors selon les contraintes qui lui sont imposées un nœud sur lequel les pods peuvent être démarrés et exécutés.

  • Planifie les ressources sur le cluster
  • En fonction de règles implicites (CPU, RAM, stockage disponible, etc.)
  • En fonction de règles explicites (règles d'affinité et anti-affinité, labels, etc.)

Kubernetes : kube-controller-manager

Le kube-controller-manager exécute et fait tourner les processus de contrôle du cluster.

  • Boucle infinie qui contrôle l'état d'un cluster
  • Effectue des opérations pour atteindre un état donné
  • De base dans Kubernetes : replication controller, endpoints controller, namespace controller et serviceaccounts controller
  • Processus de contrôle :
    • Node Controller : responsable de la gestion des nœuds du cluster et de leur cycle de vie
    • Replication Controller : responsable du maintien du nombre de pods pour chaque objet de réplication dans le cluster
    • Endpoints Controller : fait en sorte de joindre correctement les services et les pods
    • Service Account & Token Controllers : Gestion des comptes et des tokens d'accès à l'API pour l'accès aux namespaces Kubernetes

Kubernetes : kube-cloud-controller-manager

  • Fonction principale :

    • Le CCM agit comme une interface entre Kubernetes et le fournisseur de cloud spécifique (comme AWS, Google Cloud, Azure, etc.). Il permet à Kubernetes de gérer les ressources spécifiques au cloud de manière indépendante du reste du cluster.
    • Séparation des responsabilités :
      • Avant l'introduction du CCM, le contrôleur de nœud (node controller), le contrôleur de route (route controller) et le contrôleur de service (service controller) étaient intégrés au contrôleur de gestion Kubernetes (kube-controller-manager). Le CCM a extrait ces fonctionnalités spécifiques au cloud pour les gérer séparément.
    • Contrôleurs spécifiques au cloud : Le CCM implémente plusieurs contrôleurs qui interagissent avec l'API du fournisseur de cloud :
      • Node Controller : Vérifie si les nœuds ont été supprimés dans le cloud après avoir cessé de répondre.
      • Route Controller : Configure les routes dans l'infrastructure cloud pour que les pods sur différents nœuds puissent communiquer.
      • Service Controller : Crée, met à jour et supprime les load balancers du cloud.

Kubernetes : kube-proxy

Le kube-proxy maintient les règles réseau sur les nœuds. Ces règles permettent la communication vers les pods depuis l'intérieur ou l'extérieur de votre cluster.

  • Responsable de la publication de services

  • Route les paquets à destination des PODs et réalise le load balancing TCP/UDP

  • 3 modes de proxyfication :

    • Userspace mode

    • IPtables mode

    • IPVS (IP Virtual Server) mode

Remarque: Par défaut, Kube-proxy fonctionne sur le port 10249. Vous pouvez utiliser un ensemble d'endpoints exposés par Kube-proxy pour l'interroger et obtenir des informations.

Pour voir quel mode est utilisé :

Sur un des noeuds executer la commande :

curl -v localhost:10249/proxyMode;echo

# ex: retourne iptables

Certains plugins réseaux, tel que Cilium, permettent de ne plus utiliser kube-proxy et de le remplacer par un composant du CNI

Kubernetes : kube-proxy Userspace mode

  • Userspace mode est ancien et inefficace.
  • Le paquet est comparé aux règles iptables puis transféré au pod kube-Proxy, qui fonctionne comme une application pour transférer le paquet aux pods backend.
  • Kube-proxy fonctionne sur chaque nœud en tant que processus dans l'espace utilisateur.
  • Il distribue les requêtes entre les pods pour assurer l'équilibrage de charge et intercepte la communication entre les services.
  • Malgré sa portabilité et sa simplicité, le surcoût de traitement des paquets dans l'espace utilisateur le rend moins efficace pour les charges de trafic élevées.

Kubernetes : kube-proxy IPtables mode

  • Le mode iptables est préférable car il utilise la fonctionnalité iptables du noyau, qui est assez mature.
  • kube-proxy gère les règles iptables en fonction du fichier YAML du service de Kubernetes.
  • Pour gérer le trafic des services, Kube-proxy configure des règles iptables sur chaque nœud.
  • Il achemine les paquets vers les pods pertinents en utilisant du NAT (Network Address Translation) iptables.
  • Ce mode fonctionne bien avec des volumes de trafic modestes et est plus efficace que le mode espace utilisateur.

Kubernetes : kube-proxy IPVS mode

  • IPVS mode équilibre la charge en utilisant la fonctionnalité IPVS du noyau Linux. Par rapport au mode IPtables, il offre une meilleure évolutivité et des performances améliorées.

  • IPVS est le mode recommandé pour les installations à grande échelle car il peut gérer de plus gros volumes de trafic avec efficacité. IPtable Non !

Kubernetes : Kubelet

Elle, Il, iel ? 😉

  • Agent principal du nœud : Kubelet est le principal agent qui s'exécute sur chaque nœud (machine) d'un cluster Kubernetes.
  • Gestion des pods : Elle est responsable de la création, de la mise à jour et de la suppression des pods sur ce nœud, en suivant les instructions du plan de contrôle Kubernetes.
  • Communication avec l'API Kubernetes : Kubelet communique en permanence avec l'API Kubernetes pour recevoir les mises à jour de configuration et les commandes.
  • Exécution des conteneurs : Il utilise un runtime de conteneur (comme Docker ou containerd) pour lancer et gérer les conteneurs à l'intérieur des pods.
  • Permet à Kubernetes de s'auto configurer :
    • Surveille un dossier contenant les manifests (fichiers YAML des différents composant de Kubernetes).
    • Applique les modifications si besoin (upgrade, rollback).
  • Surveillance de l'état des pods : Kubelet surveille en permanence l'état des pods et des conteneurs, et signale tout problème au plan de contrôle.
  • Gestion des ressources : Il gère l'allocation des ressources (CPU, mémoire) aux pods et assure que les limites de ressources ne sont pas dépassées.
  • Intégration avec le système d'exploitation : Kubelet s'intègre avec le système d'exploitation hôte pour gérer les réseaux, les volumes et autres fonctionnalités du système.

Kubernetes : Architecture détaillée

Architecture détaillée
Architecture détaillée

Kubernetes : Cluster Architecture

Cluster architecture
Cluster architecture

Kubernetes: Network

Kubernetes n'implémente pas de solution réseau par défaut, mais s'appuie sur des solutions tierces qui implémentent les fonctionnalités suivantes:

Kubernetes : Aujourd'hui

Les versions de Kubernetes sont exprimées sous la forme x.y.z, où x est la version majeure, y est la version mineure et z est la version du correctif, conformément à la terminologie du Semantic Versioning.

1.33

Latest Release:1.33.4 (released: 2025-08-12)

End of Life:2026-06-28

Complete 1.33 Schedule and Changelog

Top expectation

KUBERNETES : Concepts et Objets

Kubernetes : Core API Resources

  • Namespaces

  • Labels

  • Annotations

  • Pods

  • Deployments

  • DaemonSets

  • Jobs

  • Cronjobs

  • Services

Kubernetes : Namespaces

  • Namespaces : Pensez aux différents départements d'une entreprise (par exemple, les ressources humaines, l'ingénierie, le marketing). Chaque département a ses propres ressources (employés, budgets, projets) et fonctionne de manière assez indépendante, mais ils font tous partie de la même entreprise. Vous ne pouvez pas avoir deux projets avec le même nom dans le même département, mais vous le pouvez dans des départements différents.

  • Fournissent une séparation logique des ressources :
    • Par utilisateurs
    • Par projet / applications
    • Autres...
  • Les objets existent uniquement au sein d'un namespace donné
  • Évitent la collision de nom d'objets
  • Font partie du fqdn du service (DNS) (mon-service.mon-namespace.svc.cluster.local)
  • Quotas et limites: Vous pouvez définir des quotas et des limites sur les ressources (CPU, mémoire, nombre de pods, etc.) au niveau du namespace pour contrôler l'utilisation des ressources.
  • Défaut: Le namespace default existe par défaut dans chaque cluster Kubernetes.

Kubernetes : Labels

  • Labels : Imaginez des étiquettes sur des boîtes dans un entrepôt. Vous pouvez étiqueter les boîtes avec des mentions comme "fragile", "lourd", "électronique" ou par destination comme "Paris". Cela vous aide à trouver et à organiser rapidement toutes les boîtes ayant une caractéristique spécifique. Une boîte peut avoir plusieurs étiquettes.

  • Système de clé/valeur
  • Organisent, filtrent, selectionnent les différents objets de Kubernetes (Pods, RC, Services, etc.) d'une manière cohérente qui reflète la structure de l'application
  • Corrèlent des éléments de Kubernetes : par exemple un service vers des Pods
  • Ils contiennent des informations d'identification utilisées par les requêtes qui utilisent un sélecteur ou dans les sections de sélecteurs dans les définitions d'objets
  • Le nom dans la clé est limité à 63 caractères et le suffixe à 253 caractères
  • La valeur ne peut dépasser 63 caractères
  • La valeur doit commencer un aplhanum ou être vide
  • La valeur peut contenir des ~ . et alphanum
  • Arbitraires: Vous pouvez définir n'importe quelle paire clé-valeur.
  • Immuables: Une fois créés, les labels ne peuvent pas être modifiés directement. Pour les changer, il faut créer un nouveau déploiement ou un nouveau pod.
  • Multiples: Un objet peut avoir plusieurs labels.

Kubernetes : Labels

  • Exemple de label :
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
    env: prod
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

Kubernetes : Labels

  • La commande kubectl get pods, par défaut, ne liste pas les labels.

  • Il est possible de les voir en utilisant --show-labels:

$ kubectl get pods --show-labels
NAME      READY     STATUS    RESTARTS   AGE       LABELS
nginx     1/1       Running   0          31s       app=nginx,env=prod
  • Lister des ressources par l'utilisation de labels

kubectl get po -A -l k8s-app=kube-dns
# ou 
kubectl get pods --selector=k8s-app=dns

kubectl get po -A -l k8s-app=kube-dns -l pod-template-hash=6d4b75cb6d
# equivalent
kubectl get po -A -l k8s-app=kube-dns,pod-template-hash=6d4b75cb6d
# ou
kubectl get po -A --selector=8s-app=kube-dns,pod-template-hash=6d4b75cb6d

# Lister les valeurs d'un label 
kubectl get pods -L k8s-app

# Lister to les labels d'un object

kubectl get deploy --show-labels
kubectl get deploy,po --show-labels

# Utiliser la forme négative

kubectl get po -A -l k8s-app!=kube-dns

Kubernetes : Annotations

  • Annotations : C'est comme un commentaire ou une note sur un document. Il fournit des informations supplémentaires pour les humains ou d'autres outils (comme le nom de l'auteur, la date de la dernière révision ou un lien vers une documentation externe), mais il ne change pas la manière dont le document est traité par le système principal.

  • Système de clé/valeur
  • Ce sont des informations qui ne sont pas utilisées pour l'identification de ressources.
  • Les annotations ne sont pas utilisées en interne par kubernetes
  • Stockage de données personnalisées: Pour stocker des informations spécifiques à votre application ou à votre infrastructure.
  • Elles peuvent être utilisées par des outils externes ou librairies (ex: cert-manager, ingress-controller...)
  • Le nom dans la clé est limitée à 63 caractères et le suffixe à 253 caractères
  • Arbitraires: Vous pouvez définir n'importe quelle paire clé-valeur.
  • Mutables: Les annotations peuvent être modifiées après la création de l'objet.
  • Multiples: Un objet peut avoir plusieurs annotations.

Kubernetes : Annotations

  • exemple d'annotation

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: theClusterIssuer 
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:

Kubernetes : Pod

  • Pods : Un Pod est comme un appartement dans un immeuble. L'appartement fournit l'environnement essentiel (murs, électricité, eau) pour ses habitants (les conteneurs). Tous les habitants de l'appartement partagent la même adresse (adresse IP) et peuvent facilement communiquer entre eux. Ils partagent des ressources comme la cuisine et la salle de bain (volumes, réseau).

  • Un Pod n'est pas un processus, c'est un environnement pour les containers
    • Un pod ne peut pas être redémarré
    • Il ne peut pas se "planter", les containers d'un pod "oui"
  • C'est, donc, Ensemble logique composé de un ou plusieurs conteneurs
  • Les conteneurs d'un pod fonctionnent ensemble (instanciation et destruction) et sont orchestrés sur un même hôte
  • Les conteneurs partagent certaines spécifications du Pod :
    • La stack IP (network namespace)
    • Inter-process communication (PID namespace)
    • Volumes
    • IP: Le pod lui-même dispose d'une adresse IP unique, que tous les conteneurs du pod peuvent utiliser.
    • Cycle de vie: Les conteneurs d'un pod sont créés et détruits en même temps
    • Node: Tous les conteneurs d'un pod sont généralement co-localisés sur le même nœud du cluster Kubernetes.
  • C'est la plus petite et la plus simple unité dans Kubernetes

En savoir plus : https://kubernetes.io/fr/docs/concepts/workloads/pods/pod/

Kubernetes : Pod

Kubernetes : Pod

  • Les Pods sont définis en YAML comme les fichiers docker-compose :
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

Kubernetes : Pod

Dans les statuts du pod on trouve la notion de phase d'exécution

  • Phases :
    • Pending: accepté par le cluster, les container ne sont pas initialisé
    • Running: Au moins un des containers est en cours de démarrage, d'exécution ou de redémarrage
    • Succeeded: Tous les containers se sont arrêtés avec un "exit code" à 0 (zéro); Le pod ne sera pas redémarré
    • Failed: Tous les containers se sont arrêtés et au moins un a un exit code différent de 0
    • Unknown: L'état du pod ne peut pas être déterminé
$ kubectl get pods -o wide

en sortie :

NAME                  READY   STATUS    RESTARTS   AGE   IP           NODE      
xx-79c5968bdc-6lcfq   1/1     Running   0          84m   10.244.0.6   kind-cp   
yy-ss7nk              1/1     Running   0          84m   10.244.0.5   kind-cp

Kubernetes : Pod

Dans les statuts du pod on trouve la notion de Conditions d'état des pods

  • Conditions :
    • PodScheduled: Un nœud a été sélectionné avec succès pour "lancer" le pod, et la planification est terminée.
    • ContainersReady: Tous les containers sont prêts
    • Initialized: Les "Init containers sont démarrés"
    • Ready: Le pod est capable de répondre aux demandes ; par conséquent, il doit être inclus dans le service et les répartiteurs de charge.
kubectl describe pods <POD_NAME>

en sortie

...
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
...

Kubernetes : Pod

États des containers (States)

Les containers peuvent avoir seulement 3 états

  • États:
    • Waiting: Les processus requis sont en cours d'exécution pour un démarrage réussi
    • Running: Le container est en cours d'exécution
    • Terminated: L'exécution du conteneur s'est déroulée et s'est terminée par un succès ou un échec.
$ kubectl get pods <POD_NAME> -o jsonpath='{.status}' | jq

Kubernetes : Pod

Kubernetes : Deployment

  • Deployments : C'est comme le gérant d'une chaîne de cafés identiques. Le travail du gérant est de s'assurer qu'un certain nombre de cafés (Pods/réplicas) sont toujours ouverts et fonctionnent de la même manière. Si un café ferme de manière inattendue, le gérant en ouvre un nouveau immédiatement. S'il veut changer le menu (mettre à jour l'application), le gérant déploie le changement dans tous les cafés, un par un, sans les fermer tous en même temps.

  • Permet d'assurer le fonctionnement d'un ensemble de Pods
  • Gère les Version, Update et Rollback
  • Il est lié avec l'object ReplicaSet qui gère le cycle de vie et la mise à l'échelle des pods
  • Souvent combiné avec un objet de type service

Kubernetes : Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:stable
        ports:
        - containerPort: 80

Ou en ligne de commande

kubectl create deployment my-app --image=nginx:latest --replicas=3

Kubernetes : Deployment

Kubernetes : DaemonSet

  • DaemonSets : Pensez à avoir un agent de sécurité à chaque étage d'un immeuble. Vous ne spécifiez pas combien de gardes vous avez besoin au total ; vous déclarez simplement que chaque étage doit en avoir exactement un. Si un nouvel étage est ajouté, un nouveau garde lui est automatiquement assigné.

  • Assure que tous les noeuds exécutent une copie du pod sur tous les noeuds du cluster
  • Ne connaît pas la notion de replicas.
  • Utilisé pour des besoins particuliers comme :
    • l'exécution d'agents de collection de logs comme fluentd ou logstash
    • l'exécution de pilotes pour du matériel comme nvidia-plugin
    • l'exécution d'agents de supervision comme NewRelic agent, Prometheus node exporter

Kubernetes : DaemonSet

daemonset
daemonset

Kubernetes : DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
  spec:
  selector:
    matchLabels:
      app: ssd-monitor
  template:
    metadata:
      labels:
        app: ssd-monitor
  spec:
    nodeSelector:
    disk: ssd
    containers:
    - name: main
      image: luksa/ssd-monitor

Kubernetes : StatefulSet

  • StatefulSets : C'est la différence entre le bétail (cattle) et les animaux de compagnie (pets). Un Deployment gère le bétail : si une vache tombe malade, vous la remplacez par une autre en bonne santé, et cela n'a pas d'importance. Un StatefulSet gère les animaux de compagnie : si votre chien Fido est malade, vous voulez que Fido soit soigné et revienne. Vous ne voulez pas un nouveau chien identique. Les StatefulSets donnent à chaque Pod une identité unique et stable (un nom comme db-0, db-1) et un stockage persistant qui lui est propre. C'est essentiel pour les applications comme les bases de données, où chaque instance a un rôle et des données spécifiques qui doivent être préservés.

  • Similaire au Deployment mais les noms des composants sont prédictibles
  • Les pods possèdent des identifiants uniques.
  • Chaque replica de pod est créé par ordre d'index
  • Nécessite un Persistent Volume et un Storage Class.
  • Supprimer un StatefulSet ne supprime pas le PV associé

statefulset
statefulset

Kubernetes : StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
web-0   0/1     ContainerCreating   0          3s
❯ kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
web-0   1/1     Running             0          9s
web-1   0/1     ContainerCreating   0          1s
❯ kubectl get po
NAME    READY   STATUS              RESTARTS   AGE
web-0   1/1     Running             0          12s
web-1   1/1     Running             0          4s
web-2   0/1     ContainerCreating   0          2s
❯ kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          15s
web-1   1/1     Running   0          7s
web-2   1/1     Running   0          5s

Kubernetes : StatefulSet avancé


apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
    app.kubernetes.io/name: mysql
data:
  primary.cnf: |
    [mysqld]
    log-bin    
  replica.cnf: |
    [mysqld]
    super-read-only    

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
      app.kubernetes.io/name: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
        app.kubernetes.io/name: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
          if [[ $ordinal -eq 0 ]]; then
            cp /mnt/config-map/primary.cnf /mnt/conf.d/
          else
            cp /mnt/config-map/replica.cnf /mnt/conf.d/
          fi          
        ....
      - name: clone-mysql
        image: gcr.io/google-samples/xtrabackup:1.0
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ -d /var/lib/mysql/mysql ]] && exit 0
          # Skip the clone on primary (ordinal index 0).
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          [[ $ordinal -eq 0 ]] && exit 0
          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
        ...
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "1"
        ...

Kubernetes : Job

  • Jobs : C'est comme une tâche ponctuelle pour un entrepreneur, par exemple, "peindre cette pièce". L'entrepreneur (Job) vient, apporte ses outils (conteneur), effectue le travail (exécute le processus), et part une fois que le travail est terminé avec succès. S'il renverse la peinture et fait un gâchis (échec), il devra peut-être nettoyer et réessayer.

  • Crée des pods et s'assurent qu'un certain nombre d'entre eux se terminent avec succès.
  • Peut exécuter plusieurs pods en parallèle
  • Si un noeud du cluster est en panne, les pods sont reschedulés vers un autre noeud.

job
job

Kubernetes : Job

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  parallelism: 1
  completions: 1
  template:
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: OnFailure

En ligne de commande :

kubectl create job exemple-job --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

Kubernetes: CronJob

  • CronJobs : Imaginez un service de nettoyage quotidien programmé pour un bureau. Le service (CronJob) est configuré pour venir chaque jour à 18h (l'horaire) pour effectuer la tâche de nettoyage (le Job). C'est une tâche récurrente et automatisée.

  • Un CronJob permet de lancer des Jobs de manière planifiée.
  • la programmation des Jobs se définit au format Cron
  • le champ jobTemplate contient la définition de l'application à lancer comme Job.

cronjob
cronjob

Kubernetes : CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: batch-job-every-fifteen-minutes
spec:
  schedule: '0,15,30,45 * * * *'
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: periodic-batch-job
        spec:
          restartPolicy: OnFailure
          containers:
            - name: pi
              image: perl
              command:
                - perl
                - '-Mbignum=bpi'
                - '-wle'
                - print bpi(2000)

En ligne de commande :

kubectl create cronjob exemple-cronjob --image=busybox --schedule="*/5 * * * *" -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

Susprendre un cronjob :

kubectl patch cronjob <cronjob-name> -p '{"spec" : {"suspend" : true }}'

Reprendre l'exécution :

kubectl patch cronjob <cronjob-name> -p '{"spec" : {"suspend" : false }}'

Kubernetes : Service

  • Services : C'est comme le réceptionniste dans un grand immeuble de bureaux. Vous n'avez pas besoin de connaître l'emplacement exact ou le numéro de téléphone direct de la personne à qui vous voulez parler (un Pod spécifique, qui peut changer). Vous dites simplement au réceptionniste (Service) qui vous voulez joindre (en utilisant un sélecteur de label comme app=ventes), et il vous mettra en relation avec une personne disponible dans ce département. Le réceptionniste fournit un point de contact stable.

Un Service est un objet Kubernetes qui fournit une abstraction pour accéder à un ensemble de Pods. Il agit comme un point d'entrée unique et stable pour les applications, même si les Pods derrière lui sont créés, détruits ou déplacés.

Voici ses principales caractéristiques :

  • Point d'accès stable : Chaque Service possède une adresse IP virtuelle (ClusterIP) et un nom DNS stables qui ne changent pas pendant son cycle de vie. Les applications clientes se connectent au Service plutôt qu'aux Pods directement, dont les adresses IP sont éphémères.
  • Découverte de services et sélection de Pods : Un Service utilise des labels et des sélecteurs pour identifier dynamiquement l'ensemble des Pods auxquels il doit acheminer le trafic. Cela permet de découpler les applications qui consomment le service des Pods qui le fournissent.
  • Répartition de charge (Load Balancing) : Par défaut, un Service répartit le trafic réseau de manière égale (round-robin) entre tous les Pods correspondants, assurant ainsi la haute disponibilité et la scalabilité des applications.

Cet objet est fondamental pour la communication inter-applicative au sein du cluster. Nous aborderons en détail les différents types de Services (comme ClusterIP, NodePort, et LoadBalancer) et leurs cas d'usage dans un chapitre dédié au réseau dans Kubernetes.

Extras : Init Containers

  • On peut définir des conteneurs qui doivent s'exécuter avant les conteneurs principaux
  • Ils seront exécutés dans l'ordre (au lieu d'être exécutés en parallèle)
  • ⚠️ Ils doivent tous réussir avant que les conteneurs principaux ne soient démarrés

exemple :

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

Extras : Init Containers

  • Lors du démarrage d'un Pod, le kubelet retarde l'exécution des conteneurs d'initialisation jusqu'à ce que le réseau et le stockage soient prêts. Ensuite, le kubelet exécute les conteneurs d'initialisation du Pod dans l'ordre où ils apparaissent dans la spécification du Pod.
  • Chaque conteneur d'initialisation doit se terminer avec succès avant que le suivant ne démarre.
  • Si un conteneur ne parvient pas à démarrer en raison de l'environnement d'exécution ou se termine avec un échec, il est relancé conformément à la restartPolicy du Pod. Cependant, si la restartPolicy du Pod est définie sur Always, les conteneurs d'initialisation utilisent la restartPolicy OnFailure.
  • Un Pod ne peut pas être Ready tant que tous les conteneurs d'initialisation n'ont pas réussi. Les ports d'un conteneur d'initialisation ne sont pas agrégés sous un Service.
  • Un Pod en cours d'initialisation est dans l'état Pending mais doit avoir une condition Initialized définie à false.
  • Si le Pod redémarre, ou est redémarré, tous les conteneurs d'initialisation doivent s'exécuter à nouveau.

  • Utilisations possibles
    • Charger/préparer des données (code, data, configuration,...)
    • Organiser les update (migrations) de bases de données
    • Attendre que certains services soient démarrés (bonne alternative à des sondes)
    • ...

KUBERNETES : Networking

Kubernetes : Network plugins

  • Kubernetes n'implémente pas de solution de gestion de réseau par défaut
  • Le réseau est implémenté par des solutions tierces:

Kubernetes : CNI

  • Container Network Interface
  • Projet dans la CNCF
  • Standard pour la gestion du réseau en environnement conteneurisé
  • Les solutions précédentes s'appuient sur CNI
  • Flexibilité: Il offre une grande flexibilité pour choisir le type de réseau à utiliser (bridge, VLAN, VXLAN, etc.) et les fonctionnalités associées (routage, NAT, etc.).
  • Plugin: Un CNI est implémenté sous forme de plugin, ce qui permet de choisir le plugin adapté aux environnements et besoins.

  • Rôle d'un CNI dans Kubernetes
    • Création d'interfaces réseau: Lorsqu'un pod est créé, le CNI est appelé pour créer une ou plusieurs interfaces réseau pour les conteneurs du pod.
    • Configuration IP: Le CNI attribue une adresse IP à chaque interface réseau et configure les routes nécessaires.
    • Gestion des réseaux: Le CNI gère la configuration réseau au cours du cycle de vie du pod (création, modification, suppression).

Kubernetes : POD Networking

pod network
pod network

Kubernetes : Services

  • Une abstraction de niveau supérieur qui expose un ensemble de pods sous un nom et une adresse IP stables.
  • Permet d'accéder à un groupe de pods de manière uniforme, même si les pods individuels sont créés, mis à jour ou supprimés.
  • Rendre un ensemble de pods accessibles depuis l'extérieur
  • Load Balancing entre les pods d'un même service

Kubernetes : Services

pod network
pod network

Kubernetes : Services : ClusterIP

  • ClusterIP :
    • C'est le service par défaut
    • Attribue une adresse IP interne accessible uniquement au sein du cluster, cette adresse est accessible dans le cluster par les pods et les noeuds
    • Expose le service pour les connexions depuis l'intérieur du cluster
    • L'application peut utiliser le port de l'application directement

Kubernetes : Services : ClusterIP

apiVersion: v1
kind: Service
metadata: 
  name: the-service
spec: 
  ports: 
    - port: 80
      protocol: TCP
      targetPort: 8080
  selector: 
    app: web
# déploiement 

kubectl create deployment web --image=nginx

# service
# par défaut type= ClusterIP

kubectl expose deploy web --port=80 --target-port=8080

Kubernetes : Services : HeadLess ClusterIP

  • Headless ClusterIP :
    • Il n'y pas de load balancing
    • Le service renvoie sur une requête DNS la liste des IP des pods et non pas l'IP du service
    • Le service donc envoi les requêtes sur les pods même ceux-ci ne fonctionnent pas
    • C'est donc à l'application de gérer la tolérance de panne et le routage

Kubernetes : Services : HeadLess ClusterIP


apiVersion: v1
kind: Service
metadata:
  name: my-headless-service
spec:
  clusterIP: None # <--
  selector:
    app: test-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
# déploiement 

kubectl create deployment web --image=nginx

# service

kubectl expose deploy web --port=80 --target-port=8080  --cluster-ip none

Kubernetes : Services : NodePort

  • NodePort :
    • chaque noeud du cluster ouvre un port statique (entre 30000-32767 par défaut) et redirige le trafic vers le port indiqué
    • Un service de type ClusterIP est créé automatiquement lors de la création du Service NodePort
    • Expose le service au trafic externe
    • Expose le service sur un port sur chaque nœud du cluster
    • Pb : le code doit être changé pour accéder au bon n° de port

Kubernetes : Services : NodePort

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: my-nginx
# déploiement 

kubectl create deployment web --image=nginx

# service

kubectl expose deploy web --type NodePort --protocol TCP --port 80 --target-port 8080

Kubernetes : Services : LoadBalancer

  • LoadBalancer : expose le service à l'externe en utilisant le loadbalancer d'un cloud provider (AWS, Google, Azure)
    • Expose des services au trafic externe
    • Expose le service sur chaque nœud (comme NodePort)
    • Fournit un répartiteur de charge

Kubernetes : Services : LoadBalancer

Service de type Spécial

  • Load Balancing : intégration avec des cloud provider :
    • AWS ELB
    • GCP
    • Azure Kubernetes Service
    • OpenStack
    • ...
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  ports:
    - port: 9000
      targetPort: 1234
  selector:
    app: myapp
  type: LoadBalancer
# déploiement 

kubectl create deployment web --image=myapp

# service

kubectl expose deploy web --type LoadBalancer --protocol TCP --port 9000 --target-port 1234

Kubernetes : Services : ExternalName

  • ExternalName
    • Un alias vers un service externe en dehors du cluster
    • La redirection se produit au niveau DNS, il n'y a aucune proxyfication ou forward

Exemples d'utilisation concrets :

  • Intégration avec des services tiers:
    • Base de données externe: Vous avez une base de données hébergée sur un service cloud comme AWS RDS. Au lieu d'utiliser l'adresse IP ou l'URL complète, vous pouvez créer un service ExternalName qui pointera vers le nom DNS de cette base de données. Cela facilite la configuration de vos applications dans le cluster.
    • API externe: Vous souhaitez consommer une API publique (comme une API météo ou une API de paiement). En créant un service ExternalName qui pointe vers l'URL de cette API, vous pouvez y accéder depuis vos pods comme si c'était un service interne.
  • Migration progressive:
    • Transition vers un nouveau service: Vous êtes en train de migrer vers un nouveau service et souhaitez maintenir l'ancien pendant un certain temps. Vous pouvez créer un service ExternalName qui pointera alternativement vers l'ancien ou le nouveau service, selon votre configuration.
  • Abstraction de noms DNS complexes:
    • Noms DNS longs ou difficiles à retenir: Si vous avez des noms DNS très longs ou complexes, un service ExternalName peut servir d'alias plus court et plus facile à mémoriser.
  • Microservices:
    • Simplifie les interactions entre différents microservices qui peuvent être déployés sur des infrastructures différentes.
  • Tests:
    • Permet de simuler des environnements de test en pointant vers des services de test.

Kubernetes : Services : ExternalName

Il est aussi possible de mapper un service avec un nom de domaine en spécifiant le paramètre spec.externalName.

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

En ligne de commande :

kubectl create service externalname my-service --external-name  my.database.example.com

Kubernetes : Services : External IPs

On peut définir une IP externe permettant d'accèder à un service interne

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  externalIPs:
  - 1.2.3.4
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

En ligne de commande :

kubectl expose deploy nginx --port=80 --external-ip=1.2.3.4

Kubernetes : Services Résumé

  • ClusterIP : C'est le type de service par défaut. Il fournit une IP virtuelle stable accessible uniquement à l'intérieur du cluster, parfait pour la communication entre microservices.

  • NodePort : Il étend ClusterIP en exposant le service sur un port spécifique de chaque nœud du cluster. C'est utile pour le développement ou les environnements de test.

  • LoadBalancer : Idéal pour la production, il étend NodePort en provisionnant automatiquement un load balancer externe (souvent fourni par le cloud provider).

  • ExternalName : Un cas particulier qui permet de créer un alias CNAME vers un service externe au cluster.

  • Headless Service : A Utiliser quand vous avez besoin d'une découverte de service fine, sans Load Balancing. Très utile pour les bases de données distribuées.

  • ExternalIPs : Permet d'exposer un service Kubernetes sur une adresse IP spécifique qui existe déjà sur l'un des nœuds du cluster, offrant ainsi un accès direct depuis l'extérieur sans passer par un LoadBalancer.

Kubernetes : Quand utiliser tel ou tel type de service ?

Choisir le bon type de service dans Kubernetes est essentiel pour l'architecture de votre application. Voici un guide pour vous aider à décider :

  • ClusterIP

    • Quand l'utiliser ? Pour la communication interne au cluster. C'est le type par défaut et le plus courant.
    • Cas d'usage typique : Un pod frontend qui doit communiquer avec un pod backend (par exemple, une API ou une base de données) à l'intérieur du même cluster. Le service n'est pas exposé à l'extérieur.
  • NodePort

    • Quand l'utiliser ? Pour exposer un service à l'extérieur du cluster à des fins de développement, de test ou de démonstration. Il n'est généralement pas recommandé pour la production.
    • Cas d'usage typique : Vous développez une application sur Minikube ou un cluster on-premise et vous avez besoin d'un accès rapide à un service depuis votre machine locale via http://<IP_DU_NOEUD>:<NODE_PORT>.
  • LoadBalancer

    • Quand l'utiliser ? Pour exposer une application à Internet en production, en particulier sur un fournisseur de cloud (AWS, GCP, Azure).
    • Cas d'usage typique : Une application web ou une API que les utilisateurs finaux doivent pouvoir atteindre. Le fournisseur de cloud provisionne automatiquement un load balancer externe qui distribue le trafic vers vos services.
  • ExternalName

    • Quand l'utiliser ? Lorsque vous souhaitez qu'un service Kubernetes soit un alias pour un service externe (en dehors du cluster).
    • Cas d'usage typique : Votre application dans le cluster doit se connecter à une base de données externe gérée (comme Amazon RDS) ou à une API tierce. Au lieu de coder en dur l'URL externe, vous créez un service ExternalName (database.local) qui pointe vers l'endpoint externe (xxxx.rds.amazonaws.com).
  • Headless Service

    • Quand l'utiliser ? Lorsque vous n'avez pas besoin de load balancing et que vous voulez que les clients se connectent directement aux pods. La découverte de service renvoie les IPs de tous les pods.
    • Cas d'usage typique : Pour les applications StatefulSets comme les bases de données distribuées (par exemple, Cassandra, MongoDB) où les pods ont des identités réseau stables et doivent pouvoir se découvrir et communiquer entre eux.
  • ExternalIPs

    • Quand l'utiliser ? Un cas d'usage plus avancé où vous voulez assigner une IP externe statique que vous gérez vous-même à un service. Le trafic arrivant sur cette IP sur n'importe quel noeud est routé vers le service.
    • Cas d'usage typique : Vous avez un cluster on-premise et un routeur externe qui peut diriger le trafic vers les IPs de vos nœuds. Vous pouvez alors exposer un service sur une IP spécifique de ce routeur.

Kubernetes : Services Discovery

  • Kubernetes prend en charge 2 modes principaux de "service discovery"
    • Variables d'environnement
    • DNS
  • Variables d'environnement
    • {SERVICE_NAME} _SERVICE_HOST
    • {SERVICE_NAME} _SERVICE_PORT
  • DNS
    • Ensemble d'enregistrements DNS pour chaque service

Kubernetes : Services Discovery

  • Exemple
    • Active service : my-app
    • Variables d'environnement
      • MY_APP_SERVICE_HOST=<Cluster IP Address>
      • MY_APP_SERVICE_PORT=<Service Port>

Kubernetes : Services Discovery

  • exemple :
kubectl get svc
web   ClusterIP   10.96.163.5     <none>        80/TCP     3m56s

kubectl exec web-96d5df5c8-lfmhs -- env | sort

WEB_SERVICE_HOST=10.96.163.5
WEB_SERVICE_PORT=80

Kubernetes : Services Discovery

  • Exemple name: my-app namespace: default
    • Les application dans les pods peuvent utiliser le nom my-app comme nom d'hôte dans le même namespace
    • Les application dans les pods peuvent utiliser le nom my-app.default comme nom d'hôte dans d'autres namespace
  • Syntaxe FQDN - <svc name>.<ns>.svc.cluster.local

ex: my-app.default.svc.cluster.local

Kubernetes: Ingress

  • L'objet Ingress permet d'exposer un service à l'extérieur d'un cluster Kubernetes
  • Il sont faits pour les services de type HTTP (et pas pour UDP et TCP)
  • Il permet de fournir une URL visible permettant d'accéder un Service Kubernetes
  • Il permet d'avoir des terminations TLS, de faire du Load Balancing, etc...
  • Ils ont besoin d'un ingress Controller pour fonctionner

Kubernetes : Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: le
    meta.helm.sh/release-name: argocd
    meta.helm.sh/release-namespace: argocd
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/instance: argocd
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
    app.kubernetes.io/version: v2.10.1
    helm.sh/chart: argo-cd-6.0.14
  name: argocd-server
  namespace: argocd
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.caas.fr
    http:
      paths:
      - backend:
          service:
            name: argocd-server
            port:
              number: 443
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - argocd.caas.fr
    secretName: argocd-server-tls

Kubernetes : Ingress Controller

Pour utiliser un Ingress, il faut un Ingress Controller

Il existe plusieurs solutions OSS ou non :

⚠︎ Note : Il est possible d'avoir plusieurs Ingress Controller sur un cluster il suffira dans les objets ingress de préciser sur quelle classe d'ingress on souhaite le créer.

Ca se fait par l'attribut ingressClassName.

Ces classes sont créees au moment de l'installation du contrôleur.

Les Ingress vont bientôt être dépréciés en faveur des Gateway API qui sont la nouvelle génération de Kubernetes Ingress, Load Balancing, et Service Mesh APIs.

Plus d'informations ici : https://gateway-api.sigs.k8s.io/

Kubernetes : Gateway API

Les Gateway APIs sont une évolution des Ingress Controllers, offrant une approche plus moderne et flexible pour gérer le trafic entrant dans un cluster Kubernetes. Voici les points essentiels :

Architecture en layers:

  • GatewayClass : Définit l'implémentation (comme NGINX, Traefik, etc.)
  • Gateway : Instance spécifique qui gère le trafic entrant
  • Route : Définit les règles de routage (HTTP, TCP, etc.)

Avantages principaux:

- Configuration plus fine et granulaire
- Support natif de plusieurs protocoles
- Meilleure séparation des responsabilités
- API plus extensible et cohérente

Cas d'utilisation:

- Multi-tenancy avec isolation du trafic
- Gestion avancée du routage
- Configuration du TLS
- Gestion du trafic nord-sud et est-ouest

Différence avec les Ingress:

Les Gateway APIs offrent plus de fonctionnalités que les Ingress traditionnels :

- Support multi-protocole natif
- Meilleure extensibilité
- Configuration plus détaillée
- Meilleure séparation des rôles

Kubernetes : Gateway API

KUBERNETES : Stockage

Kubernetes : CSI

  • Container Storage Interface
  • CSI est une interface standard pour connecter Kubernetes à différents fournisseurs de stockage.
  • Équivalent de CNI mais pour les volumes
  • Avant Kubernetes 1.13, tous les drivers de volumes étaient in tree
  • Le but de la séparation est de sortir du code du core de Kubernetes
  • GA depuis Kubernetes 1.13
  • Permet d'utiliser des solutions de stockage variées (cloud, locales, etc.) de manière transparente.
  • Simplifie l'intégration de nouveaux systèmes de stockage.

Kubernetes : CSI

  • La plupart des volumes supportés dans Kubernetes supportent maintenant CSI:
    • Amazon EBS
    • Google PD
    • Cinder
    • GlusterFS
    • La liste exhaustive est disponible ici
    • Drivers CSI: Chaque système de stockage nécessite un driver CSI spécifique pour s'intégrer à Kubernetes.
    • Points de montage: Les drivers CSI créent des points de montage que Kubernetes peut ensuite attacher aux pods.
  • Cycle de vie des volumes: Le CSI gère le cycle de vie complet des volumes (provisionnement, attachement, détachement, suppression).

Kubernetes : Volumes

  • Fournir du stockage persistent aux PODs
    • Défini au niveau pod
  • On le même cycle de vie que le pod
    • Quand le pod est supprimé le volume aussi
    • Les différents type de volumes sont implémentés comme des plugins
    • Les comportement sous-jacents dépendent du backend
  • Fonctionnent de la même façon que les volumes Docker pour les volumes hôte :
    • EmptyDir ~= volumes docker
    • HostPath ~= volumes hôte

Type de Volumes

  • emptyDir
  • hostPath
  • gcePersistentDisk
  • awsElasticBlockStore
  • nfs
  • iscsi
  • fc (fibre channel)
  • flocker
  • glusterfs
  • rbd
  • cephfs
  • secret
  • persistentVolumeClaim
  • downwardAPI
  • projected
  • azureFileVolume
  • azureDisk
  • vsphereVolume
  • Quobyte
  • PortworxVolume
  • ScaleIO
  • StorageOS
  • local

Kubernetes : Volumes

  • On déclare d'abord le volume et on l'affecte à un "service" (container) :
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-persistent-storage
      mountPath: /data/redis
  volumes:
  - name: redis-persistent-storage
    emptyDir: {}

Kubernetes : Volumes

  • Autre exemple
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-persistent-storage-host
      mountPath: /data/redis
  volumes:
  - name: redis-persistent-storage-host
    hostPath:
      path: /mnt/data/redis

Type de stockage

  • Persistent Volume (PV) : Représentation de bas niveau d'un volume de stockage.
  • Persistent Volume Claim (PVC) : binding entre un Pod et un Persistent Volume (PV).
  • Storage Class : Permet de provionner dynamiquement d'un Persistent Volumes (PV).

Kubernetes : Storage Class

  • Permet de définir les différents types de stockage disponibles
  • StorageClass permet le provisionnement dynamique des volumes persistants, lorsque PVC le réclame.
  • Utilisé par les Persistent Volumes pour solliciter un espace de stockage au travers des Persistent Volume Claims
  • StorageClass utilise des provisionneurs spécifiques à la plate-forme de stockage ou au fournisseur de cloud pour donner à Kubernetes l'accès au stockage physique.
  • Chaque backend de stockage a son propre provisionneur. Le backend de stockage est défini dans le composant StorageClass via l'attribut provisioner.

Kubernetes : Storage Class

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zones: us-east-1d, us-east-1c
  iopsPerGB: "10"

Kubernetes : Storage Class

Autre exemple

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
parameters:
  cachingmode: ReadOnly
  kind: Managed
  storageaccounttype: Premium_LRS
provisioner: kubernetes.io/azure-disk
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true

Kubernetes : Storage Class

Autre exemple

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
  name: local-path
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

Kubernetes : PersistentVolume

  • Composant de stockage dans le cluster kubernetes
  • Stockage externe aux noeuds du cluster
  • Cycle de vie d'indépendant du pod qui le consomme
  • Peut être provisionné manuellement par un administrateur ou dynamiquement grâce une StorageClass
  • Supporte différent mode d'accès
    • RWO - read-write par un noeud unique
    • ROX - read-only par plusieurs noeuds
    • RWX - read-write par plusieurs noeuds

Kubernetes : PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: persistent-volume-1
spec:
  storageClassName: slow
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp/data"

Reclaim Policy

  • Les PV qui sont créés dynamiquement par une StorageClass auront la politique de récupération spécifiée dans le champ reclaimPolicy de la classe, qui peut être Delete ou Retain.
  • Si aucun reclaimPolicy n'est spécifié lors de la création d'un objet StorageClass, il sera par défaut delete.

  • Les PV qui sont créés manuellement et gérés via une StorageClass auront la politique de récupération qui leur a été attribuée lors de la création.

  • La stratégie de récupération s'applique aux volumes persistants et non à la classe de stockage elle-même. Les PV et les PVC créés à l'aide de cette StorageClass hériteront de la stratégie de récupération définie dans StorageClass.

Kubernetes : PersistentVolumeClaims

  • Le PVC est un binding entre un pod et un PV. Le pod demande le volume via le PVC.
  • Le liage est géré automatiquement par Kubernetes.
  • Ressource utilisée et vue comme une requête utilisateur pour solliciter du stockage persistant en définissant :
    • une quantité de stockage
    • un type d'accès
    • un namespace pour le montage
  • Offre aux PV une variété d'options en fonction du cas d'utilisation
  • Kubernetes recherche un PV qui répond aux critères définis dans le PVC, et s'il y en a un, il fait correspondre la demande au PV.
  • Utilisé par les StatefulSets pour solliciter du stockage (Utilisation du champ volumeClaimTemplates)
  • Le PVC doit se trouver dans le même namespace que le pod. Pour chaque pod, un PVC effectue une demande de stockage dans un namespace.
  • Les "Claim"" peuvent demander une taille et des modes d'accès spécifiques (par exemple, elles peuvent être montées ReadWriteOnce, ReadOnlyMany ou ReadWriteMany).

Kubernetes : PersistentVolumeClaims

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: storage-claim
spec:
    accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: "slowl"
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: capacity, operator: In, values: [10Gi, 20Gi]}

Kubernetes : PersistentVolumeClaims

Utilisation d'un PVC dans un pod

apiVersion: v1
kind: Pod
metadata: 
  name: myapp
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: mywebsite
    volumes:
    - name: mywebsite
      persistentVolumeClaim:
        claimName: myclaim

Kubernetes : Provisionnement Dynamique

KUBERNETES : Gestion de la Configuration des Applications

Kubernetes : ConfigMaps

  • Objet Kubernetes permettant stocker séparer les fichiers de configuration
  • Il peut être créé d'un ensemble de valeurs ou d'un fichier ressource Kubernetes (YAML ou JSON)
  • Un ConfigMap peut être sollicité (utilisé) par plusieurs pods
  • Limité à 1MiB de data
  • Non sécurisé: Les données sont stockées en clair dans le cluster.

Kubernetes : ConfigMaps

  • Exemple pour être utilisé comme fichier de configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-config
data:
    redis-config: |
      maxmemory 2mb
      maxmemory-policy allkeys-lru

Kubernetes : ConfigMaps

  • Exemple pour être utilisé dans des variables d'environnements
  • Utilisation de clés valeurs individuelles
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-env
data:
   redis_host: "redis_svc"
   redis_port: "6349"

Kubernetes : ConfigMap environnement

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: REDIS_HOST
          valueFrom:
            configMapKeyRef:
              name: redis-env
              key: redis_host
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: env-config
              key: log_level
  restartPolicy: Never

Kubernetes: ConfigMap volume

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: redis-conf-volume
        mountPath: /etc/config
  volumes:
    - name: redis-conf-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: redis-config
  restartPolicy: Never

Autres solution pour créer des ConfigMaps

  • En utilisant le contenu complet d'un répertoire
kubectl create configmap my-config --from-file=./my/dir/path/
  • En utilisant le contenu d'un fichier d'un répertoire
kubectl create configmap my-config --from-file=./my/dir/path/myfile.txt
  • En utilisant des clés valeurs
kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2

Kubernetes : Secrets

  • Objet Kubernetes de type secret utilisé pour stocker des informations sensibles comme les mots de passe, les tokens, les clés SSH...
  • Similaire à un ConfigMap, à la seule différence que le contenu des entrées présentes dans le champ data sont encodés en base64.
  • Il est possible de directement créer un Secret spécifique à l'authentification sur un registre Docker privé.
  • Il est possible de directement créer un Secret à partir d'un compte utilisateur et d'un mot de passe.
  • Limité à 1MiB de data

Kubernets : Secrets

  • S'utilisent de la même façon que les ConfigMap
  • La seule différence est le stockage en base64
  • 3 types de secrets:
  • Generic: valeurs arbitraire comme dans une ConfigMap
  • tls: certificat et clé pour utilisation avec un serveur web
  • docker-registry: utilisé en tant que imagePullSecret par un pod pour pouvoir pull les images d'une registry privée

Kubernetes : Secrets

$ kubectl create secret docker-registry mydockerhubsecret \
--docker-username="employeeusername" --docker-password="employeepassword" \
--docker-email="employee.email@organization.com"
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'

Kubernetes : Secrets

apiVersion: v1
kind: Secret
metadata:
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  namespace: default
  resourceVersion: "164619"
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

KUBERNETES : Gestion des Ressources

Pods resources : requests et limits

  • Permettent de gérer l'allocation de ressources au sein d'un cluster
  • Par défaut, un pod/container sans request/limits est en best effort
  • Request: allocation minimum garantie (réservation)
  • Limit: allocation maximum (limite)
  • Se base sur le CPU et la RAM

  • Relation entre requests et limits
    • Requests <= Limits: La valeur de la request doit toujours être inférieure ou égale à celle de la limit.
    • Qualité de service (QoS): Les valeurs de requests et limits définissent le niveau de QoS d'un pod (BestEffort, Burstable, Guaranteed).

QoS

  • BestEffort :
    • Pas de limites ni de requests définies: Le pod peut consommer autant de ressources que disponibles, mais il n'a aucune garantie.
    • Conséquences: Le pod peut être évincé à tout moment si les ressources du nœud sont insuffisantes, ce qui peut entraîner des interruptions de service.
  • Burstable :
    • Requests définies: Le pod a une garantie minimale de ressources (requests).
    • Pas de limites strictes: Le pod peut dépasser ses requests si les ressources sont disponibles, mais il peut être évincé si d'autres pods Guaranteed ont besoin de ressources.
    • Conséquences: Le pod bénéficie d'une certaine priorité, mais il peut être impacté par les besoins des pods Guaranteed.
  • Guaranteed :
    • Requests et limites définies: Le pod a une garantie minimale de ressources (requests) et une limite maximale (limits).
    • Priorité élevée: Le pod a la plus haute priorité et ne peut pas être évincé tant qu'il respecte ses limites.
    • Conséquences: Le pod bénéficie d'une garantie de ressources stable, ce qui est idéal pour les applications critiques.

Exemple concret :

Un nœud Kubernetes avec 4 cœurs CPU.

- Pod BestEffort: Il peut utiliser 0, 1, 2, 3 ou 4 cœurs, selon la disponibilité.
- Pod Burstable (requests: 2 cœurs, pas de limits): Il est garanti d'avoir au moins 2 cœurs, mais il peut en utiliser jusqu'à 4 s'ils sont disponibles. Si un pod Guaranteed a besoin de 2 cœurs, le pod Burstable peut en perdre 2.
- Pod Guaranteed (requests: 2 cœurs, limits: 2 cœurs): Il a toujours 2 cœurs garantis et ne peut pas en utiliser plus.

Pods resources : CPU

  • 1 CPU est globalement équivalent à un cœur
  • L'allocation se fait par fraction de CPU:
  • 1 : 1 vCPU entier
  • 100m : 0.1 vCPU
  • 0.5 : 1/2 vCPU
  • Lorsqu'un conteneur atteint la limite CPU, celui ci est throttled

Pods resources : RAM

  • L'allocation se fait en unité de RAM:
  • M : en base 10
  • Mi : en base 2
  • Lorsqu'un conteneur atteint la limite RAM, celui ci est OOMKilled

Pods resources : requests et limits

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

LimitRanges

  • l'objet LimitRange permet de définir les valeurs minimales et maximales des ressources utilisées par les containers et les pods pour les requests et limits de CPU, de mémoire et de stockage
  • l'objet LimitRange s'applique au niveau du namespace
  • les limites spécifiées s'appliquent à chaque pod/container créé dans le namespace
  • le LimitRange ne limite pas le nombre total de ressources disponibles dans le namespace

LimitRanges

apiVersion: v1
kind: LimitRange
metadata:
  name: limit-example
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256 Mi
    type: Container

ResourceQuotas

  • un objet ResourceQuota limite le total des ressources de calcul consommées par les pods ainsi que le total de l'espace de stockage consommé par les PersistentVolumeClaims dans un namespace
  • il permet aussi de limiter le nombre de pods, PVC, réplicas, services et autres objets qui peuvent être créés dans un namespace

ResourceQuotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-and-ram
spec:
  hard:
    requests.cpu: 400m
    requests.memory: 200Mi
    limits.cpu: 600m
    limits.memory: 500Mi

ResourceQuotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-for-objects
spec:
  hard:
    pods: 200
    services: 10
    secrets: 20
    configmaps: 40
    persistentvolumeclaims: 40
    services.nodeports: 0
    services.loadbalancers: 0
    count/roles.rbac.authorization.k8s.io: 10

ResourceQuotas

KUBERNETES : Observabilité et Monitoring

Sondes : Readiness, Liveness et StartUP

  • Permettent à Kubernetes de sonder l'état d'un pod et d'agir en conséquence
  • 3 types de sonde : Readiness, Liveness, StartUp
  • 4 manières de sonder :
  • TCP : ping TCP sur un port donné
  • HTTP: http GET sur une url donnée
  • Command: Exécute une commande dans le conteneur
  • grpc : standard GRPC Health Checking Protocol

Sondes : Startup

  • Disponible en bêta à partir de la version 1.18
  • Utiles pour les applications qui ont un démarrage lent
  • Permet de ne pas augmenter les initialDelaySeconds des Readiness et Liveness
  • Elle sert à savoir quand l'application est prête
  • Les 3 sondes combinées permet de gérer très finement la disponibilité de l'application

Sondes : Readiness

  • Gère le trafic à destination du pod
  • Un pod avec une sonde readiness NotReady ne reçoit aucun trafic
  • Permet d'attendre que le service dans le conteneur soit prêt avant de router du trafic
  • Un pod Ready est ensuite enregistrer dans les endpoints du service associé

Sondes : Liveness

  • Gère le redémarrage du conteneur en cas d'incident
  • Un pod avec une sonde liveness sans succès est redémarré au bout d'un intervalle défini
  • Permet de redémarrer automatiquement les pods "tombés" en erreur

Différents types de sondes : httpGet

  • Effectuer une requête HTTP GET vers le conteneur
  • La requête sera effectuée par la Kubelet (ne nécessite pas de binaires supplémentaires dans l'image du conteneur)
  • Le paramètre port doit être spécifié
  • Les paramètres path et httpHeaders supplémentaires peuvent être spécifiés de manière optionnelle
  • Kubernetes utilise le code de statut HTTP de la réponse :
    • 200-399 = succès
    • tout autre code = échec

Différents types de sondes : exec

  • Exécute un programme arbitraire à l'intérieur du conteneur (comme avec kubectl exec ou docker exec)
  • Le programme doit être disponible dans l'image du conteneur
  • Kubernetes utilise le code de sortie du programme (convention UNIX standard : 0 = succès, toute autre valeur = échec)

Différents types de sondes : tcpSocket

  • Kubernetes vérifie si le port TCP indiqué accepte des connexions
  • Il n'y a pas de vérification supplémentaire 🫥 Il est tout à fait possible qu'un processus soit défaillant, tout en continuant à accepter des connexions TCP !

Différents types de sondes : grpc

  • Disponible en version bêta depuis Kubernetes 1.24
  • Exploite le protocole standard GRPC Health Checking
apiVersion: v1
kind: Pod
metadata:
  name: test-grpc
spec:
  containers:
  - name: agnhost
    image: registry.k8s.io/e2e-test-images/agnhost:2.35
    command: ["/agnhost", "grpc-health-checking"]
    ports:
    - containerPort: 5000
    - containerPort: 8080
    readinessProbe:
      grpc:
        port: 5000

Plus d'informations : https://kubernetes.io/blog/2022/05/13/grpc-probes-now-in-beta/

Sondes : Exemples

aapiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app-container
    image: my-image
    ports:
    - containerPort: 8080
    readinessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Authorization
          value: Bearer my-token
      initialDelaySeconds: 15
      periodSeconds: 5
      timeoutSeconds: 1
      failureThreshold: 3
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 2
      failureThreshold: 5
    startupProbe:
      exec:
        command:
        - cat /etc/nginx/nginx.conf
      initialDelaySeconds: 10
      timeoutSeconds: 5

Sondes : gérer les délais et seuils

  • initialDelaySeconds

    • Une probe peut avoir un paramètre initialDelaySeconds (défaut : 0).
    • Kubernetes attendra ce délai avant d'exécuter le probe pour la première fois.
    • Il est généralement préférable d'utiliser un startupProbe à la place. (mais ce paramètre existait avant l'implémentation des startup probes)
  • temps et seuils

    • Les probes sont exécutées à intervalles de periodSeconds (défaut : 10).
    • Le délai d'expiration d'un probe est défini avec timeoutSeconds (défaut : 1).
    • Si une probe prend plus de temps que cela, il est considéré comme un ÉCHEC.
    • Pour les probes de liveness et de startup, cela entraîne la terminaison et le redémarrage du conteneur.
    • Une probe est considérée comme réussi après successThreshold succès (défaut : 1).
    • Une probe est considérée comme en échec après failureThreshold échecs (défaut : 3).
    • Tous ces paramètres peuvent être définis indépendamment pour chaque probe.

Sondes : Startup Probe Bonnes pratiques

  • Si une startupProbe échoue, Kubernetes redémarre le conteneur correspondant.

  • En d'autres termes : avec les paramètres par défaut, le conteneur doit démarrer en 30 secondes. (failureThreshold × periodSeconds)

  • C'est pourquoi il faut presque toujours ajuster les paramètres d'une startupProbe. (spécifiquement, son failureThreshold)

  • Parfois, il est plus facile d'utiliser une readinessProbe à la place.(voir la prochaine diapositive pour plus de détails)

Sondes : Liveness Probe Bonnes pratiques

  • N'utilisez pas de probes de liveness pour des problèmes qui ne peuvent pas être résolus par un redémarrage. Sinon, les pods redémarrent sans raison, créant une charge inutile.

  • Ne dépendez pas d'autres services au sein d'une probe de liveness. Sinon, Possibilités d'échecs en cascade.(exemple : probe de liveness d'un serveur web qui effectue des requêtes vers une base de données)Assurez-vous que les probes de liveness répondent rapidement.

  • Le délai d'expiration par défaut des probes est de 1 seconde (cela peut être ajusté).

  • Si la probe prend plus de temps que cela, il finira par provoquer un redémarrage.

  • Une startupProbe nécessite généralement de modifier le failureThreshold.

  • Une startupProbe nécessite généralement également une readinessProbe.

  • Une seule readinessProbe peut remplir les deux rôles.

Sondes : Readiness Probe Bonnes pratiques

  • Presque toujours bénéfique.
  • Sauf pour :
    • les service web qui n'ont pas de route dédiée "health" ou "ping".
    • toutes les requêtes sont "coûteuses" (par exemple, nombreux appels externes).

Sondes : Exemple Kubernetes API

L'API Kubernetes inclut également des points de terminaison de contrôle d'état : healthz (obsolète), readyz, livez.

kubectl get --raw='/readyz?verbose'

Sondes : Exemple Kubernetes API

Point de terminaison readyz

[+]ping ok
[+]log ok
[+]etcd ok
[+]informer-sync ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]shutdown ok
readyz check passed

Sondes : Exemple Kubernetes API

Point de terminaison livez

kubectl get --raw='/livez?verbose'

Sondes : Exemple Kubernetes API

+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
livez check passed

KUBERNETES : Utilisation et Déploiement des Ressources

Kubernetes : kubectl

  • Le seul (ou presque) outil pour interagir avec des clusters Kubernetes
  • Utilise un ou plusieurs fichier(s) de configuration (kubeconfig) pour communiquer avec l'API de Kubernetes
  • Le(s) fichier(s) se trouve(nt) par défaut dans le répertoire ~/.kube/config

  • Le fichier de configuration contient des informations essentielles pour se connecter au cluster, notamment :
    • L'adresse(URI) de l'APIServer
    • Les chemins des certificats TLS utilisés pour l'authentification
    • Le contexte actuel (cluster, utilisateur, namespace) pour cibler un environnement spécifique.
    • Des informations d'identification (jetons, mots de passe) pour l'authentification.
  • Fichier kubeconfig peut être passé en paramètre de kubectl avec le flag --kubeconfig
    • ex: kubectl --kubeconfig=/opt/k8s/config get po
  • Fichier kubeconfig peut être passé en paramètre de kubectl avec la variable d'nvironnement KUBECONFIG
    • ex: KUBECONFIG=/opt/k8s/config kubectl get pods

Kubeconfig 1/4

Un seul fichier pour gérer tous les clusters avec trois informations :

  • Serveurs (IP, CA Cert, Nom)
  • Users (Nom, Certificat, Clé)
  • Context, association d'un user et d'un serveur

Kubeconfig 2/4

Synthèse architecture
Synthèse architecture

Kubeconfig 3/4


apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FU..
    server: https://akshlprod001-e419e3f0.hcp.northeurope.azmk8s.io:443
  name: aks-hl-prod-001
contexts:
- context:
    cluster: aks-hl-prod-001
    namespace: velero
    user: clusterUser_rg-hl-prod-001_aks-hl-prod-001
  name: aks-hl-prod-001
current-context: aks-hl-prod-001
kind: Config
preferences: {}
users:
- name: clusterUser_rg-hl-prod-001_aks-hl-prod-001
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t..
    client-key-data: LS0tLS1CRUdJTiBSU0Eg..
    token: 0ad033b165e2f7a4f705ca6defef8555ff501345e2324cf337b68820d85dc65bae39c47bb58ad913b0385a0d7eb5df6e872dbd1fe62fd34ca6e4ed58b2e8a733

Kubeconfig 3/4

Lorsque vous accédez à plusieurs clusters Kubernetes, vous aurez de nombreux fichiers kubeconfig.

Par défaut, kubectl recherche uniquement un fichier nommé config dans le répertoire $HOME/.kube.

Alors, comment pouvons-nous fusionner plusieurs fichiers kubeconfig en un seul ?

    1. Faire une copie de votre fichier kubeconfig (au cas ou 😱...)
cp ~/.kube/config ~/.kube/config-backup 
    1. Définir la variable d'environnement KUBECONFIG

La variable d'environnement KUBECONFIG est une liste de chemins vers des fichiers de configuration, par exemple :

export KUBECONFIG=~/.kube/config:/path/cluster1/config:/path/cluster2/config:/path/cluster3/config
    1. Fusionner tous les fichiers kubeconfig en un seul
kubectl config view --flatten > all-in-one-kubeconfig.yaml
    1. Remplacer l'ancien fichier de configuration par le nouveau fusionné
mv all-in-one-kubeconfig.yaml ~/.kube/config
    1. Tester !
kubectl config get-contexts

Kubernetes : Kubectl

Kubernetes : kubectl api-resources

  • Afficher la liste des ressources API supportées par le serveur:
$ kubectl api-resources
NAME                              SHORTNAMES   APIGROUP                             NAMESPACED   KIND
configmaps                        cm                                                true         ConfigMap
limitranges                       limits                                            true         LimitRange
namespaces                        ns                                                false        Namespace
nodes                             no                                                false        Node
persistentvolumeclaims            pvc                                               true         PersistentVolumeClaim
persistentvolumes                 pv                                                false        PersistentVolume
pods                              po                                                true         Pod
secrets                                                                             true         Secret
services                          svc                                               true         Service
daemonsets                        ds           apps                                 true         DaemonSet
deployments                       deploy       apps                                 true         Deployment
replicasets                       rs           apps                                 true         ReplicaSet
statefulsets                      sts          apps                                 true         StatefulSet
horizontalpodautoscalers          hpa          autoscaling                          true         HorizontalPodAutoscaler
cronjobs                          cj           batch                                true         CronJob
jobs                                           batch                                true         Job
ingresses                         ing          extensions                           true         Ingress
  • Pourquoi utiliser kubectl api-resources ?
    • Découverte: Pour connaître les ressources disponibles dans votre cluster.
    • Documentation: Pour obtenir des informations sur les différentes ressources et leurs propriétés.
    • Développement: Pour créer des scripts et des outils d'automatisation.
    • Dépannage: Pour identifier les problèmes liés à des ressources spécifiques.

Kubernetes : kubectl explain

  • Le "man pages" de kubernetes
  • Explorer les types et définitions
kubectl explain type
  • Expliquer la définition d'un champs de ressource, ex:
kubectl explain node.spec
  • Boucler sur les définitions
kubectl explain node --recursive

Kubernetes : Kind

  • Les noms de ressources les plus courants ont 3 formes:

    • singulier (par exemple, node, service, deployment)
    • pluriel (par exemple, nodes, services, deployments)
    • court (par exemple no, svc, deploy)
  • Certaines ressources n'ont pas de nom court (clusterroles, clusterrolebindings, roles ...)

  • Les points de terminaison (endpoints) ont uniquement une forme plurielle ou courte (ep)

Kubernetes - Obtenir des informations : kubectl get

Nous allons explorer en détail les différents types de ressources Kubernetes plus tard dans ce cours.

Pour l'instant, concentrons-nous sur l'utilisation de kubectl pour récupérer des informations sur notre cluster.

Voiçi quelques exemples d'utilisation de cette commande très puissante

  • Afficher les noeuds du cluster :
kubectl get nodes
  • Ces commandes sont équivalentes:
kubectl get no
kubectl get nodes

Kubernetes - Obtenir des informations : kubectl get

  • plus d'infos
kubectl get nodes -o wide
  • Sortie yaml / json
kubectl get nodes -o yaml
kubectl get nodes -o json
  • Utiliser JSONPath

    • Plus d'infos : https://kubernetes.io/docs/reference/kubectl/jsonpath/

kubectl get pods -o=jsonpath='{@}'
kubectl get pods -o=jsonpath='{.items[0]}'

kubectl get pods  \
  --output=jsonpath='{.items[0].metadata.name}'

Kubernetes - Obtenir des informations : kubectl get

  • Utiliser jq
kubectl get nodes -o json |
        jq ".items[] | {name:.metadata.name} + .status.capacity"

⚠ : Il faut utiliser jq quand on a besoin de regexp car JSONPath ne les supporte pas.

ex:


# KO :
kubectl get pods -o jsonpath='{.items[?(@.metadata.name=~/^test$/)].metadata.name}'

# OK :
kubectl get pods -o json | jq -r '.items[] | select(.metadata.name | test("test-")).spec.containers[].image'

Kubernetes - Obtenir des informations : kubectl get

  • Afficher les namespaces
kubectl get ns
kubectl get namespaces
  • Par défaut, kubectl utilise le namespace default
  • Il est possible de sélectionner un namespace avec l'option -n ou --namespace
kubectl -n kube-system get pods

Kubernetes - Obtenir des informations : kubectl get

  • Afficher les pods (pour le namespace default)
kubectl get pods
kubectl get pod

Kubernetes - Obtenir des informations : kubectl get

  • Afficher les services (pour le namespace default):
kubectl get services
kubectl get svc

Kubernetes : kubectl get

  • Afficher les ressources d'un namespace particulier
  • Utilisable avec la plupart des commandes kubectl
kubectl get pods --namespace=kube-system
kubectl get pods -n kube-system
# Mais aussi sur d'autres commandes
kubectl create -n NNN ...
kubectl run -n NNN ...
kubectl delete -n NNN ...
# ...

Kubernetes - Obtenir des informations : kubectl get

  • Pour lister des ressources dans tous les namespaces : --all-namespaces
  • Depuis kubernetes 1.14 on peut utiliser le flag -A en raccourci
  • Il est possible de l'utiliser avec beaucoup de commande kubectl pour manipuler toutes les ressources
kubectl get pods --all-namespaces
# ou
kubectl get pods -A
# autres actions
kubectl delete -A ...
kubectl label -A ...

Kubectl : Se déplacer dans un Namespace de manière permanente (comme un cd)

Évite de toujours préciser le flag -n


kubectl get ns

kubectl config set-context --current --namespace <nom-du-namespace>

# ou

alias kubens='kubectl config set-context --current --namespace '

# ex: kubens kube-system 

Kubernetes : namespace kube-public

kube-public est créé par kubeadm

kubectl get all -n kube-public
  • Le configMap contient les informations données par la commande kubectl cluster-info
kubectl -n kube-public get configmaps
# voir le contenu du configmap (cm)
kubectl -n kube-public get configmap cluster-info -o yaml
# Ce configmap est lisible par tout le monde sans authentification
curl -k https://{NodeIP}/api/v1/namespaces/kube-public/configmaps/cluster-info

# Contient le kubeconfig
  • Ce configmap contient l'url de l'API du serveur, et la clé publique de l'AC

  • Ce fichier ne contient pas de clés client ni de tokens

  • Il ne s'agit pas d'informations sensibles

Kubernetes : kubeconfig

  • Extraire le kubeconfig du configmap cluster-info
curl -sk https://<IP PRIV>/api/v1/namespaces/kube-public/configmaps/cluster-info \
     | jq -r .data.kubeconfig

Kubernetes : namespace kube-node-lease

Qu'est-ce qu'un Lease dans Kubernetes ? Un Lease est un objet qui expire après un certain temps s'il n'est pas renouvelé. Dans le contexte de kube-node-lease, chaque nœud du cluster a un Lease associé. La kubelet (l'agent Kubernetes s'exécutant sur chaque nœud) envoie régulièrement des mises à jour à ce Lease pour indiquer qu'il est toujours en fonctionnement.

  • Ce namespace particulier existe depuis la 1.14
  • Il contient un objet leasepar noeud
  • Ces leases permettent d'implémenter une nouvelle méthode pour vérifier l'état de santé des noeuds
  • Voir (KEP-0009)[https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/0009-node-heartbeat.md] pour plus d'information

Kubernetes : kubectl describe

  • kubectl describe a besoin d'un type de ressource et optionnellement un nom de ressource
  • Il est possible de fournir un préfixe de nom de ressource

  • ex:

 kubectl describe node/worker-0
 kubectl describe node worker-0
  • Pourquoi utiliser kubectl describe ? :

    • Dépannage: Pour comprendre pourquoi un objet ne fonctionne pas comme prévu.
    • Audit: Pour vérifier la configuration d'un objet et s'assurer qu'elle correspond à vos attentes.
    • Apprentissage: Pour mieux comprendre la structure et le fonctionnement des différents objets Kubernetes.

Kubernetes : Création d'objets Kubernetes

Kubernetes : Création d'objets Kubernetes

  • Les objets Kubernetes sont créés sous la forme de fichiers JSON ou YAML et envoyés à l'APIServer

  • Possible d'utiliser la commande kubectl run, mais limitée aux deployments et aux jobs

  • L'utilisation de fichiers YAML permet de les stocker dans un système de contrôle de version comme git, mercurial, etc...

  • La documentation de référence pour l'API Kubernetes https://kubernetes.io/docs/reference/#api-reference

Kubernetes : Créer un pod en ligne de commande

  • Cette commande avant la 1.18 créait un deployment
  • Depuis elle démarre un simple pod
# Création d'un pod en tâche de fond
kubectl run pingu --image=alpine -- ping 127.1
# Création d'un pod en intératif
kubectl run -i --tty my-pod --image=debian -- /bin/bash

⚠ : Notez le --entre le nom de l'image et la commande à lancer

Kubernetes : Créer un déploiement (par exemple) en ligne de commande

  • kubectl create deployment ...
  • Depuis kubernetes 1.19, il est possible de préciser une commande au moment du create
kubectl create deployment pingu --image=alpine -- ping 127.1

⚠ : Notez le --entre le nom de l'image et la commande à lancer

Kubernetes : Création d'objets Kubernetes

  • Pour créer un object Kubernetes depuis votre fichier YAML, utilisez la commande kubectl create :
kubectl create -f object.yaml
  • Il est possible de créer des objets Kubernetes à partir d'une URL :
kubectl create -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/frontend-deployment.yaml

Kubernetes : Création d'objets Kubernetes

  • Pour les supprimer exécuter simplement :
kubectl delete -f object.yaml
  • Mettre à jour un objet Kubernetes en écrasant la configuration existante:
kubectl replace -f object.yaml
kubectl apply -f object.yaml

⚠ : Il est possible d'utiliser apply pour créer des resources.

Kubernetes : Kubernetes Dashboard

  • Interface graphique web pour les clusters Kubernetes
  • Permet de gérer les différents objets Kubernetes créés dans le(s) cluster(s).
  • Installé par défaut dans minikube

Kubernetes : Kubernetes Dashboard

Kubernetes : Kubernetes Dashboard

  • Interface web pour manager les ressources kubernetes
  • Le dashboard requière une authentification (token ou kubeconfg)
  • Plusieurs alternatives open source existent :
  • k9s
  • octant
  • skooner
  • lens
  • ...

Kubernetes : Kubernetes Dashboard

Étape 1: Déployer le Dashboard

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

Étape 2: Créer un compte de service et un rôle d'administration

  1. Créer un fichier YAML pour le compte de service:
# dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
  1. Appliquer le fichier YAML pour créer le compte de service:
kubectl apply -f dashboard-adminuser.yaml

Kubernetes : Kubernetes Dashboard

  1. Créer un fichier YAML pour le rôle d'administration:
# admin-role-binding.yaml
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
  1. Appliquer le fichier YAML pour créer le rôle d'administration:

kubectl apply -f admin-role-binding.yaml

Kubernetes : Kubernetes Dashboard

Étape 3: Récupérer le token d'accès

kubectl -n kubernetes-dashboard create token admin-user

Copiez le token affiché et sauvegardez le.

Kubernetes : Kubernetes Dashboard

Étape 4: Accéder au Dashboard

Si vous êtes sur votre PC (installation locale de kubernetes)

Démarrer un proxy pour accéder au Dashboard:

kubectl proxy

Kubernetes : Kubernetes Dashboard

Si vos machines sont déployées sur un Cloud Provider (AWS, Azure, GCP, etc)

  • Sur le master
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard 8443:443 --address=0.0.0.0

Dans votre navigateur utilisez l'url suivante en l'adaptant avec l'adresse IP publique du master

https://[IP-PUBLIQUE-MASTER]:8443/

  • Acceptez l'alerte de sécurité concernant le certificate

  • Se connecter avec le token:
    • Lorsque vous êtes invité à vous connecter, choisissez l'option "Token" et entrez le token que vous avez récupéré à l'Étape 3.

Kubernetes : Kubernetes Dashboard

Kubernetes : Kubernetes Dashboard

Kubernetes : Kubernetes Dashboard

Kubernetes : Kubernetes Dashboard

Résumé des commandes kubectl

  • Lister les ressources : kubectl get
    • Utilité : Voir les objets qui tournent sur le cluster.
    • Exemples :

      # Lister les pods dans le namespace actuel
      kubectl get pods
      
      # Lister les nœuds avec plus d'informations
      kubectl get nodes -o wide
      
      # Lister les services dans tous les namespaces
      kubectl get services -A
  • Inspecter une ressource : kubectl describe
    • Utilité : Obtenir une vue détaillée et les événements récents d'un objet. Indispensable pour le débogage.
    • Exemple :

      # Voir les détails d'un pod spécifique
      kubectl describe pod <nom-du-pod>
  • Créer ou Mettre à jour : kubectl apply
    • Utilité : Appliquer une configuration définie dans un fichier YAML. La commande la plus courante pour déployer.
    • Exemple :

      kubectl apply -f mon-deploiement.yaml
  • Supprimer des ressources : kubectl delete
    • Utilité : Supprimer les objets créés à partir d'un fichier YAML.
    • Exemple :

      kubectl delete -f mon-deploiement.yaml

Aide et Découverte

  • Découvrir les API : kubectl api-resources
    • Utilité : Lister tous les types de ressources que vous pouvez créer sur le cluster (ex: pods, deployments, ingresses...).
    • Exemple :

      kubectl api-resources
  • Obtenir de la documentation : kubectl explain
    • Utilité : Comprendre la structure et les champs possibles pour un type de ressource, directement dans le terminal.
    • Exemple :

      # Comprendre ce qu'on peut mettre dans la section 'spec' d'un pod
      kubectl explain pod.spec

KUBECTL : Usage Avancé

Kubectl : Usage avancé

  • Certaines commandes qui modifient un déploimement accepte un flag optionnel --record
  • Ce flag stocke la ligne de commande dans le déploiement
  • Et est copié aussi dans le replicaSet (annotation)
  • Cela permet de suivre quelle commande a créé ou modifié ce replicatset

$ kubectl create -f nginx.yaml --record
deployment.apps/nginx created

# Voir les informations
kubectl rollout history

Kubectl : Usage avancé

  • Utiliser le flag --record
# déployer l'image worker:v0.2
kubectl create deployment worker --image=dockercoins/worker:v0.2

# Roll back `worker` vers l'image version 0.1:
kubectl set image deployment worker worker=dockercoins/worker:v0.1 --record

# Le remettre sur la version 0.2:
kubectl set image deployment worker worker=dockercoins/worker:v0.2 --record

# Voir l'historique des changement:
kubectl rollout history deployment worker

Kubectl : Usage avancé

  • Il est possible d'augmenter le nombre de pods avec la commande kubectl scale :
kubectl scale --replicas=5 deployment nginx
  • Il est possible de changer l'image d'un container utilisée par un Deployment :
kubectl set image deployment nginx nginx=nginx:1.15

Kubectl : Usage avancé

  • Dry run. Afficher les objets de l'API correspondant sans les créer :
kubectl run nginx --image=nginx --dry-run=client
kubectl run nginx --image=nginx --dry-run=server
  • Démarrer un container en utilisant une commande différente et des arguments différents :
kubectl run nginx --image=nginx \
--command -- <cmd> <arg1> ... <argN>
  • Démarrer un Cron Job qui calcule π et l'affiche toutes les 5 minutes :
kubectl run pi --schedule="0/5 * * * ?" --image=perl --restart=OnFailure \
-- perl -Mbignum=bpi -wle 'print bpi(2000)'

Kubectl : Usage avancé

  • Se connecter à un container:
kubectl run -it busybox --image=busybox -- sh
  • S'attacher à un container existant :
kubectl attach my-pod -i
  • Accéder à un service via un port :
kubectl port-forward my-svc 6000
  • Mettre en place de l'auto-scaling ex: Mise à l'échelle automatique avec un minimum de 2 et un maximum de 10 réplicas lorsque l'utilisation du processeur est égale ou supérieure à 70 %
kubectl autoscale deployment my-Deployments --min=2 --max=10 --cpu-percent=70  

Kubectl : Logging

  • Utiliser kubectl pour diagnostiquer les applications et le cluster kubernetes :
kubectl cluster-info
kubectl get events --sort-by='.lastTimestamp'
kubectl describe node <NODE_NAME>
kubectl describe node <node-name> | grep Taints
kubectl  logs (-f) <POD_NAME>

Kubectl : Logs

  • Voir les logs containers kubectl logs
  • Il est possible de donner un nom de pod ou un type/nom par exemple si l'on donne un nom de déploiement ou de replica set, les logs correspondront au premier pod
  • Par défaut les logs affichées sont celles du premier container dans le pod.
# exemple :
kubectl logs deploy/nginx
  • Faire un CTRL-Cpour arrêter la sortie

Kubectl : Afficher les logs en temps réel

kubectl logs supporte les options suivantes : - -f/--follow pour suivre les affichage des logs en temps réel (comme pour tail -f) - --tail pour n'afficher que les n lignes à partir de la fin de la sortie - --since pour n'afficher que les logs à partir d'une certaine date - --timestampsaffichera le timestamp du message

# exemple :
kubectl logs deploy/pingpong --tail 100 --follow --since=5s
# Affichera toutes les logs depuis 5 secondes et commencera au 100eme messages et continuera l'affichage des nouveaux messages

Kubectl : Afficher les logs de plusieurs pods

  • Lorsque on spécifie un nom de déploiement, seuls les logs d'un seul pod sont affichés

  • Pour afficher les logs de plusieurs pod il faudra utiliser un selecteur (label)

kubectl logs -l app=my-app --tail 100 # -f 

Kubectl : un outil très pratique pour les logs :

stern

pod network
pod network

Kubectl : Maintenance

  • Obtenir la liste des noeuds ainsi que les informations détaillées :
kubectl get nodes
kubectl describe nodes

Kubectl : Maintenance

  • Marquer le noeud comme unschedulable (+ drainer les pods) et schedulable :
kubectl cordon <NODE_NAME>
kubectl drain <NDOE_NAME>
kubectl uncordon <NODE_NAME>

Kubectl : Contexts

  • Dans le cas ou votre kubeconfig comporte plusieurs clusters

# lister les contextes
kubectl config get-contexts

# Se déplacer dans un contexte 
kubectl config use-context <nom-du-contexte>


# ou

alias kubectx='kubectl config use-context '

# ex: kubectx <nom-du-cluster>

Kubectl : Se déplacer dans un NS de manière permanente

Évite de toujours préciser le flag -n


kubectl get ns

kubectl config set-context --current --namespace <nom-du-namespace>

# ou

alias kubens='kubectl config set-context --current --namespace '

# ex: kubens kube-system 

Kubectl : Installer des plugins

krew est un manager de plugins pour kubectl

installation de krew (https://krew.sigs.k8s.io/docs/user-guide/setup/install/)


kubectl krew install example

kubectl example deploy

Liste des plugins : https://krew.sigs.k8s.io/plugins/ très utiles :

  • neat : permet de d'avoir un ouput "propre" d'une resource kubernetes - très utile pour créer des manifestes à partir de resources existantes
  • ctx : permet de changer de contexte facilement
  • ns : permet de changet de namespace facilement
  • node-shell : Créer un shell racine sur un nœud via kubectl, très pratique sur les CSP
  • df-pv : Afficher l'utilisation du disque (comme la commande df) pour les volumes persistants
  • popeye : Analyse vos clusters pour détecter d'éventuels problèmes de ressources

Conclusion

CKA, CKAD et CKS

  • Certified Kubernetes Application Developer (CKAD)
  • Certified Kubernetes Administrator (CKA)
  • Certified Kubernetes Security Specialist (CKS)

  • Les programmes CKAD, CKA et CKS ont été développés par la Cloud Native Computing Foundation (CNCF), en collaboration avec la Linux Foundation, pour faciliter l'extension de l'écosystème Kubernetes grâce à des certifications standardisées.

https://www.cncf.io/certification/ckad/ https://www.cncf.io/certification/cka/ https://www.cncf.io/certification/cks/

A vous de Jouer !