E-NO
Kubernetes 7 min de lecture

Runtimes de conteneurs Kubernetes en production : guide opérationnel avancé

calendar_today Publié : 2026-09-12
update Dernière mise à jour : 2026-09-12
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Runtimes de conteneurs Kubernetes en production : guide opérationnel avancé ».

Introduction

Les runtimes de conteneurs sont les logiciels qui décompactent les images de conteneurs, créent les namespaces et les cgroups, et démarrent les processus à l'intérieur d'un pod. Dans Kubernetes, le kubelet appelle un runtime via la Container Runtime Interface (CRI). Le choix du runtime affecte l'isolation de sécurité, la latence de démarrage, la compatibilité des images et les modes de défaillance opérationnels.

Ce guide va au-delà des bases. Nous couvrons comment vérifier la configuration de votre runtime, optimiser les performances en toute sécurité, diagnostiquer les pannes courantes et choisir entre containerd, CRI-O et gVisor pour des charges de travail spécifiques. Chaque section inclut des commandes prêtes à copier-coller, les sorties attendues et les étapes de récupération.

Avant de modifier quoi que ce soit, exécutez les vérifications en lecture seule ci-dessous et enregistrez l'état actuel. Cela vous donne un point de restauration et rend les défaillances visibles.

Architecture des runtimes et la CRI

Le kubelet communique en gRPC avec un plugin CRI. containerd prend en charge la CRI via un plugin intégré ; CRI-O implémente la CRI nativement. Tous deux gèrent des runtimes conformes à l'OCI comme runc (par défaut) ou Kata Containers.

La CRI définit deux services :

  • RuntimeService : gère les sandboxes de pods et les conteneurs (création, démarrage, arrêt, exécution, etc.)
  • ImageService : tire, liste et supprime les images

Lorsque vous créez un pod, le kubelet appelle d'abord RunPodSandbox. Cela crée le namespace réseau, met en place le conteneur pause et applique les cgroups au niveau du pod. Ensuite, il crée chaque conteneur à l'intérieur de ce sandbox.

Pour voir quel runtime utilise votre nœud :

kubectl get nodes -o wide
# La colonne CONTAINER-RUNTIME indique le runtime de conteneurs et sa version.

Sortie attendue (exemple) :

NAME       STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
node-1     Ready    control-plane   10d   v1.31.0   192.168.1.10    <none>        Ubuntu 22.04.3 LTS   5.15.0-91-generic   containerd://1.7.2

Sur le nœud lui-même, vérifiez le socket CRI :

sudo crictl info

crictl est une CLI pour les runtimes CRI. Elle affiche le nom du runtime, sa version et sa configuration. Si crictl n'est pas installé, installez-le à partir des assets de release Kubernetes ou de votre gestionnaire de paquets.

Inventaire des versions et de l'environnement

Avant de diagnostiquer tout problème de runtime, collectez des versions et configurations précises. Exécutez ces commandes sur un nœud (via SSH ou un pod de débogage) et enregistrez la sortie :

# Version du runtime
sudo crictl version
# Exemple de sortie :
# Version:  0.1.0
# RuntimeName:  containerd
# RuntimeVersion:  1.7.2
# RuntimeApiVersion:  v1

# Noyau et système d'exploitation
uname -a
cat /etc/os-release

# Vérifier si cgroups v2 est activé
stat -fc %T /sys/fs/cgroup
# Si la sortie est "cgroup2fs", vous êtes sur cgroups v2. Si "tmpfs", cgroups v1.

# Lister les conteneurs en cours d'exécution avec leurs runtimes
sudo crictl ps -a

Pour containerd, inspectez le runtime par défaut :

sudo containerd config default | grep -A10 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes'

Cela montre les gestionnaires de runtime. Dans un cluster typique, vous verrez runc comme défaut. Si vous avez installé gVisor, il apparaît comme gestionnaire supplémentaire.

Pourquoi c'est important : De nombreuses défaillances mystérieuses proviennent d'une inadéquation entre le pilote cgroup attendu par le runtime et celui du kubelet. Par exemple, si le kubelet utilise systemd mais que containerd utilise cgroupfs, les pods peuvent être tués de manière incorrecte ou ne pas démarrer. Confirmez les deux paramètres :

# Sur le nœud
sudo cat /var/lib/kubelet/config.yaml | grep cgroupDriver
# Souvent attendu : cgroupDriver: systemd

Réconciliez avec la configuration du runtime. S'ils diffèrent, décidez lequel utiliser (généralement systemd sur les distributions modernes) et mettez à jour les deux, puis redémarrez les services avec précaution.

Question rapide 1 sur 2

D'après le passage, que se passe-t-il si un pod spécifie un runtimeClassName qui n'existe pas ou dont le handler ne peut pas être exécuté par le CRI ?

Le passage indique que si la RuntimeClass nommée n'existe pas ou si le CRI ne peut pas exécuter le handler correspondant, le pod entre dans la phase terminale Failed, et vous devriez rechercher un événement correspondant contenant un message d'erreur.

Diagnostiquer les problèmes de runtime

Commencez par une observation en lecture seule. Utilisez kubectl pour obtenir le statut des pods et les événements :

kubectl get pods -n <namespace>
kubectl describe pod <nom-du-pod> -n <namespace>

Recherchez des événements comme FailedCreatePodSandBox, Failed to start container ou CreateContainerConfigError. Ceux-ci indiquent souvent des problèmes de runtime.

Si un conteneur ne cesse de planter, vérifiez ses journaux :

kubectl logs <nom-du-pod> -n <namespace> --previous

Si le conteneur ne démarre jamais parce que le runtime ne peut pas tirer l'image, vous verrez ImagePullBackOff ou ErrImagePull. Vérifiez le nom de l'image et l'accès au registre.

Pour les problèmes au niveau du nœud, inspectez les états des conteneurs avec crictl :

# Lister les pods (sandboxes) sur ce nœud
sudo crictl pods
# Lister les conteneurs
sudo crictl ps -a
# Inspecter un conteneur arrêté
sudo crictl inspect <id-du-conteneur>

La sortie d'inspection inclut la spécification du runtime OCI, qui révèle les limites de ressources, les montages et les variables d'environnement. Elle inclut également la dernière erreur si le conteneur n'a pas démarré.

Pour tester directement le runtime, essayez d'exécuter un conteneur simple avec crictl :

# Tirer une petite image
sudo crictl pull busybox:latest
# Créer un sandbox
POD_ID=$(sudo crictl runp --runtime runc <(echo '{"metadata":{"name":"test-pod","namespace":"default"}}'))
# Créer et démarrer un conteneur dans ce sandbox
CONTAINER_ID=$(sudo crictl create $POD_ID <(echo '{"metadata":{"name":"test-container"},"image":{"image":"busybox"},"command":["sleep","300"]}') <(echo '{}'))
sudo crictl start $CONTAINER_ID
# Vérifier qu'il est en cours d'exécution
sudo crictl ps
# Nettoyer
sudo crictl stop $CONTAINER_ID
sudo crictl rm $CONTAINER_ID
sudo crictl stopp $POD_ID
sudo crictl rmp $POD_ID

Si cela échoue, le runtime a un problème de configuration ou d'installation.

Modifications de configuration en toute sécurité

Lorsque vous devez modifier les paramètres du runtime, suivez ces principes :

  1. Sauvegardez le fichier de configuration avant de le modifier.
  2. Changez un paramètre à la fois.
  3. Testez sur un seul nœud ou un petit sous-ensemble en utilisant des taints et tolérances.
  4. Documentez le résultat attendu et comment revenir en arrière.

Exemple : Passer du runtime par défaut runc à crun (un runtime OCI plus rapide)

crun est un runtime OCI léger écrit en C, souvent plus rapide que runc pour les charges de travail à haute densité. Pour le tester sur un nœud :

  1. Installez crun :
sudo apt-get install crun   # ou équivalent pour votre OS
  1. Ajoutez un gestionnaire de runtime à containerd. Modifiez /etc/containerd/config.toml :
version = 2
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]
    BinaryName = "/usr/bin/crun"
  1. Redémarrez containerd :
sudo systemctl restart containerd
  1. Vérifiez que crun est disponible :
sudo crictl info | jq .config.containerd.runtimes

Vous devriez voir crun listé.

  1. Créez un pod qui utilise le nouveau runtime en définissant runtimeClassName dans la spécification du pod. D'abord, définissez une RuntimeClass :
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: crun
handler: crun

Appliquez-la, puis dans une spécification de pod :

spec:
  runtimeClassName: crun
  containers:
  - name: demo
    image: busybox
    command: ["sleep", "3600"]

