Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

CNI, CSI et CRI — Les interfaces d'extension de Kubernetes

16 min de lecture

Kubernetes ne gère pas directement le réseau, le stockage ou l’exécution des conteneurs. Il délègue ces responsabilités à des plugins externes via trois interfaces standardisées : CNI (réseau), CSI (stockage) et CRI (runtime). Comprendre ces interfaces est essentiel pour la certification CKA (domaine Cluster Architecture, 25%).

Ce guide explique le rôle de chaque interface et comment les diagnostiquer.

  • CNI : comment Kubernetes configure le réseau des Pods
  • CSI : comment Kubernetes accède au stockage externe
  • CRI : comment le kubelet communique avec le runtime de conteneurs
  • Les commandes de diagnostic pour chaque interface
┌─────────────────────────────────────────────────────────────────────────┐
│ KUBERNETES │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ kubelet │ │
│ └───────────┬─────────────────────┬─────────────────────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ CRI │ │ CNI │ │ CSI │ │
│ │ Runtime │ │ Réseau │ │ Stockage │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
└────────────┼─────────────────────┼─────────────────────┼────────────────┘
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ containerd │ │ Calico │ │ AWS EBS │
│ CRI-O │ │ Cilium │ │ Ceph CSI │
│ etc. │ │ Flannel │ │ NFS CSI │
└────────────┘ └────────────┘ └────────────┘
InterfaceAcronymeRôleExemple de plugins
CRIContainer Runtime InterfaceCréer/gérer les conteneurscontainerd, CRI-O
CNIContainer Network InterfaceConfigurer le réseau des PodsCalico, Cilium, Flannel
CSIContainer Storage InterfaceProvisionner le stockageAWS EBS, Ceph, NFS

Le CRI est l’interface gRPC entre le kubelet et le runtime de conteneurs. Il permet au kubelet de créer, démarrer, arrêter et supprimer des conteneurs sans connaître les détails d’implémentation du runtime.

Avant le CRI (Kubernetes < 1.5), le kubelet était couplé à Docker. Le CRI a permis de supporter d’autres runtimes comme containerd ou CRI-O.

RuntimeDescriptionCas d’usage
containerdRuntime léger, standard de factoClusters kubeadm, cloud providers
CRI-OOptimisé pour KubernetesOpenShift, clusters minimalistes
Fenêtre de terminal
# Voir le runtime utilisé par le kubelet
kubectl get nodes -o wide
NAME STATUS ROLES VERSION CONTAINER-RUNTIME
master1 Ready control-plane v1.35.2 containerd://1.7.14
worker1 Ready <none> v1.35.2 containerd://1.7.14
Fenêtre de terminal
# Détails du socket CRI
kubectl get node <node-name> -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}'

Le kubelet se connecte au runtime via un socket Unix. C’est le paramètre clé de la configuration CRI :

Fenêtre de terminal
# Socket containerd (défaut sur la plupart des distributions)
--container-runtime-endpoint=unix:///run/containerd/containerd.sock
# Socket CRI-O
--container-runtime-endpoint=unix:///var/run/crio/crio.sock

La configuration exacte varie selon les distributions. Sur un nœud kubeadm, vous pouvez vérifier :

Fenêtre de terminal
# Voir l'endpoint configuré
ps aux | grep kubelet | grep container-runtime-endpoint
# Ou dans la config kubelet (selon distribution)
cat /var/lib/kubelet/kubeadm-flags.env
Fenêtre de terminal
# Vérifier que le socket existe
ls -la /run/containerd/containerd.sock
# Tester la connexion avec crictl
crictl info
# Lister les conteneurs via CRI
crictl ps
# Lister les images
crictl images

Le CNI est la spécification qui définit comment configurer le réseau des conteneurs. Quand un Pod est créé, le runtime appelle les plugins CNI pour :

  1. Créer une interface réseau dans le Pod
  2. Assigner une adresse IP
  3. Configurer les routes
1. kubelet demande la création d'un Pod au runtime (CRI)
2. Le runtime crée le conteneur et son namespace réseau
3. Le runtime appelle les plugins CNI configurés
4. CNI assigne une IP et configure le réseau
5. Le Pod est accessible sur le réseau du cluster
PluginMode réseauForces
CalicoBGP / VXLAN / IP-in-IPNetwork Policies, performance
CiliumeBPFObservabilité, sécurité avancée
FlannelVXLAN / host-gwSimplicité, idéal pour débuter
CanalCalico + FlannelCombine les deux

Les plugins CNI sont configurés dans /etc/cni/net.d/ :

Fenêtre de terminal
# Lister les configurations CNI
ls /etc/cni/net.d/
10-calico.conflist

Exemple de configuration Calico :

