crictl est l'outil CLI officiel pour interagir avec les runtimes de conteneurs compatibles CRI (Container Runtime Interface) comme containerd ou CRI-O. Si vous administrez un cluster Kubernetes et devez déboguer des conteneurs au niveau du runtime (lister les pods, inspecter les logs, exécuter des commandes), crictl est l'outil qu'il vous faut. Version actuelle : v1.35.0 (décembre 2025).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer et configurer crictl pour containerd ou CRI-O
- Lister et inspecter les conteneurs et pods
- Déboguer les problèmes Kubernetes au niveau du runtime
- Utiliser les fonctionnalités avancées (exec parallèle, filtrage par namespace, TLS)
Comprendre le contexte : CRI et les runtimes
Section intitulée « Comprendre le contexte : CRI et les runtimes »En 2016, Kubernetes a introduit la CRI (Container Runtime Interface) pour découpler le runtime de conteneurs du reste de la plateforme. Avant cela, Docker était le seul runtime supporté.
L'objectif : permettre à plusieurs runtimes (containerd, CRI-O, etc.) de fonctionner avec Kubernetes via une API gRPC standardisée.
Qu'est-ce qu'un runtime CRI ?
Section intitulée « Qu'est-ce qu'un runtime CRI ? »Un runtime CRI est un composant qui :
- Reçoit des ordres de Kubernetes via l'API gRPC CRI
- Crée et gère les conteneurs et leurs sandboxes (pods)
- Rapporte l'état des conteneurs au kubelet
| Runtime | Maintenu par | Usage principal |
|---|---|---|
| containerd | CNCF | Défaut sur la plupart des distributions K8s |
| CRI-O | Red Hat | Optimisé pour OpenShift |
| cri-dockerd | Mirantis | Pont vers Docker Engine |
Installation de crictl
Section intitulée « Installation de crictl »crictl est distribué dans le projet cri-tools qui suit les versions mineures de Kubernetes. Utilisez la même version mineure que votre cluster (ex: crictl 1.35 pour Kubernetes 1.35).
# Définir la versionVERSION="v1.35.0"ARCH="amd64" # ou arm64
# Télécharger et installercurl -sL "https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-${ARCH}.tar.gz" \ | sudo tar -xzf - -C /usr/local/bin
# Vérifier l'installationcrictl --version# crictl version v1.35.0# Installer les prérequissudo apt-get update && sudo apt-get install -y apt-transport-https
# Ajouter le dépôt Kubernetescurl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | \ sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \ https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /" | \ sudo tee /etc/apt/sources.list.d/kubernetes.list
# Installer crictl via cri-toolssudo apt-get update && sudo apt-get install -y cri-tools
crictl --versionPour maîtriser apt, consultez le guide apt.
# TéléchargerVERSION="v1.35.0"wget "https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-amd64.tar.gz"
# Vérifier le checksum (optionnel mais recommandé)wget "https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-amd64.tar.gz.sha256"sha256sum -c crictl-${VERSION}-linux-amd64.tar.gz.sha256
# Extraire et installertar -xzf crictl-${VERSION}-linux-amd64.tar.gzsudo mv crictl /usr/local/bin/Configuration de crictl
Section intitulée « Configuration de crictl »crictl doit connaître le socket de votre runtime CRI. La configuration se fait
dans /etc/crictl.yaml.
-
Identifiez votre runtime
Fenêtre de terminal # containerdls -la /run/containerd/containerd.sock# CRI-Ols -la /run/crio/crio.sock -
Créez le fichier de configuration
Fenêtre de terminal sudo tee /etc/crictl.yaml << EOFruntime-endpoint: unix:///run/containerd/containerd.sockimage-endpoint: unix:///run/containerd/containerd.socktimeout: 10debug: falseEOF -
Testez la connexion
Fenêtre de terminal crictl infoSi la commande retourne les informations du runtime, la configuration est correcte.
Activer CRI dans containerd (si nécessaire)
Section intitulée « Activer CRI dans containerd (si nécessaire) »Si vous utilisez containerd en dehors de Kubernetes, le plugin CRI peut être désactivé par défaut.
-
Générez la configuration par défaut
Fenêtre de terminal sudo containerd config default | sudo tee /etc/containerd/config.toml -
Vérifiez que CRI est activé
Ouvrez
/etc/containerd/config.tomlet assurez-vous que cette ligne est commentée ou absente :# disabled_plugins = ["cri"] -
Redémarrez containerd
Fenêtre de terminal sudo systemctl restart containerdcrictl info
Utiliser crictl sans sudo
Section intitulée « Utiliser crictl sans sudo »Par défaut, le socket containerd appartient à root:root, ce qui oblige à
utiliser sudo. Pour permettre l'accès sans privilèges root, créez un groupe
dédié et configurez le socket.
-
Créez le groupe containerd et ajoutez votre utilisateur
Fenêtre de terminal sudo groupadd containerdsudo usermod -aG containerd $USER -
Changez le groupe du socket
Fenêtre de terminal sudo chgrp containerd /run/containerd/containerd.sock -
Rendez le changement permanent
Créez un override systemd pour appliquer le changement à chaque démarrage :
Fenêtre de terminal sudo mkdir -p /etc/systemd/system/containerd.service.dsudo tee /etc/systemd/system/containerd.service.d/socket-group.conf << 'EOF'[Service]ExecStartPost=/bin/chgrp containerd /run/containerd/containerd.sockEOFsudo systemctl daemon-reload -
Appliquez les changements de groupe
Déconnectez-vous et reconnectez-vous, ou utilisez :
Fenêtre de terminal newgrp containerd -
Vérifiez l'accès sans sudo
Fenêtre de terminal crictl info -o json | jq '{runtime: .config.containerd.defaultRuntimeName}'Sortie {"runtime": "runc"}
Gestion des images
Section intitulée « Gestion des images »crictl permet de gérer les images stockées par le runtime, c'est-à-dire celles réellement présentes sur le nœud. C'est une distinction importante : kubectl vous dit quelle image un Pod demande, crictl vous dit laquelle est téléchargée. Quand un Pod reste en ImagePullBackOff, ces commandes permettent de confirmer si l'image est absente ou si le problème vient d'ailleurs.
Lister les images
Section intitulée « Lister les images »La sortie donne le nom complet de l'image (registre inclus), son tag, l'identifiant court et la taille sur disque.
crictl imagesIMAGE TAG IMAGE ID SIZEdocker.io/library/busybox 1.36 114f4abb67995 2.22MBdocker.io/library/nginx 1.27 1e5f3c5b981a9 72.4MBregistry.k8s.io/pause 3.10.1 cd073f4c5f6a8 320kBTélécharger et inspecter une image
Section intitulée « Télécharger et inspecter une image »crictl pull force le téléchargement sans attendre qu'un Pod le déclenche, ce qui est pratique pour préchauffer un nœud ou vérifier que le registre est joignable. crictl inspecti renvoie les métadonnées de l'image, dont son digest sha256, le seul identifiant qui garantit que deux nœuds exécutent bien le même contenu.
# Télécharger une imagecrictl pull nginx:1.27
# Inspecter les métadonnées d'une imagecrictl inspecti docker.io/library/busybox:1.36 | jq '{ digest: .status.id[0:50], size: .status.size, tags: .status.repoTags}'{ "digest": "sha256:114f4abb67995cfe8e368760f3bc8a1d00e12ac98", "size": "2217150", "tags": ["docker.io/library/busybox:1.36"]}Supprimer une image
Section intitulée « Supprimer une image »La suppression échoue tant qu'un conteneur, même arrêté, référence encore l'image. Pour faire de la place sur un nœud sous DiskPressure, crictl rmi --prune retire d'un coup toutes les images qu'aucun conteneur n'utilise.
crictl rmi alpine:3.19# Deleted: docker.io/library/alpine:3.19Gestion des conteneurs avec crictl
Section intitulée « Gestion des conteneurs avec crictl »Au niveau du runtime, un conteneur est une unité indépendante du Pod qui le contient : crictl voit les conteneurs applicatifs, mais aussi ceux qu'un Pod a redémarrés et qui restent en état Exited. C'est précisément cet historique que kubectl masque et qui permet de comprendre pourquoi un Pod boucle en CrashLoopBackOff.
Lister les conteneurs
Section intitulée « Lister les conteneurs »crictl ps n'affiche par défaut que les conteneurs en cours d'exécution. La colonne ATTEMPT compte les redémarrages, et POD ID rattache chaque conteneur à sa sandbox.
# Conteneurs en cours d'exécutioncrictl psCONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID209fb8b19830c docker.io/library/busybox:1.36 2 minutes ago Running test-container 0 027378143d3ff# Tous les conteneurs (y compris arrêtés)crictl ps -a
# Filtrer par étatcrictl ps --state running
# Filtrer par nomcrictl ps --name test
# Filtrer par namespace Kubernetes (v1.32+)crictl ps --namespace kube-system
# Filtrer par podcrictl ps --pod <POD_ID>
# Sortie JSONcrictl ps -o jsonInspecter un conteneur
Section intitulée « Inspecter un conteneur »crictl inspect renvoie l'état complet du conteneur en JSON : montages, variables d'environnement, code de sortie du dernier arrêt et PID du processus principal sur le nœud. Ce PID est la porte d'entrée vers les outils système classiques (ps, nsenter, /proc) quand le conteneur n'embarque aucun shell.
crictl inspect 209fb8b19830c | jq '{ id: .status.id[0:12], state: .status.state, pid: .info.pid, image: .status.image.image}'{ "id": "209fb8b19830", "state": "CONTAINER_RUNNING", "pid": 136906, "image": "docker.io/library/busybox:1.36"}Gérer les conteneurs
Section intitulée « Gérer les conteneurs »Ces trois commandes agissent sous Kubernetes, sans passer par l'API. Sur un nœud d'un cluster actif, le kubelet reconstruira le conteneur que vous venez de supprimer, puisque son état désiré n'a pas changé : ces opérations servent au diagnostic, jamais à piloter une application.
# Démarrer un conteneurcrictl start <CONTAINER_ID>
# Arrêter un conteneurcrictl stop <CONTAINER_ID>
# Supprimer un conteneurcrictl rm <CONTAINER_ID>Debugging et inspection
Section intitulée « Debugging et inspection »Quand le kubelet ne répond plus ou que l'API Server est injoignable, kubectl logs et kubectl exec cessent de fonctionner : ces deux commandes passent par le control plane. crictl parle directement au runtime local et reste donc utilisable, ce qui en fait le dernier recours pour lire une trace d'erreur sur un nœud isolé.
Logs des conteneurs
Section intitulée « Logs des conteneurs »crictl lit les fichiers de log écrits par le runtime sur le nœud, sans transiter par l'API. Conséquence pratique : les logs d'un conteneur supprimé ne sont plus accessibles, contrairement à ceux d'un conteneur simplement arrêté.
# Voir les logscrictl logs <CONTAINER_ID>Hello from crictl test containerHello from crictl test containerHello from crictl test container# Dernières N lignescrictl logs --tail 2 <CONTAINER_ID>
# Suivre en temps réelcrictl logs -f <CONTAINER_ID>
# Filtrer par flux (v1.33+)crictl logs --stream stdout <CONTAINER_ID>crictl logs --stream stderr <CONTAINER_ID>
# Logs avec timestampscrictl logs -t <CONTAINER_ID>Exécuter des commandes
Section intitulée « Exécuter des commandes »crictl exec lance un processus à l'intérieur du conteneur : la commande doit donc exister dans son image. Sur une image minimale sans /bin/sh, un shell interactif échouera, et il faudra passer par le PID du conteneur depuis le nœud.
# Commande simplecrictl exec <CONTAINER_ID> uname -aLinux master1 6.8.0-90-generic #91-Ubuntu SMP ... x86_64 GNU/Linux# Shell interactifcrictl exec -it <CONTAINER_ID> /bin/sh
# Exécution parallèle sur plusieurs conteneurs (v1.32+)crictl exec --image nginx -x -- cat /etc/nginx/nginx.conf
# Avec support TLS (v1.32+)crictl exec --tls-ca /path/to/ca.crt \ --tls-cert /path/to/client.crt \ --tls-key /path/to/client.key \ -it <CONTAINER_ID> /bin/shStatistiques des conteneurs
Section intitulée « Statistiques des conteneurs »crictl stats affiche la consommation instantanée relevée par le runtime : CPU, mémoire, disque, inodes et swap. Contrairement à kubectl top, ces chiffres ne dépendent pas du metrics-server, ce qui les rend exploitables sur un cluster où la remontée de métriques est justement en panne.
# Stats d'un conteneur spécifiquecrictl stats <CONTAINER_ID>CONTAINER NAME CPU % MEM DISK INODES SWAP209fb8b19830c test-container 0.01 327.7kB 16.38kB 7 0B# Stats de tous les conteneurscrictl statsGestion des pods avec crictl
Section intitulée « Gestion des pods avec crictl »Dans Kubernetes, un pod est un groupe de conteneurs partageant réseau et stockage. crictl permet de gérer les pods directement au niveau du runtime.
Lister et inspecter les pods
Section intitulée « Lister et inspecter les pods »Ce que crictl appelle un pod est en réalité la sandbox : l'environnement réseau et d'isolation partagé, matérialisé par le conteneur pause. Son état SANDBOX_READY et l'adresse IP retournée par inspectp indiquent si le plugin réseau a bien fait son travail, avant même de regarder les conteneurs applicatifs.
# Lister tous les podscrictl podsPOD ID CREATED STATE NAME NAMESPACE ATTEMPT RUNTIME027378143d3ff 5 minutes ago Ready test-pod default 0# Filtrer par namespacecrictl pods --namespace kube-system
# Inspecter un podcrictl inspectp <POD_ID> | jq '{ id: .status.id[0:12], state: .status.state, ip: .status.network.ip}'{ "id": "027378143d3f", "state": "SANDBOX_READY", "ip": "10.88.0.2"}# Stats des pods (v1.28+)crictl statspCréer un pod (test/debug)
Section intitulée « Créer un pod (test/debug) »Pour créer un pod manuellement (utile pour les tests), vous avez besoin d'un fichier de configuration JSON :
{ "metadata": { "name": "test-pod", "namespace": "default", "uid": "test-pod-uid-001" }, "log_directory": "/tmp/crictl-logs", "linux": {}}# Créer le podcrictl runp pod-config.json# 027378143d3ff23e276aeffbd06002ac40a7c03c280ceb9ce94f971d4c7f90c5
# Lister pour vérifiercrictl podsCréer un conteneur dans un pod
Section intitulée « Créer un conteneur dans un pod »Une fois le pod créé, vous pouvez y ajouter un conteneur :
{ "metadata": { "name": "test-container" }, "image": { "image": "docker.io/library/busybox:1.36" }, "command": ["sh", "-c", "while true; do echo 'Hello'; sleep 5; done"], "log_path": "test-container.log", "linux": {}}# Créer le conteneur (sans le démarrer)POD_ID=$(crictl pods -q)crictl create $POD_ID container-config.json pod-config.json# 209fb8b19830c2e569d778285035b55db673fd88816d066a9b0cd1b83db076e3
# Démarrer le conteneurcrictl start 209fb8b19830cSupprimer un pod
Section intitulée « Supprimer un pod »La suppression se fait en deux temps : stopp arrête la sandbox et les conteneurs qu'elle contient, rmp la retire du runtime. L'ordre n'est pas optionnel, un pod encore actif ne peut pas être supprimé.
# Arrêter le pod (arrête les conteneurs)crictl stopp <POD_ID># Stopped sandbox 027378143d3ff
# Supprimer le podcrictl rmp <POD_ID># Removed sandbox 027378143d3ffFonctionnalités avancées
Section intitulée « Fonctionnalités avancées »Les versions récentes de crictl ont introduit des fonctionnalités puissantes pour le débogage et la gestion à grande échelle. Voici les plus utiles, avec leurs dates de sortie et cas d'usage concrets.
Informations du runtime
Section intitulée « Informations du runtime »Ces commandes répondent à la première question de tout diagnostic : quel runtime tourne réellement sur ce nœud, dans quelle version, et avec quel cgroup driver. Une incohérence de cgroup driver entre le kubelet et containerd (systemd d'un côté, cgroupfs de l'autre) provoque des Pods qui refusent de démarrer sans message explicite.
# Informations de versioncrictl versionVersion: v1.35.0RuntimeName: containerdRuntimeVersion: v2.2.1RuntimeApiVersion: v1# Configuration du runtimecrictl runtime-config# cgroup driver: CGROUPFS
# Informations détailléescrictl info -o json | jq '{ runtimeSpec: .config.containerd.defaultRuntimeName, cgroupDriver: .config.containerd.runtimes.runc.options.SystemdCgroup}'Informations sur le stockage
Section intitulée « Informations sur le stockage »crictl imagefsinfo indique où le runtime stocke ses images et combien d'espace et d'inodes elles consomment. C'est la vérification à faire quand un nœud passe en DiskPressure : le point de montage retourné est celui que le kubelet surveille, souvent différent de la racine du système.
crictl imagefsinfo{ "status": { "imageFilesystems": [{ "fsId": { "mountpoint": "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs" }, "inodesUsed": { "value": "5908" }, "usedBytes": { "value": "212267008" } }] }}Événements en temps réel
Section intitulée « Événements en temps réel »La commande events affiche les événements du runtime en temps réel. Utile
pour surveiller ce qui se passe sur le nœud :
crictl events{ "containerId": "209fb8b19830c...", "containerEventType": "CONTAINER_STARTED_EVENT", "podSandboxStatus": { "id": "027378143d3ff...", "state": "SANDBOX_READY", "network": { "ip": "10.88.0.2" } }}Exécution parallèle
Section intitulée « Exécution parallèle »L'exécution parallèle permet de lancer une commande dans plusieurs conteneurs simultanément, filtré par image, pod, nom ou état. C'est indispensable pour :
- Audit rapide : vérifier une config sur tous les conteneurs d'un type
- Diagnostic de masse : collecter des infos système (date, env, mémoire)
- Nettoyage : exécuter un script de maintenance sur tous les conteneurs
Créer un environnement de test
Section intitulée « Créer un environnement de test »Pour tester l'exécution parallèle, créez plusieurs conteneurs busybox :
# Créer le fichier de configuration du pod (UID unique requis)cat > /tmp/test-pod.json << EOF{ "metadata": { "name": "test-parallel", "namespace": "default", "uid": "test-parallel-$(date +%s)" }, "log_directory": "/tmp/crictl-logs", "linux": {}}EOF
# Créer le podcrictl runp /tmp/test-pod.json
# Récupérer l'ID du podPOD_ID=$(crictl pods -q)echo "Pod créé: $POD_ID"
# Créer et démarrer 3 conteneurs avec des noms uniquesfor i in 1 2 3; do cat > /tmp/test-container-$i.json << EOF{ "metadata": { "name": "worker-$i" }, "image": { "image": "docker.io/library/busybox:1.36" }, "command": ["sh", "-c", "while true; do sleep 3600; done"], "log_path": "worker-$i.log", "linux": {}}EOF CID=$(crictl create $POD_ID /tmp/test-container-$i.json /tmp/test-pod.json) crictl start $CIDdone
# Vérifiercrictl psCONTAINER IMAGE STATE NAME POD ID720505c9523ac docker.io/library/busybox:1.36 Running worker-3 9418c9638da3982e328bd61005 docker.io/library/busybox:1.36 Running worker-2 9418c9638da390f83e10e7e4b3 docker.io/library/busybox:1.36 Running worker-1 9418c9638da39Exemples d'exécution parallèle
Section intitulée « Exemples d'exécution parallèle »Chaque filtre (--image, --state, --pod) désigne l'ensemble de conteneurs visés, et -x déclenche l'exécution simultanée. Les commandes partant en parallèle, l'ordre des lignes de sortie n'est pas garanti : laissez les identifiants affichés pour savoir quel conteneur a produit quelle ligne, et n'ajoutez -q que si vous cherchez uniquement la valeur.
# Voir le hostname de tous les conteneurs busybox (nom complet requis)crictl exec --image "docker.io/library/busybox:1.36" --parallel -- hostnamemaster1master1master1# Voir les variables d'environnement de tous les conteneurs actifscrictl exec --state running -x -- env | grep "^PATH"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# Lister les processus de tous les conteneurs d'un pod spécifiquecrictl exec --pod $POD_ID -x -- ps aux
# Ignorer les erreurs et continuer sur tous les conteneurscrictl exec --state running -x -e -- cat /etc/os-releaseNettoyer l'environnement de test
Section intitulée « Nettoyer l'environnement de test »Ces conteneurs de test ne sont pilotés par aucun contrôleur Kubernetes : personne ne les supprimera à votre place, et ils continueront d'apparaître dans tous vos crictl ps ultérieurs. La boucle ci-dessous les arrête et les retire, avant de supprimer la sandbox.
# Arrêter et supprimer tous les conteneurs du podfor CID in $(crictl ps -q); do crictl stop $CID crictl rm $CIDdone
# Supprimer le podcrictl stopp $POD_IDcrictl rmp $POD_ID| Option | Description | Exemple |
|---|---|---|
--image | Filtre par nom d'image (conteneurs actifs uniquement) | --image busybox |
--pod | Filtre par ID de pod | --pod abc123def |
--state | Filtre par état | --state running |
--name | Filtre par nom de conteneur | --name worker |
-x, --parallel | Active l'exécution parallèle | -x |
-q, --quiet | Masque les IDs conteneurs dans la sortie | -q |
-e, --ignore-error | Continue même si une commande échoue | -e |
Support TLS pour le streaming
Section intitulée « Support TLS pour le streaming »Les commandes exec, attach et portforward supportent maintenant le
chiffrement TLS. C'est essentiel pour :
- Conformité sécurité : exigences PCI-DSS, HIPAA, SOC2
- Débogage distant : accès sécurisé aux conteneurs via réseau externe
- Zero-trust : ne jamais faire confiance au réseau interne
# Exécution avec authentification TLS mutuellecrictl exec \ --tls-ca /etc/kubernetes/pki/ca.crt \ --tls-cert /etc/kubernetes/pki/admin.crt \ --tls-key /etc/kubernetes/pki/admin.key \ --tls-server-name containerd.local \ -it abc123 /bin/sh| Option | Description |
|---|---|
--tls-ca | Certificat CA pour valider le serveur |
--tls-cert | Certificat client |
--tls-key | Clé privée du certificat client |
--tls-server-name | Nom du serveur pour la validation SNI |
Filtrage des logs par flux
Section intitulée « Filtrage des logs par flux »L'option --stream permet de récupérer uniquement stdout ou stderr,
facilitant le tri des logs :
# Voir uniquement les erreurs (stderr)crictl logs --stream stderr abc123
# Voir uniquement les logs normaux (stdout)crictl logs --stream stdout abc123
# Combiner avec tail pour les dernières erreurscrictl logs --stream stderr --tail 50 abc123Cas d'usage typique : un conteneur produit beaucoup de logs INFO sur stdout.
Vous cherchez une erreur spécifique. Avec --stream stderr, vous isolez
instantanément les messages d'erreur.
Découverte des fonctionnalités du runtime
Section intitulée « Découverte des fonctionnalités du runtime »L'API CRI permet d'interroger les capacités du runtime installé. C'est utile pour :
- Vérifier la compatibilité : le runtime supporte-t-il les user namespaces ?
- Diagnostic : pourquoi une fonctionnalité ne marche pas ?
- Automatisation : scripts qui s'adaptent aux capacités disponibles
# Voir toutes les fonctionnalités du runtimecrictl info -o json | jq '.features'{ "supplementalGroupsPolicy": true, "recursiveReadOnlyMounts": true, "userNamespaces": true}| Fonctionnalité | Description |
|---|---|
supplementalGroupsPolicy | Gestion avancée des groupes Linux |
recursiveReadOnlyMounts | Montages récursifs en lecture seule |
userNamespaces | Isolation des user namespaces (rootless) |
Descripteurs de métriques
Section intitulée « Descripteurs de métriques »La commande metricdescs (introduite en v1.33, stabilisée en v1.34) liste
les métriques disponibles via l'API ListMetricDescriptors :
crictl metricdescs | head -20{ "descriptors": [ { "name": "container_fs_reads_bytes_total", "help": "Cumulative count of bytes read", "labelKeys": ["id", "name", "device"] }, { "name": "container_fs_reads_total", "help": "Cumulative count of reads completed", "labelKeys": ["id", "name", "device"] } ]}Cas d'usage : avant de configurer votre monitoring (Prometheus, Datadog), vérifiez quelles métriques le runtime expose nativement.
Ajustement du score OOM
Section intitulée « Ajustement du score OOM »La commande crictl update --oom-score-adj permet de modifier la priorité
OOM d'un conteneur en cours d'exécution, sans redémarrage :
# Protéger un conteneur critique (base de données)# Score -500 = moins susceptible d'être tuécrictl update --oom-score-adj -500 abc123
# Rendre un conteneur moins prioritaire (tâche batch)# Score +500 = plus susceptible d'être tué en cas de pénurie mémoirecrictl update --oom-score-adj 500 def456
# Vérifier le score actuelcrictl inspect abc123 | jq '.status.resources.oomScoreAdj'Cas d'usage : votre cluster a une pression mémoire temporaire. Vous voulez
protéger la base de données mais accepter que les workers de tâches batch
soient tués en premier. Avec --oom-score-adj, vous ajustez les priorités
sans redéployer.
| Valeur | Comportement |
|---|---|
-1000 | Jamais tué par l'OOM killer (réservé au système) |
-500 | Fortement protégé |
0 | Comportement par défaut |
+500 | Prioritaire pour être tué |
+1000 | Tué en premier |
Intégration avec Kubernetes
Section intitulée « Intégration avec Kubernetes »crictl et kubectl ne s'opposent pas, ils regardent le cluster depuis deux points différents. kubectl interroge l'API Server et décrit l'état désiré ; crictl interroge le runtime local et décrit ce qui tourne vraiment sur un nœud. Tant que tout va bien, la seconde vue n'apporte rien ; dès que le kubelet ou l'API Server défaille, elle devient la seule disponible.
Pourquoi utiliser crictl avec Kubernetes ?
Section intitulée « Pourquoi utiliser crictl avec Kubernetes ? »Le partage des rôles est net : gérer des charges de travail relève de kubectl, inspecter un nœud en panne relève de crictl. Se tromper de couche est un piège classique, supprimer un conteneur avec crictl sur un cluster sain ne fait que déclencher sa recréation par le kubelet.
| Cas d'usage | kubectl | crictl |
|---|---|---|
| Gestion normale des workloads | ✅ | ❌ |
| Débogage kubelet défaillant | ❌ | ✅ |
| Inspection bas niveau | ❌ | ✅ |
| Pods bloqués en Terminating | ❌ | ✅ |
Workflow de débogage typique
Section intitulée « Workflow de débogage typique »Le principe est de partir du plus global et de descendre d'un cran à chaque étape, jusqu'à obtenir un message d'erreur exploitable. On ne se connecte au nœud qu'une fois le Pod fautif identifié, sans quoi on inspecte au hasard.
-
Identifiez le problème avec kubectl
Fenêtre de terminal kubectl get pods -A | grep -v Running -
Connectez-vous au nœud concerné
Fenêtre de terminal ssh worker-node-1 -
Listez les pods avec crictl
Fenêtre de terminal crictl pods -
Inspectez le pod problématique
Fenêtre de terminal crictl inspectp <POD_ID> -
Vérifiez les logs des conteneurs
Fenêtre de terminal crictl logs <CONTAINER_ID>
Dépannage
Section intitulée « Dépannage »Les erreurs rencontrées avec crictl viennent presque toujours de la connexion au socket, rarement de la commande elle-même. Avant de suspecter le cluster, vérifiez donc que crictl parle bien au bon runtime et avec les droits nécessaires.
| Problème | Cause probable | Solution |
|---|---|---|
FATA: Cannot connect to runtime | Socket introuvable | Vérifiez /etc/crictl.yaml |
error: no running containers | Aucun conteneur actif | Utilisez crictl ps -a |
permission denied | Droits insuffisants | Exécutez avec sudo |
CRI plugin is disabled | containerd mal configuré | Activez CRI dans config.toml |
À retenir
Section intitulée « À retenir »- crictl est l'outil de débogage bas niveau pour les runtimes CRI
- Configurez le socket dans
/etc/crictl.yaml - Utilisez la même version mineure que Kubernetes
crictl ps→ conteneurs,crictl pods→ pods- Fonctionnalités avancées : exécution parallèle (
-x), filtrage namespace, TLS - Filtrage des logs par flux (stdout/stderr), ajustement OOM score
Prochaines étapes
Section intitulée « Prochaines étapes »Questions fréquentes
Section intitulée « Questions fréquentes »crictl vs docker CLI
| Aspect | crictl | docker CLI |
|---|---|---|
| Communication | API CRI (gRPC) | Docker Engine API |
| Runtimes | containerd, CRI-O | Docker uniquement |
| Cas d'usage | Debug Kubernetes | Dev local |
| Gestion build | Non | Oui |
| Gestion réseau | Non | Oui |
Configuration du socket
Créez/etc/crictl.yaml :runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
Sockets par runtime :| Runtime | Socket |
|---|---|
| containerd | unix:///run/containerd/containerd.sock |
| CRI-O | unix:///run/crio/crio.sock |
| cri-dockerd | unix:///var/run/cri-dockerd.sock |
crictl info
Filtrage par namespace
# Conteneurs du namespace kube-system
crictl ps --namespace kube-system
# Tous les conteneurs (y compris arrêtés)
crictl ps -a --namespace default
# Filtrage par regex
crictl ps --namespace 'kube-.*'
Options utiles :| Option | Description |
|---|---|
--namespace |
Filtre par namespace (regex) |
-a |
Inclut les conteneurs arrêtés |
-o json |
Sortie JSON |
--pod |
Filtre par pod ID |
Exécution parallèle (v1.32+)
# Exécuter dans tous les conteneurs nginx
crictl exec --image nginx -x -- cat /etc/nginx/nginx.conf
# Exécuter dans tous les conteneurs d'un pod
crictl exec --pod abc123 -x -- env
# Exécuter sans afficher les IDs
crictl exec --image busybox -x -q -- date
Options de filtrage :| Option | Description |
|---|---|
--image |
Filtre par image |
--pod |
Filtre par pod ID |
--state |
Filtre par état |
-x, --parallel |
Exécution parallèle |
-q, --quiet |
Masque les IDs |
Filtrage des flux de logs (v1.33+)
# Logs stdout uniquement
crictl logs --stream stdout CONTAINER_ID
# Logs stderr uniquement
crictl logs --stream stderr CONTAINER_ID
# Logs avec timestamps
crictl logs -t --stream stderr CONTAINER_ID
# Suivre les logs en temps réel
crictl logs -f --stream stdout CONTAINER_ID
Combinaison avec autres options :# 100 dernières lignes de stderr
crictl logs --tail 100 --stream stderr CONTAINER_ID
Support TLS (v1.32+)
crictl exec \
--tls-ca /path/to/ca.crt \
--tls-cert /path/to/client.crt \
--tls-key /path/to/client.key \
--tls-server-name api.example.com \
-it CONTAINER_ID /bin/sh
Options TLS disponibles :| Option | Description |
|---|---|
--tls-ca |
Certificat CA |
--tls-cert |
Certificat client |
--tls-key |
Clé privée client |
--tls-server-name |
Nom pour validation SNI |
exec, attach et port-forward.Workflow de débogage
# 1. Lister les pods
crictl pods
# 2. Inspecter un pod
crictl inspectp POD_ID
# 3. Lister les conteneurs du pod
crictl ps --pod POD_ID
# 4. Voir les logs
crictl logs CONTAINER_ID
# 5. Exécuter une commande
crictl exec -it CONTAINER_ID /bin/sh
# 6. Stats des conteneurs du pod
crictl statsp
Astuce : Utilisez crictl info pour vérifier que le runtime est accessible.RuntimeFeatures (v1.33+)
# Afficher les infos du runtime
crictl info
# Extraire les features (jq)
crictl info -o json | jq '.features'
Exemple de sortie :{
"features": {
"supplementalGroupsPolicy": true,
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
Ces informations aident à vérifier la compatibilité avant d'utiliser des fonctionnalités avancées.Mise à jour OOM score (v1.33+)
# Protéger un conteneur critique
crictl update --oom-score-adj -500 CONTAINER_ID
# Rendre un conteneur prioritaire pour OOM killer
crictl update --oom-score-adj 500 CONTAINER_ID
Échelle des valeurs :| Valeur | Comportement |
|---|---|
| -1000 | Jamais tué par OOM |
| 0 | Comportement par défaut |
| 1000 | Tué en premier |
--cpu-share, --memory, --cpuset-cpusInstallation standalone
# Définir la version
VERSION="v1.35.0"
ARCH="amd64"
# Télécharger et installer
curl -sL "https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-${ARCH}.tar.gz" \
| sudo tar -xzf - -C /usr/local/bin
# Vérifier l'installation
crictl --version
Configuration : Créez /etc/crictl.yaml avec le socket de votre runtime (containerd ou CRI-O).Note : crictl suit les versions mineures de Kubernetes (ex: crictl 1.35 pour K8s 1.35).