Déployez et vérifiez que le pod fonctionne. Sur le nœud, sudo crictl inspect <id-du-conteneur> devrait indiquer le runtime comme crun.

Utiliser gVisor pour une isolation renforcée

gVisor (runsc) est un noyau en espace utilisateur qui intercepte les appels système, fournissant un sandbox. Pour ajouter gVisor comme runtime alternatif :

  1. Téléchargez et installez runsc :
(
  set -e
  ARCH=$(uname -m)
  URL=https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH}
  wget ${URL}/runsc ${URL}/runsc.sha512
  sha512sum -c runsc.sha512
  rm -f runsc.sha512
  sudo mv runsc /usr/local/bin
  sudo chown root:root /usr/local/bin/runsc
  sudo chmod 0755 /usr/local/bin/runsc
)
  1. Configurez containerd pour l'utiliser :
sudo containerd config default > /etc/containerd/config.toml
# Modifiez le fichier pour ajouter sous [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
  runtime_type = "io.containerd.runsc.v1"
  1. Redémarrez containerd.
  2. Créez une RuntimeClass :
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
  1. Utilisez-la pour les pods nécessitant une isolation.

Note de performance : gVisor ajoute une surcharge car il intercepte chaque appel système. Il n'est pas destiné aux charges de travail à haut débit. Testez avant de généraliser.

Optimisation des performances et observabilité

Les performances du runtime dépendent de la vitesse de tirage des images, du pilote de stockage et de l'allocation CPU/mémoire. Voici des vérifications et optimisations concrètes.

Accélération du tirage d'images

Utilisez crictl pour tirer une image et chronométrez :

time sudo crictl pull nginx:latest

Si les tirages sont lents, envisagez :

  • Mise en miroir de registres : Pour containerd, ajoutez un miroir de registre dans /etc/containerd/certs.d/docker.io/hosts.toml :
server = "https://docker.io"

[host."https://registry-mirror.example.com"]
  capabilities = ["pull", "resolve"]
  • Pré-tirage d'images sur les nouveaux nœuds à l'aide d'un DaemonSet ou d'un script d'initialisation du nœud.
  • Utilisation d'un cache local comme Dragonfly ou Kraken.

Pilote de stockage

Vérifiez le pilote de stockage pour containerd :

sudo ctr version
sudo ctr plugins ls | grep snapshot

Le défaut est overlayfs. C'est généralement le meilleur choix. Évitez devicemapper en production en raison de problèmes de stabilité.

Limites de ressources et surcharge du runtime

Le runtime lui-même consomme du CPU et de la mémoire pour chaque conteneur. Pour les nœuds à haute densité, réduisez la surcharge en utilisant un runtime plus léger comme crun (comme montré précédemment). Assurez-vous également que les drapeaux --system-reserved et --kube-reserved du kubelet réservent des ressources pour les démons système, y compris le runtime.

Exemple de drapeaux kubelet dans /var/lib/kubelet/config.yaml :

systemReserved:
  cpu: 500m
  memory: 1Gi
kubeReserved:
  cpu: 250m
  memory: 512Mi

Ajustez en fonction de la taille de votre nœud et du runtime.

Surveillance des métriques du runtime

containerd expose des métriques Prometheus sur /v1/metrics si activé. Pour activer, modifiez config.toml :

[metrics]
  address = "127.0.0.1:1338"
  grpc_histogram = true

Redémarrez containerd, puis vérifiez :

curl http://127.0.0.1:1338/v1/metrics | grep containerd_runtime

Importez ces métriques dans votre pile de surveillance. Métriques clés : containerd_runtime_metrics_containers (nombre de conteneurs), containerd_runtime_metrics_cpu_usage_nanoseconds, containerd_runtime_metrics_memory_usage_bytes.

Modes de défaillance et récupération

Plantages ou non-réponse du runtime

Si crictl ps se bloque ou renvoie une erreur, le démon du runtime peut être arrêté. Vérifiez :

sudo systemctl status containerd    # ou crio
sudo journalctl -u containerd -n 100

Recherchez des OOM kills, des segfaults ou des problèmes de disque. Redémarrez le démon si nécessaire :

sudo systemctl restart containerd

Après le redémarrage, vérifiez que les pods récupèrent :

kubectl get pods --all-namespaces --field-selector=status.phase!=Running

Certains pods peuvent être en Error ou CrashLoopBackOff. Les supprimer forcera leur recréation.

Nœud non prêt

Si un nœud passe à NotReady, vérifiez le kubelet et le runtime :

kubectl describe node <nœud> | grep -A10 Conditions

La condition ContainerRuntimeIsHealthy doit être True. Si False, investiguez le runtime.

Échecs de tirage d'images

Si les pods ne peuvent pas tirer les images, testez manuellement :

sudo crictl pull <image>

Si cela échoue, vérifiez la connectivité au registre et l'authentification. Pour les registres privés, assurez-vous que le nœud dispose des secrets de tirage d'images corrects. Exemple de spécification de pod :

spec:
  imagePullSecrets:
  - name: my-registry-secret
  containers:
  - name: app
    image: private-registry.example.com/app:v1

Échecs de création de sandbox

Si la création du sandbox de pod échoue, vérifiez les plugins CNI :

ls /opt/cni/bin

Des plugins manquants provoquent FailedCreatePodSandBox. Installez les plugins CNI requis ou réparez la configuration réseau.

Stratégie de retour en arrière

Gardez toujours une sauvegarde des fichiers de configuration du runtime. Pour containerd :

sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak-$(date +%Y%m%d)

Si un changement casse les nœuds, restaurez la sauvegarde et redémarrez le démon. Pour la configuration du kubelet, sauvegardez /var/lib/kubelet/config.yaml.

Documentez les étapes de retour en arrière dans vos runbooks. Testez un retour en arrière sur un seul nœud avant d'appliquer les changements à tout le cluster.

Question rapide 2 sur 2

Quel chemin de socket de runtime de conteneur est indiqué pour containerd sous Linux ?

Le tableau des points de terminaison connus pour les systèmes d'exploitation pris en charge indique containerd sous Linux comme unix:///var/run/containerd/containerd.sock.

Durcissement de la sécurité

Sandboxing du runtime

Pour les charges de travail non fiables, utilisez gVisor ou Kata Containers. gVisor est plus facile à intégrer ; Kata fournit une isolation par virtualisation matérielle mais nécessite plus de configuration. Choisissez en fonction de votre modèle de menace et de vos besoins en performances.

Restriction des privilèges du runtime

Même avec runc, vous pouvez durcir les conteneurs :

  • Définissez allowPrivilegeEscalation: false dans les contextes de sécurité des pods.
  • Utilisez des profils seccomp. Le profil par défaut bloque de nombreux appels système dangereux. Pour un seccomp au niveau du runtime, configurez dans le gestionnaire de runtime :
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  NoNewPrivileges = true
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SeccompProfile = "/chemin/vers/seccomp.json"
  • Réduisez les capacités :
securityContext:
  capabilities:
    drop: ["ALL"]
    add: ["NET_BIND_SERVICE"]

Maintenir les runtimes à jour

Les vulnérabilités des runtimes sont fréquentes. Suivez les CVE pour containerd, CRI-O et runc. Automatisez les mises à jour via votre gestionnaire de paquets et testez en staging. Exemple pour Ubuntu :

sudo apt-get update && sudo apt-get upgrade containerd.io

Redémarrez le démon après la mise à niveau et vérifiez la santé du cluster.