{
"name": "k8s-pod-network",
"cniVersion": "1.0.0",
"plugins": [
{
"type": "calico",
"datastore_type": "kubernetes",
"ipam": {
"type": "calico-ipam"
},
"policy": {
"type": "k8s"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}

Les binaires des plugins sont dans /opt/cni/bin/ :

Fenêtre de terminal
ls /opt/cni/bin/
bandwidth bridge calico calico-ipam flannel host-local loopback portmap ...
Fenêtre de terminal
# Vérifier le plugin CNI installé
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel|weave'
# Voir l'IP attribuée à un Pod
kubectl get pod <pod-name> -o wide
# Vérifier le CIDR du cluster
kubectl cluster-info dump | grep -m 1 cluster-cidr
# Voir le CIDR alloué à chaque nœud
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
SymptômeCause probableSolution
Pod en ContainerCreatingPlugin CNI manquantInstaller un CNI (Calico, Flannel…)
Pod sans IPErreur IPAMVérifier logs du plugin CNI
Pods ne communiquent pasNetwork Policy ou erreur pluginVérifier les Network Policies

Le CSI est l’interface standard pour provisionner et attacher du stockage aux conteneurs. Il remplace les plugins de stockage “in-tree” (intégrés au code de Kubernetes).

Avant CSI, chaque type de stockage (AWS EBS, GCE PD, Ceph…) nécessitait du code dans le core Kubernetes. Avec CSI :

  • Les drivers sont développés indépendamment de Kubernetes
  • Les mises à jour de drivers n’impactent pas le cycle de release Kubernetes
  • N’importe quel vendor peut créer un driver CSI

Kubernetes redirige automatiquement les appels aux plugins in-tree vers les drivers CSI correspondants :

Plugin in-tree (déprécié)Driver CSI
awsElasticBlockStoreebs.csi.aws.com
gcePersistentDiskpd.csi.storage.gke.io
azureDiskdisk.csi.azure.com
cinder (OpenStack)cinder.csi.openstack.org
vsphereVolumecsi.vsphere.vmware.com
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PVC │───▶│ StorageClass │───▶│ CSI Driver │ │
│ │ (claim) │ │ (provisioner)│ │ (controller) │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │
└──────────────────────────────────────────────────┼───────────────┘
┌──────────────┐
│ Stockage │
│ externe │
└──────────────┘

Un driver CSI se compose de plusieurs pods :

ComposantRôleDéploiement typique
ControllerProvisionne/supprime les volumesDeployment dans kube-system
NodeMonte/démonte les volumesDaemonSet sur chaque nœud
CSI Sidecarsexternal-provisioner, external-attacher…Avec le controller
Fenêtre de terminal
# Lister les CSI Drivers installés
kubectl get csidrivers
NAME ATTACHREQUIRED PODINFOONMOUNT ...
ebs.csi.aws.com true false
efs.csi.aws.com false false
Fenêtre de terminal
# Détails d'un driver
kubectl describe csidriver ebs.csi.aws.com
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
fsType: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Fenêtre de terminal
# Vérifier les pods CSI
kubectl get pods -n kube-system | grep csi
# Logs du controller CSI
kubectl logs -n kube-system -l app=ebs-csi-controller -c csi-provisioner
# Vérifier les PV créés via CSI
kubectl get pv -o custom-columns=NAME:.metadata.name,DRIVER:.spec.csi.driver
# Événements de PVC
kubectl describe pvc <pvc-name>
AspectCRICNICSI
RôleExécuter les conteneursConfigurer le réseauProvisionner le stockage
Appelé parkubeletContainer runtimekubelet + sidecars + controller
ConfigSocket runtime/etc/cni/net.d/StorageClass
Exemplescontainerd, CRI-OCalico, CiliumAWS EBS, Ceph
Diagnosticcrictlkubectl get pods -n kube-systemkubectl get csidrivers

Structurez votre diagnostic par interface :

Symptômes : kubelet ne lance pas les Pods, erreurs “container runtime is down”

Fenêtre de terminal
# Vérifier que le socket existe
ls -la /run/containerd/containerd.sock
# Vérifier l'état du service
systemctl status containerd
journalctl -u containerd -n 50
# Tester la connexion
crictl info

Symptômes : Pods bloqués en ContainerCreating, pas d’IP assignée

Fenêtre de terminal
# Vérifier qu'un plugin CNI est installé
ls /etc/cni/net.d/
ls /opt/cni/bin/
# Vérifier les Pods CNI
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel'
# Logs du plugin CNI
kubectl logs -n kube-system -l k8s-app=calico-node

Symptômes : PVC en Pending, volume qui ne se monte pas

Fenêtre de terminal
# Vérifier le driver CSI
kubectl get csidrivers
# Vérifier les événements du PVC
kubectl describe pvc <name>
# Logs du controller CSI
kubectl logs -n kube-system -l app=ebs-csi-controller -c csi-provisioner
Fenêtre de terminal
# === CRI ===
# Vérifier le runtime
kubectl get nodes -o wide
crictl info
crictl ps
# === CNI ===
# Voir le plugin CNI
ls /etc/cni/net.d/
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel'
# Voir les CIDR par nœud
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
# === CSI ===
# Lister les drivers CSI
kubectl get csidrivers
# Vérifier les StorageClasses
kubectl get storageclasses
# Debug un PVC bloqué
kubectl describe pvc <name>
  1. CRI = interface kubelet ↔ container runtime (containerd, CRI-O)
  2. CNI = interface pour configurer le réseau des Pods
  3. CSI = interface pour provisionner du stockage externe
  4. Les plugins in-tree sont dépréciés — utilisez CSI pour le stockage
  5. crictl pour diagnostiquer le runtime
  6. Config CNI dans /etc/cni/net.d/, binaires dans /opt/cni/bin/
  7. StorageClass définit quel driver CSI utiliser

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn