Kubernetes, c'est quoi ?

2 Décembre 2021 • 11 min

Kubernetes, souvent abrégé kube ou encore K8s, est la solution d'orchestration de conteneurs applicatifs de référence qui s’est imposée ces dernières années.

Kubernetes permet de déployer des applications conteneurisées sur tout type d’infrastructure IT et de gérer de façon centralisée les différentes ressources dont elles ont besoin. Cela peut être des ressources de computing, de stockage, de base de donnée, de networking, etc. Ces ressources sont regroupées dans un cluster Kubernetes composé d’un ensemble de serveurs.

Cet article ne revient pas sur la notion de conteneurs applicatifs (préalable à l’utilisation de K8s), il présente Kubernetes dans ses grandes lignes, son utilité pour l’opération de plateformes, les différents types de déploiements.

Un peu d’histoire sur Kubernetes

Kubernetes a initialement été développé par Google en 2013, puis le projet a été rendu open-source en 2014.

Kubernetes a profité de 15 ans d’expérience des équipes de Google sur la gestion de cluster en se basant sur les leçons tirées de l’écriture et de l’exploitation d’un projet interne nommé Borg, présenté dans un papier publié en 2015 : Large-scale cluster management at Google with Borg. L’outil n’est cependant pas disponible au public. Ces deux projets s’appuient sur le concept de conteneurs, Google ayant été l’un des premiers contributeurs aux technologies de conteneurisation via les cgroups Linux, concept introduit en 2006.

En 2015, Google fait le don du projet à la Cloud Native Computing Foundation rattachée à la Linux Foundation. Le projet devient donc indépendant et neutre par rapport aux fournisseurs de services cloud. En quelques années, Kubernetes s’est progressivement imposé comme la solution d’orchestration la plus utilisée et bénéficie de l’apport d’une très grande communauté.

Pourquoi Kubernetes ?

Tant qu’une application conteneurisée est déployée sur une seule machine (et si cela convient en terme de disponibilité), il n’est pas nécessaire d’utiliser une solution d’orchestration.

Mais dès lors que les applications sont complexes, et que l’on souhaite assurer la haute disponibilité du service sur différents environnements (serveurs, clouds, etc.), vous allez rapidement devoir gérer un grand nombre de conteneurs applicatifs, avec des besoins variés en ressources infrastructure.

Vous allez ainsi probablement être confronté à ce type de problématiques :

  • Certains services doivent être accessibles depuis l’Internet, d’autres seulement par les autres conteneurs (avec potentiellement des logiques de load-balancing interne / externe) : la configuration réseau devient complexe et doit être réalisée manuellement.
  • Le stockage doit être géré manuellement (par exemple, monter les bons volumes aux bons endroits, etc.).
  • Les conteneurs ne permettent pas nativement de scaler horizontalement, il faut donc lancer et répartir manuellement les différents conteneurs sur les différents serveurs.
  • Il n’est pas possible de facilement / automatiquement réagir aux évènements, comme par exemple la montée en charge, l’indisponibilité d’une machine ou d’un conteneur, etc.
  • Il est difficile d’obtenir une liste de tous les conteneurs liés à un service ou une application déployés sur les différents serveurs. L’exploitation peut ainsi s’avérer particulièrement difficile.

Kubernetes est une solution d’orchestration de conteneurs qui permet notamment de résoudre ces problématiques, et bien d’autres encore. Regardons ceci de plus près !

L’essentiel sur Kubernetes

Principales ressources de Kubernetes

Kubernetes definit plusieurs types de ressources afin de décrire la nature et l’état d’un cluster :

  • Les Nodes, ce sont les serveurs (ou instances) virtuels (VM) ou physique (“bare-metal”) du cluster Kubernetes.
  • Les Pods, des groupes de conteneurs qui tournent ensemble sur un node. Ils sont considérés comme l’unité de base de Kubernetes. Dans un pod on a généralement un conteneur applicatif, et zéro, un ou plusieurs side-car(s), cela peut-être par exemple un agent de monitoring du conteneur applicatif.
  • Les Deployments qui permettent de créer des pods en suivant un modèle défini par l’utilisateur. Ils permettent notamment de préciser le nombre de Replicas qui sont ensuite instanciés par Kubernetes. Lorsque vous supprimez un pod créé par un Deployment, Kubernetes le reconstruit automatiquement. Ils sont destinés à des long-running process tels que des services webs ou des workers.
  • Les DaemonSets permettent un peu à la façon des Deployments de demander à K8s de créer des pods, à la différence que ceux-ci garantissent l’existence d’un et d’un seul Replica par node.
  • Les CronJobs simulent le fonctionnement d’une crontab en créant des pods à intervalles réguliers qui exécuteront les tâches en question. Ces pods sont éphémères, ils s’arrêtent une fois la tâche accomplie.
  • Les Ingress permettent d’exposer des ports à l’extérieur d’un pod et/ou d’exposer un service avec un nom de domaine.
  • Les Secrets permettent de stocker et de gérer de façon sécurisée des informations sensibles (comme des identifiants)
  • Et bien d’autres encore, comme les Namespaces, les Services, les ConfigMaps

Moins connu mais intéressant pour opérer une plateforme sous Kubernetes, il est possible aussi de rajouter de nouveaux “types de workload” (en plus de ces Deployments, StatefulSets, DaemonSets, CronJob …) qui étendent les fonctionnalités de ces derniers, comme le propose par exemple le projet OpenKruise.

Architecture Kubernetes

Kubernetes est un ensemble de composants permettant de gérer les différentes parties d’un cluster et d’en orchestrer les conteneurs. L’ensemble des composants qui constituent le cluster est appelé control plane, ils peuvent être repliqués pour assurer une haute-disponibilité du service. L’orchestration de conteneurs dans K8s, c’est le fait de scheduler, exécuter et stopper des conteneurs automatiquement selon certaines règles définies par l’utilisateur via les ressources de Kubernetes.

control plane Kubernetes

Ce schéma de Lucas Käldström montre les différentes parties du control plane (master) de Kubernetes, ainsi que les différentes parties des nodes (workers) d’un cluster :

  • API Server : L’API K8s permet de dialoguer avec le cluster et configurer ses différentes ressources.
  • etcd : Une base de données distribuée qui permet de stocker les ressources du cluster.
  • Scheduler : Un processus dont le but est d’assigner des pods à des nodes.
  • Controller Manager : Un processus qui inclut les boucles de contrôle principales de Kubernetes. Nous revenons sur ce concept dans la suite de cet article.

Les boucles de réconciliation Kubernetes

Kubernetes est un système déclaratif : l’utilisateur décrit le résultat qu’il attend et K8s le met en place, par opposition à un système impératif dans lequel il est du ressort de l’utilisateur de décrire la mise en place.

La nature déclarative de Kubernetes met en jeu deux concepts interdépendants : celui de l'état courant et celui de l'état désiré. L’état courant est l’état réel du cluster Kubernetes à un moment donné, tandis que l’état désiré correspond à la configuration donnée par l’utilisateur via les ressources abordées plus haut. La tâche de Kubernetes et plus particulièrement de son controller manager est de réaliser la réconciliation de ces deux état en faisant converger l’état courant vers l’état désiré. Ceci est fait via ce qu’on appelle des boucles de réconciliation.

boucle de réconciliation Kubernetes

Cette approche apporte plusieurs bénéfices majeurs pour faciliter l’opération d’une plateforme sous Kubernetes, tels que :

  • Le self-healing : si un node n’est plus disponible pour une raison X ou Y, Kubernetes va automatiquement recréer les pods présents sur ce node sur un ou plusieurs autres nodes disponibles. De même, si un conteneur crashe, il sera automatiquement relancé.
  • Une grande résilience : lorsqu’une action ne fonctionne pas, comme par exemple une demande de création de certificat SSL, Kubernetes va automatiquement réessayer plusieurs fois à intervalle croissant de temps.
  • Du scheduling intelligent : Kubernetes va automatiquement assigner les pods à des nodes disponibles tout en répartissant la charge de travail entre ces nodes.

Les manifestes Kubernetes

Toutes les ressources Kubernetes sont définies via des manifestes au format YAML (format de données human-readable souvent utilisé dans les fichiers de configuration) ou plus rarement JSON et sont accessibles via l’API K8s.

Voici par exemple à quoi ressemble la description d’un pod :

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Les manifestes YAML sont la définition officielle de l’état désiré. Ces manifestes peuvent (et devraient) être versionnés dans un dépot de code comme git par exemple, ce qui permettra par la suite de monter un environnement de staging très facilement, ou encore de faciliter le mise en place d’un PRA (Plan de Reprise d’Activité).

Kubectl, la CLI officielle de Kubernetes

kubectl est l’outil en ligne de commande officiel de Kubernetes. Il permet de gérer les ressources du cluster, de créer des pods, de déployer des Deployments, etc.

Voici quelques exemples d’utilisation :

$ # lister les nodes du cluster
$ kubectl get nodes
NAME      STATUS   ROLES               AGE    VERSION
main1     Ready    controlplane,etcd   166d   v1.18.18
worker1   Ready    worker              166d   v1.18.18
worker2   Ready    worker              166d   v1.18.18
worker3   Ready    worker              55d    v1.18.18
$
$ # appliquer le yaml d'un Deployment
$ # crée ou met à jour le Deployment s'il existe déjà
$ kubectl apply -f ./nginx-deployment.yaml
deployment/nginx created
$
$ # supprimer un Deployment via son yaml
$ kubectl delete -f ./nginx-deployment.yaml
deployment "nginx" deleted

D’autres excellents outils tels que Lens (proposé par notre partenaire Mirantis) ou encore K9s (sur lequel j’ai eu l’occasion d’écrire un blogpost que je vous invite à lire : K9s, un outil de gestion de clusters Kubernetes) fournissent une interface graphique pour effectuer les mêmes actions que kubectl.

Extensions de Kubernetes : plugins, CRDs et opérateurs

Kubernetes embarque de nombreuses fonctionnalités nativement. Sur une plateforme de production cependant, il doit souvent être étendu de plusieurs façons :

  • Extension au niveau infrastructure : pour s’intégrer avec des “composants” externes spécialisés comme le stockage, le réseau ou encore le moteur d’exécution de conteneurs. L’intégration de ces composants est standardisée via des spécifications telles que CSI (Container Storage Interface) pour le stockage, CNI (Container Network Interface) pour le réseau et CRI (Container Runtime Interface) pour l’exécution des conteneurs. Pour chacune de ces spécifications, plusieurs implémentations existent déjà, par exemple Kube-Router pour la CNI, containerd pour la CRI ou encore OpenEBSpour la CSI. Vous pouvez également créer vos propres implémentations de ces spécifications pour couvrir vos propres besoins. C’est par exemple ce que nous avons fait chez Enix avec notre driver de stockage SAN iSCSI CSI qui est open-sourcé sur notre GitHub.

  • Extension au niveau fonctionnel : pour couvrir des besoins spécifiques. Par exemple on peut créer de nouveaux types de ressources grâce aux CRDs (Custom Resource Definition), elles-mêmes gérées par des opérateurs. Exemple concret : grâce à l’opérateur cert-manager, on peut utiliser l’API Kubernetes pour obtenir et renouveler des certificats TLS via Vault ou Let’s Encrypt, d’une manière relativement bien intégrée avec les autres ressources Kubernetes (notamment les Secrets et les Ingress). Un autre usage courant de ces fameux opérateurs est l’automatisation du cycle de vie de clusters de bases de données : Kubernetes devient par exemple capable d’assurer le provisioning d’un couple de serveurs SQL (avec réplication primaire/secondaire) et la reprise automatique en cas de défaillance.

Distributions Kubernetes

Kubernetes n’est donc pas prévu pour fonctionner seul. Lorsqu’on souhaite maîtriser l’ensemble des éléments de son cluster et disposer de fonctionnalités sur mesure pour les déployer sur l’infrastructure de son choix, les composants peuvent être installés manuellement. On parle de cluster Kubernetes Vanilla.

Une autre alternative existe pour déployer Kubernetes sur n’importe quel type d’infrastructure, sans vendor lock-in et sans perdre en portabilité (ou de façon mineure). Un peu à l’image de Linux, il s’agit des distributions Kubernetes qui incluent les outils essentiels au fonctionnement d’un cluster.

Elles peuvent aussi intégrer des fonctionnalités connexes souvent utilisées avec un cluster Kubernetes (par exemple une chaîne de monitoring Prometheus/Grafana, une chaîne GitOps ou un pipeline CI/CD, etc.).

Des distributions Kubernetes éprouvées : Rancher Kubernetes Engine, Omni/Talos, Mirantis Kubernetes Engine, D2iQ DKP ou encore Rancher K3s pour les systèmes embarqués et l'edge computing.

Des distributions plus propriétaires ou plus adhérentes à l’infrastructures sous-jacente existent également, par exemple VMware Tanzu ou Red Hat OpenShift.

Services Kubernetes managés

Une autre alternative consiste à utiliser les services Kubernetes managés des principaux fournisseurs de Cloud.

La prise en main est plus simple et plus rapide car la complexité de Kubernetes est en bonne partie masquée, le scaling des ressources est a priori facilité grâce à l’intégration entre le service K8s managé et les autres services du fournisseur Cloud.

Ces avantages ne viennent cependant pas sans contreparties : tous les besoins ne sont pas couverts nativement, on perd une partie de l’indépendance promise par Kubernetes, on déploie sur du cloud public donc sur des infrastructures partagées, etc.

Les principaux fournisseurs de services Cloud proposent un service managé Kubernetes. On peut citer par exemple :

  • Amazon Elastic Kubernetes Service (Amazon EKS)
  • Azure Kubernetes Service (Azure AKS)
  • Google Kubernetes Engine (Google GKE)
  • OVHcloud Managed Kubernetes Service
  • Scaleway Kapsule

Une précision pour conclure cette partie sur les distributions et services managés Kubernetes. Le choix d’implémentation et de solution Kubernetes peut s’avérer complexe : il dépend de vote stratégie infrastructure / cloud plus globale, ou encore de vos critères spécifiques liés à votre plateforme, à vos applicatifs conteneurisés et in-fine à votre métier.

Conclusion

Kubernetes apporte de réels bénéfices autant techniques qu'opérationnels dans la gestion des applications conteneurisées lorsqu’elles sont distribuées et/ou de taille importante : pour gérer le load-balancing, le scaling, pour faire des rolling update lors des mises en production, etc.

Kubernetes est cependant un outil vaste et complexe nécessitant une longue période d'apprentissage. Pour vous permettre d’aborder les conteneurs et Kubernetes avec sérénité, nous proposons chez Enix une formation reconnue (notamment grâce à notre formateur Jérôme Petazzoni !) et complète sur ces formidables technologies. Vous y découvrirez les notions abordées dans cet article et bien d’autres plus expertes, telles que le RBAC, les health checks ou encore les network policies.

Et si vous avez besoin d’aide pour déployer et opérer vos clusters Kubernetes, vous pouvez consulter notre approche originale d'infogérance Cloud Native ou nous contacter pour en discuter ensemble !


Ne ratez pas nos prochains articles DevOps et Cloud Native! Suivez Enix sur Twitter!