Pièges courants

  1. Configurer incorrectement le pilote cgroup
  • Pourquoi cela arrive : Les distributions Linux utilisent par défaut les cgroups systemd, mais certains guides utilisent encore cgroupfs. Cette inadéquation fait que le kubelet et le runtime se disputent la gestion des cgroups.
  • Comment éviter : Définissez toujours le pilote cgroup sur systemd dans les configurations du kubelet et du runtime, sauf raison spécifique d'utiliser cgroupfs.
  • Récupération : Mettez à jour les deux configurations, redémarrez les services et testez avec un pod simple.
  1. Ignorer les journaux du runtime au démarrage
  • Pourquoi : Les développeurs se concentrent sur les événements des pods, mais la cause première peut être dans les journaux du runtime.
  • Éviter : Prenez l'habitude de vérifier journalctl -u containerd (ou CRI-O) lors de l'investigation des échecs de démarrage.
  • Récupération : Corrélez les horodatages entre les événements des pods et les journaux du runtime.
  1. Utiliser des tags d'image latest avec des fonctionnalités dépendantes du runtime
  • Pourquoi : Certaines fonctionnalités nécessitent des versions spécifiques du runtime ; utiliser latest peut casser si le runtime ne les prend pas en charge.
  • Éviter : Épinglez les versions d'image et testez la compatibilité du runtime en CI.
  • Récupération : Revenez au tag d'image précédent ou mettez à niveau le runtime.
  1. Surcharger les nœuds sans tenir compte de la surcharge du runtime
  • Pourquoi : runc ajoute une certaine surcharge par conteneur. Trop de conteneurs peuvent épuiser les ressources du nœud.
  • Éviter : Surveillez les métriques du runtime et définissez des limites de densité de pods appropriées par type de nœud.
  • Récupération : Évacuez les pods vers d'autres nœuds ou réduisez le nombre de conteneurs.
  1. Ne pas utiliser correctement RuntimeClass
  • Pourquoi : Des gestionnaires mal configurés font échouer les pods avec FailedCreatePodSandBox.
  • Éviter : Testez RuntimeClass sur un pod canari avant de l'assigner aux charges de travail.
  • Récupération : Supprimez le champ runtimeClassName pour revenir au runtime par défaut.

Checklist des opérations

Voici une checklist concise pour les opérations de runtime. Pour chaque élément, assignez un responsable unique dans votre équipe. Révisez cette checklist mensuellement ou après tout incident.

Vérifications quotidiennes/hebdomadaires (Responsable : Ingénieur Plateforme)

  • [ ] Vérifier les conditions des nœuds : kubectl get nodes -o custom-columns='NAME:.metadata.name,READY:.status.conditions[?(@.type=="Ready")].status,RUNTIME:.status.nodeInfo.containerRuntimeVersion'
  • [ ] Examiner les métriques du runtime : CPU, mémoire, nombre de conteneurs, latence de tirage d'images.
  • [ ] Examiner les journaux pour les erreurs : sudo journalctl -u containerd --since "24 hours ago" | grep -i error (exécuter sur les nœuds via l'automatisation).
  • [ ] Vérifier que la sauvegarde des configurations du runtime est à jour.

Avant tout changement (Responsable : Lead SRE)

  • [ ] Capturer la référence : version du runtime, nombre de nœuds, taux de succès des pods.
  • [ ] Tester le changement sur un nœud (en utilisant taint/tolérance pour isoler).
  • [ ] Documenter la procédure de retour en arrière et les commandes exactes.
  • [ ] Annoncer le changement et l'impact attendu dans le canal de communication.
  • [ ] Configurer des alertes de surveillance pour les métriques affectées.

Après tout changement (Responsable : Lead SRE)

  • [ ] Vérifier que le nœud est Ready et que tous les pods sont Running.
  • [ ] Exécuter des tests de fumée : créer un pod utilisant runtimeClassName si changé.
  • [ ] Attendre la période d'observation (par exemple, 30 minutes) et comparer les taux d'erreur.
  • [ ] Si des problèmes surviennent, exécuter le retour en arrière immédiatement et capturer les journaux pour le post-mortem.

Trimestriel (Responsable : Ingénieur Sécurité)

  • [ ] Examiner les CVE des runtimes et appliquer les correctifs.
  • [ ] Réévaluer les besoins de sandboxing et ajuster les RuntimeClasses.
  • [ ] Auditer les configurations des runtimes par rapport aux benchmarks CIS ou aux normes internes.
  • [ ] Tester la reprise après sinistre : simuler une panne du démon du runtime et restaurer.

Conclusion

La gestion avancée des runtimes de conteneurs dans Kubernetes exige une approche disciplinée. Vous devez comprendre la CRI, vérifier systématiquement les configurations, tester les changements en isolation et disposer de plans de retour en arrière robustes. Les commandes et checklists de ce guide fournissent une base.

Commencez par auditer votre configuration actuelle du runtime avec les commandes d'inventaire. Ensuite, choisissez une amélioration : passer à un runtime plus rapide comme crun, ajouter gVisor pour les charges de travail sensibles, ou renforcer la surveillance. Documentez le changement, assignez un responsable et suivez les résultats sur un mois.

Rappelez-vous, le runtime est la fondation de chaque pod. Quand il fonctionne, personne ne le remarque. Quand il échoue, tout s'arrête. Traitez-le comme une infrastructure critique : observez, planifiez, changez et vérifiez.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO