Il y a deux façons de regarder un cluster Kubernetes. La première consiste à taper kubectl get pods -n production, lire la sortie, repérer le pod qui pose problème, copier son nom, taper kubectl describe pod ce-nom -n production, ne pas trouver ce qu'on cherchait, taper kubectl logs ce-nom -n production -c le-bon-conteneur, se tromper de conteneur, recommencer. La seconde consiste à lancer k9s et à appuyer sur l.
Les deux approches sont légitimes et cet article ne va pas vous expliquer que la première est ridicule. kubectl reste l'interface de référence, celle qui se scripte, celle qui existe partout, celle dont la sortie est stable. k9s est un confort de lecture et d'exploration, pas un remplacement.
Ce guide est écrit pour k9s 0.51, sorti en juin 2026. Les raccourcis de k9s bougent d'une version à l'autre, plus souvent qu'on ne le voudrait, donc vérifiez votre version avec k9s version avant de vous étonner qu'une touche ne fasse pas ce qui est écrit ici.
Au programme : installer k9s sur Linux, macOS et WSL2, comprendre ce qu'affiche l'écran de départ, naviguer avec la barre de commande et les alias, lire des logs et ouvrir un shell dans un conteneur, faire du port-forward, changer de contexte et de namespace, puis configurer l'outil à votre main - skin transparent, hotkeys, plugins. Aucun prérequis au-delà d'un kubeconfig fonctionnel et d'un cluster auquel vous avez accès.
k9s et kubectl - ce que chacun fait bien
Poser k9s contre kubectl comme deux concurrents est une erreur de cadrage. k9s utilise votre kubeconfig, vos contextes, vos droits RBAC. Il parle à la même API. Ce qu'il change, c'est la boucle entre votre question et sa réponse.
Ce que kubectl fait mieux
- Il se scripte. Un pipeline CI, un runbook, un
Makefile: rien de tout ça ne peut passer par une interface interactive. Tout ce que vous automatisez restera en kubectl. - Sa sortie est un contrat.
-o json,-o jsonpath,-o custom-columnsproduisent des formats stables que vous pouvez traiter avec jq. Un TUI n'offre rien de comparable. - Il est partout. Sur un bastion minimal, dans un conteneur de debug, sur la machine d'un collègue, kubectl est là. k9s est un binaire de plus à installer.
- Il documente ce que vous avez fait. Une commande kubectl se copie dans un ticket, se relit dans un historique de shell, se rejoue à l'identique. Une suite de frappes dans un TUI ne laisse aucune trace exploitable.
- Il ne cache rien. Vous voyez exactement la requête que vous envoyez. Dans k9s, une touche déclenche parfois plusieurs appels API et vous ne les voyez pas.
Ce que k9s fait mieux
- L'exploration. Quand vous ne savez pas encore ce que vous cherchez, parcourir des ressources avec des touches bat très largement l'enchaînement de commandes. C'est le cas d'usage principal, et il est réel.
- Le rafraîchissement automatique. Un rollout qui se déroule, des pods qui passent de
PendingàRunning, un HPA qui scale : k9s rafraîchit tout seul toutes les deux secondes par défaut. Pas dewatch -n2 kubectl get pods. - Le passage d'une ressource à ses voisines. D'un deployment vers ses replicasets, d'un replicaset vers ses pods, d'un pod vers son node, d'un pod vers ses logs. Trois touches, aucun copier-coller de nom de ressource.
- Le choix du conteneur. Sur un pod multi-conteneurs avec des sidecars, k9s vous présente la liste. Vous ne mémorisez plus les noms.
- Les logs, tout de suite.
lsur un pod, et vous y êtes, avec l'autoscroll, le wrap et les timestamps sur des touches.
Comment les deux cohabitent en pratique
La répartition qui fonctionne, et que la plupart des gens finissent par adopter sans se le formuler :
- k9s pour comprendre. L'investigation, le diagnostic, le "qu'est-ce qui se passe sur ce cluster".
- kubectl pour agir et pour tracer. Les applications de manifeste, les commandes qui finiront dans un post-mortem, tout ce qui doit être reproductible.
Ce partage n'est pas un compromis mou, c'est le bon découpage. La lecture est interactive par nature, l'écriture doit être traçable.
Le point de friction honnête
k9s facilite des actions destructrices. ctrl-d supprime, ctrl-k tue sans confirmation, r redémarre un deployment. Sur un cluster de prod, un raccourci mal placé au mauvais moment se paie. La section mode lecture seule plus bas traite du mode lecture seule, et ce n'est pas une option cosmétique : c'est le prix d'entrée pour utiliser un TUI sur de la prod.
Autre réserve, plus discrète : k9s interroge l'API en continu. Sur un très gros cluster, plusieurs dizaines de sessions k9s ouvertes en permanence sur des vues coûteuses représentent une charge non nulle sur l'API server. La 0.51 a d'ailleurs relevé le QPS client par défaut de 5 à 50 et paginé les appels à l'API de métriques, ce qui va dans le bon sens côté réactivité, mais ne rend pas la question caduque.
Les alternatives à k9s
k9s n'est pas seul, et selon votre contexte un autre outil peut mieux vous convenir.
Headlamp est le choix par défaut côté interface graphique depuis 2026. Projet CNCF maintenu sous kubernetes-sigs, il s'utilise en desktop ou déployé dans le cluster, gère plusieurs clusters dans la même fenêtre et s'étend par plugins. C'est ce qu'il faut proposer à des développeurs qui ne vivent pas dans un terminal.
Kubernetes Dashboard, l'ancienne interface web officielle, est archivée depuis le 21 janvier 2026, faute de mainteneurs. Le projet Kubernetes recommande explicitement de migrer vers Headlamp et a publié deux billets pour accompagner la bascule : la transition et le guide pas à pas. Si vous trouvez un tutoriel qui vous propose encore de la déployer, il est périmé. Le dépôt est en lecture seule.
Lens a longtemps été la référence GUI. Son passage sous licence commerciale en 2022 a fait naître OpenLens puis, celui-ci s'étant essoufflé, le fork Freelens, qui est aujourd'hui le plus actif des deux. L'écosystème est vivant mais fragmenté, vérifiez l'état de maintenance avant de vous engager.
Aptakube est une interface graphique commerciale, multi-cluster, avec un vrai travail d'ergonomie. Payante, ce qui se défend si l'outil vous fait gagner du temps tous les jours.
kubectl augmenté reste une option sérieuse et sous-estimée : kubectx et kubens pour jongler entre contextes et namespaces, stern pour agréger les logs de plusieurs pods, kube-ps1 pour afficher le contexte courant dans votre prompt zsh. Vous gardez la traçabilité de kubectl et vous éliminez l'essentiel de la friction. Beaucoup de gens n'ont jamais eu besoin d'aller plus loin.
Le vrai critère de choix n'est pas la richesse fonctionnelle, c'est votre mode de travail. Si vous vivez déjà dans un terminal avec tmux, k9s s'y intègre sans rupture. Si vous préférez une fenêtre séparée avec une souris, une GUI vous servira mieux, et il n'y a rien à défendre là-dedans.
Installer k9s sur Linux, macOS et WSL2
k9s est un binaire Go unique, sans dépendance. L'installation est triviale, la seule question est celle de la fraîcheur : les dépôts de distribution sont souvent en retard de plusieurs versions mineures, et sur un outil dont les raccourcis bougent, c'est un vrai sujet.
Installer k9s sur Linux
Le plus simple, et celui qui vous donne la dernière version :
# Récupérer la dernière release depuis GitHub
curl -sS https://webi.sh/k9s | sh
Ou manuellement, si vous préférez voir ce que vous téléchargez :
K9S_VERSION="v0.51.0"
curl -sL "https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_amd64.tar.gz" \
| tar xz -C /tmp k9s
install -m 0755 /tmp/k9s ~/.local/bin/k9s
Sur Arch, le paquet officiel suit correctement les releases :
sudo pacman -S k9s
Sur Debian et Ubuntu, il n'y a pas de paquet officiel à jour. Passez par le .deb de la release GitHub ou par le binaire, plutôt que par un dépôt tiers dont vous ne contrôlez pas le rythme.
Installer k9s sur macOS
brew install derailed/k9s/k9s
Le tap officiel est plus à jour que la formule de homebrew-core. Utilisez-le.
Installer k9s sur Windows avec WSL2
Dans votre distribution WSL2, suivez la procédure Linux. C'est la seule qui vaille : k9s existe en binaire Windows natif, mais il devra alors lire un kubeconfig côté Windows, avec les problèmes de chemins et de fins de ligne que ça implique. Si votre workflow Kubernetes est déjà dans WSL2, gardez tout au même endroit.
Une précision qui évite une heure de perplexité : votre terminal doit gérer correctement les couleurs 256 et les caractères Unicode. Windows Terminal le fait, cmd.exe non.
Vérifier l'installation
k9s version
Vous devez voir le logo ASCII, la version, le commit et la date de build. Puis :
k9s info
C'est la commande la plus utile du lot, et personne ne la connaît. Elle vous dit exactement où k9s lit et écrit ses fichiers :
Version: v0.51.0
Config: /home/vous/.config/k9s/config.yaml
Custom Views: /home/vous/.config/k9s/views.yaml
Custom Jumps: /home/vous/.config/k9s/jumps.yaml
Plugins: /home/vous/.config/k9s/plugins.yaml
Hotkeys: /home/vous/.config/k9s/hotkeys.yaml
Aliases: /home/vous/.config/k9s/aliases.yaml
Skins: /home/vous/.config/k9s/skins
Context Configs: /home/vous/.local/share/k9s/clusters
Logs: /home/vous/.local/state/k9s/k9s.log
Benchmarks: /home/vous/.local/state/k9s/benchmarks
ScreenDumps: /home/vous/.local/state/k9s/screen-dumps
Notez la répartition XDG : la configuration dans ~/.config, l'état par cluster dans ~/.local/share, les logs et les artefacts jetables dans ~/.local/state. Les guides plus anciens parlent de ~/.k9s/, c'est obsolète depuis la 0.30. Si vous trouvez encore ce dossier chez vous, il ne sert plus à rien.
Quand quelque chose ne marche pas, ~/.local/state/k9s/k9s.log est le premier endroit à regarder. On y revient dans la section dépannage.
Lire l'écran au premier lancement
Lancez k9s. Après l'écran de démarrage, vous arrivez sur une vue de ressources. Trois zones à distinguer.

En haut à gauche, le bloc d'information. Contexte courant, cluster, utilisateur, version de k9s, version du cluster, consommation CPU et mémoire. C'est ici que vous vérifiez sur quel cluster vous êtes avant de faire une bêtise. Prenez l'habitude de le lire, sérieusement.
Le marqueur [RW] accolé au contexte indique que la session est en écriture. En lecture seule il affiche [RO]. C'est le seul endroit où l'information apparaît, et elle vaut le coup d'œil avant toute action sur un cluster que vous ne connaissez pas.
Vous aurez aussi remarqué la ligne K8s Rev de ces captures : v1.31.14. Une version sortie en août 2024 et hors support depuis octobre 2025. Le cluster tourne parfaitement, merci de vous en inquiéter. C'est là toute la cruauté de ce bandeau : il affiche votre dette technique en orange, en haut à gauche, à chaque lancement, tous les jours, sans jamais se lasser ni proposer de plan de migration. kubectl version a au moins la décence d'attendre qu'on la sollicite.
En haut au centre, les namespaces favoris. Numérotés de 0 à 9. 0 est toujours all. Appuyer sur le chiffre bascule le namespace actif. La liste se construit toute seule au fil de vos visites, les namespaces les plus fréquentés remontent. Sur la capture ci-dessus cette zone est absente : les nodes sont une ressource de portée cluster, pas de portée namespace, donc k9s n'affiche pas les favoris. Vous les retrouverez sur toute vue de ressource namespacée, comme les pods.
En haut à droite, les raccourcis contextuels. Cette zone change selon la vue. C'est votre aide-mémoire permanent : ce qui y est listé est ce qui fonctionne ici et maintenant. Quand vous ne savez plus quelle touche fait quoi, regardez à droite avant de chercher ailleurs.
Au centre, la table. Les ressources, avec un titre qui indique le type affiché, le namespace, et un compteur. Le fil d'Ariane en bas de l'écran montre la pile de vues que vous avez ouvertes.
? ouvre l'aide complète des raccourcis de la vue courante. esc revient en arrière, toujours, à tous les niveaux. Ces deux touches suffisent à explorer sans rien casser.
Pour un écran plus dépouillé, trois options qui se cumulent :
k9s --headless # masque le bloc d'information
k9s --crumbsless # masque le fil d'Ariane
k9s --logoless # masque le logo
k9s --splashless # saute l'écran de démarrage
Je déconseille --headless sur un poste qui accède à de la prod. Le bandeau de contexte est exactement ce qui vous empêche de confondre staging et production.
Naviguer : la barre de commande et les alias
Tout part de :. Cette touche ouvre la barre de commande, où vous tapez un type de ressource.
:pod # ou :po, ou :pods
:deploy # deployments
:svc # services
:ing # ingress
:node # nodes
:cm # configmaps
:sec # secrets
:ev # events, la vue la plus sous-utilisée de k9s
k9s accepte le singulier, le pluriel et les noms courts de kubectl. Il accepte aussi les CRD : :certificates, :prometheusrules, :virtualservices fonctionnent si les ressources existent dans le cluster.
ctrl-a liste tous les alias disponibles. C'est la commande à retenir quand vous cherchez comment atteindre une ressource. Elle affiche la table complète des correspondances, y compris celles des CRD installés.
Quelques vues qui ne correspondent à aucune ressource Kubernetes et qui méritent d'être connues :
| Commande | Alias | Ce que ça affiche |
|---|---|---|
:xray RESSOURCE | :x | Arbre de dépendances d'un type de ressource |
:pulse | :pu, :hz | Tableau de bord temps réel du cluster |
:workload | :wk | Vue agrégée de toutes les charges de travail |
:portforward | :pf | Les port-forwards actifs de votre session |
:context | :ctx | Sélecteur de contexte |
:screendump | :sd | Les captures d'écran sauvegardées |
:charts | :hm | Les releases Helm |
:dir CHEMIN | :d | Parcourt des manifestes sur disque |
:alias | :a | La table des alias |
:help | :h, :? | L'aide |
:quit | :q | Quitter |
:wk est arrivée récemment et remplace avantageusement l'aller-retour entre :deploy, :sts et :ds quand vous voulez juste savoir ce qui tourne.
La barre de commande accepte aussi des arguments, ce qui vous évite deux navigations :
:pod monitoring # les pods du namespace monitoring
:pod /nginx # les pods dont le nom contient nginx
:pod app=api,env=prod # filtrage par labels
:pod @staging # les pods d'un autre contexte, sans changer le contexte courant
Ce dernier point est méconnu et très utile : @contexte interroge un autre cluster sans quitter celui où vous êtes.
Filtrer et chercher
/ ouvre le filtre sur la vue courante. Le texte saisi est une expression régulière appliquée aux noms.
/api # les lignes contenant "api"
/-!api # filtre inverse : tout sauf "api"
/-l app=front # filtrage par label selector
/-f api # recherche floue, tolère les fautes de frappe
enter valide le filtre et vous rend la navigation. esc l'efface. La touche q efface aussi le filtre, ce qui surprend au début quand on s'attend à quitter.

Le filtre actif est rappelé à deux endroits : dans le prompt sous le bandeau, et à droite du titre de la table. Ce second rappel est celui qui compte, parce qu'il reste visible après que vous avez validé avec enter et rendu la main à la navigation. Un compteur de lignes vous indique en permanence combien de ressources passent le filtre.
Deux raccourcis de table qui changent la vie sur des listes longues :
ctrl-wbascule l'affichage large, l'équivalent de-o wide. Les colonnes supplémentaires apparaissent : node, IP, nominated node.ctrl-zne montre que les ressources en défaut. Sur un namespace avec deux cents pods dont trois qui crashent, cette touche vous donne la réponse immédiatement.
Pour le tri, shift-n trie par nom, shift-a par âge, shift-s par statut. shift-o trie sur la colonne actuellement sélectionnée, ce qui suppose d'avoir navigué entre colonnes avec shift-flèche gauche et shift-flèche droite. La 0.51 a ajouté des indications visuelles pour cette navigation par colonnes, qui était jusque-là parfaitement invisible.
Enfin, la sélection multiple : espace marque une ligne, ctrl-espace marque une plage, ctrl-\ efface les marques. Les actions s'appliquent alors à toutes les lignes marquées. Utile pour supprimer une série de pods d'un coup, et dangereux exactement pour la même raison.
Les raccourcis du quotidien
Voici ceux qui couvrent l'essentiel du travail. Ils sont vérifiés sur la 0.51.
La touche ? affiche à tout moment la liste complète de ce qui est actif dans la vue courante, répartie en quatre colonnes : les actions sur la ressource, les commandes générales, la navigation, et vos hotkeys personnalisées.

C'est la source à privilégier sur toute documentation en ligne, la vôtre incluse : elle correspond exactement à votre version et à vos personnalisations.
Sur n'importe quelle ressource
| Touche | Action |
|---|---|
d | Describe |
y | Afficher le YAML |
e | Éditer dans $EDITOR |
c | Copier le nom de la ressource |
n | Copier le namespace |
w | Basculer vers le namespace de la ressource sélectionnée |
shift-j | Remonter au propriétaire de la ressource |
enter | Descendre dans la ressource |
ctrl-r | Rafraîchir manuellement |
ctrl-d | Supprimer, avec confirmation |
ctrl-s | Sauvegarder la vue dans un fichier |
0 à 9 | Basculer de namespace |
esc | Remonter d'un niveau |
? | Aide de la vue courante |
w est le raccourci que personne ne connaît et qui fait gagner le plus de temps : depuis une vue all namespaces, il vous téléporte dans le namespace du pod sélectionné. shift-j fait le trajet inverse de enter : depuis un pod, il remonte au replicaset, puis au deployment.
La navigation au clavier
k9s reprend les déplacements de vi, ce qui évite les allers-retours vers les flèches.
| Touche | Action |
|---|---|
j et k | Descendre et monter |
h et l | Gauche et droite |
g et shift-g | Aller en haut, aller en bas |
ctrl-f et ctrl-b | Page suivante, page précédente |
[ et ] | Reculer et avancer dans l'historique des vues |
← → | Rappeler la dernière commande utilisée |
ctrl-u | Effacer la saisie de la barre de commande |
tab et shift-tab | Champ suivant, champ précédent dans un dialogue |
L'historique [ et ] est le plus rentable des huit : il rejoue votre parcours de vues sans retaper une seule commande.
Spécifiques aux pods
| Touche | Action |
|---|---|
l | Logs du conteneur |
p | Logs de l'instance précédente, après un crash |
s | Ouvrir un shell dans le conteneur |
a | S'attacher aux flux du conteneur |
t | Transférer des fichiers vers ou depuis le pod |
o | Afficher le node qui héberge le pod |
z | Nettoyer les pods terminés ou en erreur |
ctrl-k | Tuer le pod, sans confirmation |
p est le réflexe à acquérir face à un CrashLoopBackOff : les logs du conteneur courant sont vides ou inutiles, ceux de l'instance précédente contiennent l'erreur qui a tué le processus.
ctrl-k ne demande rien. C'est délibéré, c'est documenté, et c'est la première raison d'activer le mode lecture seule sur les contextes de production.
Spécifiques aux deployments
| Touche | Action |
|---|---|
s | Scaler, avec saisie du nombre de replicas |
r | Redémarrer, l'équivalent de kubectl rollout restart |
z | Afficher les replicasets associés |
Spécifiques aux nodes
| Touche | Action |
|---|---|
c | Cordon, marquer le node non planifiable |
u | Uncordon |
r | Drain, évacuer les pods |
s | Shell sur le node, si le feature gate est activé |
y | YAML du node |
Le shell sur node mérite une note. Il n'est pas actif par défaut : k9s lance un pod privilégié sur le node pour vous y donner accès, ce qui est une opération sensible. Il faut l'activer explicitement par contexte, voir la section configuration.
Logs, shell et transfert de fichiers
Lire des logs correctement
l sur un pod ouvre la vue logs. Si le pod a plusieurs conteneurs, k9s vous fait d'abord choisir. Les raccourcis de cette vue :
| Touche | Action |
|---|---|
s | Basculer l'autoscroll |
w | Basculer le retour à la ligne |
t | Afficher ou masquer les timestamps |
f | Plein écran |
a | Afficher tous les conteneurs à la fois |
m | Poser un marqueur dans le flux |
shift-c | Effacer l'écran |
shift-l | Verrouiller les colonnes |
ctrl-s | Sauvegarder les logs dans un fichier |
c | Copier |
/ | Filtrer le flux |
esc ou q | Revenir en arrière |
Trois de ces touches méritent d'être retenues. m pose un repère visuel : vous marquez avant de reproduire un bug, et vous savez ensuite exactement où commence ce qui vous intéresse. a agrège les conteneurs d'un pod, ce qui économise l'installation de stern pour les cas simples. s coupe l'autoscroll, indispensable pour lire tranquillement un flux bavard.
Le nombre de lignes chargées au démarrage et la taille du buffer se règlent dans la configuration, section logger. Les valeurs par défaut, 100 lignes affichées et 5000 en buffer, sont un peu justes sur une application verbeuse.

La barre d'état sous le titre donne l'état des cinq bascules en un coup d'œil, ce qui évite de tâtonner. Le titre rappelle le namespace, le pod et le conteneur affichés, ainsi que le mode de lecture entre crochets.
Ouvrir un shell
s sur un pod ouvre un shell dans le conteneur. Comme pour les logs, k9s vous demande le conteneur s'il y en a plusieurs. Il détecte le shell disponible, bash puis sh, et la 0.51 gère même le cas des conteneurs Windows NanoServer.
Si le conteneur n'a pas de shell du tout, ce qui est la norme sur une image distroless ou scratch, s échoue. La réponse correcte n'est pas de gonfler votre image, c'est un conteneur éphémère de debug :
kubectl debug -it mon-pod --image=busybox:1.37.0 --target=mon-conteneur
k9s 0.51 a amélioré la configuration des conteneurs de debug avec des champs de saisie, mais l'opération reste plus lisible en kubectl.
t ouvre le transfert de fichiers, dans les deux sens, ce qui remplace kubectl cp avec une interface qui vous évite de vous tromper de sens dans la syntaxe.
Le pod de debug configurable
Pour le shell sur node, k9s lance un pod dont vous contrôlez l'image et les limites :
k9s:
shellPod:
image: busybox:1.37.0
namespace: default
limits:
cpu: 100m
memory: 100Mi
Si votre cluster tire ses images depuis un registre privé, remplacez l'image par une des vôtres. Sinon le shell sur node échouera silencieusement sur un ImagePullBackOff que vous ne verrez pas.
Le port-forward
Le port-forward de k9s est plus agréable que celui de kubectl sur un point précis : il survit à la navigation. Vous le lancez, vous continuez à travailler dans k9s, il tourne en arrière-plan.
shift-fouvre le dialogue de port-forward. Vous y choisissez le port du conteneur, le port local et l'adresse d'écoute. La touche fonctionne directement depuis la liste des pods ; descendre d'abord dans les conteneurs avecenterne sert que si le pod en a plusieurs et que vous voulez choisir lequel exposer.faffiche les port-forwards déjà actifs sur la ressource sélectionnée.:pfliste tous les port-forwards de la session, depuis n'importe quelle vue.
Depuis la vue :pf, ctrl-d coupe un forward.

Un point qui déroute au premier essai : :pf n'affiche que les forwards que vous avez créés dans la session courante. Sur une session neuve, la vue est vide, et ce n'est pas un bug. La colonne PF de la vue conteneurs, elle, marque les conteneurs qui en ont un d'actif, et la colonne PORTS vous donne le port à saisir dans le dialogue.
Deux limites à connaître. D'abord, les port-forwards meurent avec la session k9s. Si vous quittez, tout tombe. Pour un tunnel qui doit durer, un kubectl port-forward dans une fenêtre tmux détachée est plus adapté. Ensuite, l'adresse d'écoute par défaut est localhost, ce qui est le bon défaut. Si vous devez exposer sur toutes les interfaces, c'est dans la configuration :
k9s:
portForwardAddress: 0.0.0.0
Réfléchissez à deux fois avant. Sur un poste connecté à un réseau d'entreprise, ça expose votre base de données de production à tout le monde sur le segment.
Contextes et namespaces
:ctx ouvre le sélecteur de contexte. enter bascule. C'est tout, et c'est nettement plus rapide que kubectl config use-context avec un nom de contexte de quarante caractères à taper.
Pour démarrer directement sur un contexte :
k9s --context staging
k9s --context prod -n monitoring
k9s -A # tous les namespaces
k9s -c deploy # démarrer sur la vue deployments
La combinaison --context et -c est celle que je mettrais dans un alias zsh pour chaque cluster que vous fréquentez.
Côté namespaces, :ns liste, les touches 0 à 9 basculent entre les favoris. Cette liste de favoris est persistée par contexte, dans ~/.local/share/k9s/clusters/<cluster>/<contexte>/config.yaml :
k9s:
cluster: kubernetes
namespace:
active: all
lockFavorites: false
favorites:
- apps
- all
- default
view:
active: v1/nodes
featureGates:
nodeShell: false
proxy: null
Ce fichier est intéressant à connaître pour trois raisons. view.active définit la vue d'ouverture pour ce contexte précis : si vous ouvrez toujours ce cluster pour regarder les nodes, posez-le ici. lockFavorites: true fige la liste des namespaces, ce qui empêche k9s de la réorganiser au fil de vos visites - appréciable quand vous avez fini par mémoriser que 3 est monitoring. Et featureGates.nodeShell est l'interrupteur du shell sur node évoqué plus haut.

Dans cette vue, le signe + accolé à un nom signale un namespace enregistré en favori, et all+(*) la ligne qui les couvre tous. La touche u, pour Use, bascule sur le namespace sélectionné, ce qui revient au même que enter mais s'applique aussi depuis une ligne non favorite.
Au-delà des pods : xray, pulses, workloads
Trois vues qui n'existent pas dans kubectl et qui justifient à elles seules d'ouvrir k9s.
:xray RESSOURCE affiche un arbre de dépendances. :xray deploy vous montre chaque deployment, ses replicasets, ses pods, ses conteneurs, avec l'état de santé propagé. C'est la vue qui répond en un coup d'œil à "quel deployment est en train de mal se passer". espace déplie ou replie un nœud, x déplie ou replie l'arbre entier, enter saute à la ressource sélectionnée dans sa vue normale. Les actions habituelles restent disponibles sur les nœuds. Depuis la 0.51, xray respecte correctement le mode lecture seule, ce qui n'était pas le cas avant.
:pulse est un tableau de bord temps réel : compteurs par type de ressource, cadrans de santé, événements récents. C'est ce qu'on laisse tourner sur un second écran pendant un déploiement. La 0.51 permet de cycler dans la grille dans les deux sens, ce qui rend la vue réellement navigable.
:workload agrège deployments, statefulsets, daemonsets, jobs et cronjobs dans une seule table. Quand vous cherchez "ce qui tourne" sans savoir sous quel type c'est déclaré, c'est le point d'entrée.

Configurer k9s
Le fichier principal est ~/.config/k9s/config.yaml. k9s le crée au premier lancement avec tous les champs et leurs valeurs par défaut, ce qui en fait sa propre documentation. Voici les réglages qui valent le détour.
k9s:
refreshRate: 2
apiServerTimeout: 2m0s
maxConnRetry: 5
readOnly: false
noExitOnCtrlC: false
portForwardAddress: localhost
liveViewAutoRefresh: false
skipLatestRevCheck: false
disablePodCounting: false
ui:
enableMouse: false
headless: false
logoless: false
crumbsless: false
splashless: false
reactive: false
noIcons: false
defaultsToFullScreen: false
useFullGVRTitle: false
skin: transparent
logger:
tail: 100
buffer: 5000
sinceSeconds: -1
textWrap: false
disableAutoscroll: false
showTime: false
thresholds:
cpu:
critical: 90
warn: 70
memory:
critical: 90
warn: 70
Ceux qui changent vraiment quelque chose :
refreshRate: deux secondes par défaut. Sur un gros cluster ou une connexion lente, montez à 5 ou 10. Vous soulagez l'API server et vous arrêtez de voir la table clignoter.noExitOnCtrlC: true: empêchectrl-cde fermer k9s. Si vous avez le réflexectrl-cdu shell, activez-le, vous perdrez moins de sessions.ui.noIcons: true: remplace les emoji par du texte. Nécessaire si votre police de terminal ne gère pas les glyphes, et honnêtement plus lisible.ui.reactive: true: recharge la configuration et le skin à chaud dès que le fichier change sur disque. Indispensable pendant que vous mettez au point un skin, vous voyez le résultat sans relancer.logger.tail: passez à 500 ou 1000. Cent lignes, c'est peu quand l'erreur est déjà remontée.skipLatestRevCheck: true: coupe la vérification de nouvelle version au démarrage. Un appel réseau de moins, et vous n'êtes plus tenté de mettre à jour au milieu d'un incident.thresholds: les seuils de coloration CPU et mémoire. À ajuster selon ce que vous considérez comme normal chez vous.
Un mot sur enableMouse. La souris fonctionne, mais elle entre en conflit avec la sélection de texte du terminal : avec la souris activée, vous ne pouvez plus surligner pour copier. Sur un TUI qu'on utilise justement pour lire, c'est un mauvais marché. Laissez à false.
Le tuning visuel : skins et transparence
C'est la partie qui rend l'outil agréable, et elle est très souvent négligée.
Les skins vont dans ~/.config/k9s/skins/, un fichier YAML par thème, et vous le référencez par son nom de fichier sans extension dans ui.skin. k9s embarque plusieurs thèmes, dont un One Light ajouté en 0.51.
Le skin transparent
Si vous avez configuré un fond de terminal avec de la transparence ou une image, k9s le recouvre par défaut avec sa propre couleur de fond, ce qui annule tout votre travail. La solution est un skin qui utilise default partout où une couleur de fond est attendue : default signifie "n'écris rien, laisse passer le terminal".
Créez ~/.config/k9s/skins/transparent.yaml :
k9s:
body:
fgColor: default
bgColor: default
logoColor: blue
prompt:
fgColor: default
bgColor: default
suggestColor: dodgerblue
info:
fgColor: orange
sectionColor: default
frame:
border:
fgColor: dodgerblue
focusColor: aliceblue
menu:
fgColor: default
keyColor: dodgerblue
numKeyColor: dodgerblue
crumbs:
fgColor: default
bgColor: default
activeColor: dodgerblue
status:
newColor: '#00ff00'
modifyColor: aqua
addColor: lightskyblue
errorColor: orangered
highlightColor: aquamarine
killColor: mediumpurple
completedColor: gray
title:
fgColor: aqua
bgColor: default
highlightColor: fuchsia
counterColor: papayawhip
filterColor: seagreen
views:
charts:
bgColor: default
defaultDialColors: [dodgerblue, orangered]
defaultChartColors: [dodgerblue, orangered]
table:
fgColor: default
bgColor: default
header:
fgColor: default
bgColor: default
sorterColor: orange
xray:
fgColor: default
bgColor: default
cursorColor: aqua
graphicColor: dodgerblue
yaml:
keyColor: steelblue
colonColor: default
valueColor: papayawhip
logs:
fgColor: default
bgColor: default
indicator:
fgColor: dodgerblue
bgColor: default
Puis dans config.yaml :
k9s:
ui:
skin: transparent
La règle est simple : tout bgColor doit valoir default, y compris dans table.header, logs et xray. Il suffit d'en oublier un pour voir un rectangle opaque traverser votre écran. Les couleurs de premier plan peuvent être nommées (dodgerblue, papayawhip) ou en hexadécimal (#00ff00), les deux formes cohabitent sans problème.
Activez ui.reactive: true pendant que vous ajustez : chaque sauvegarde du fichier se voit immédiatement.
Un skin par contexte
Le détail qui vaut de l'or en prod : le skin peut être défini par contexte, dans le fichier de contexte sous ~/.local/share/k9s/clusters/. Un skin rouge sur production, un skin neutre sur staging, et votre cerveau vous prévient avant votre lucidité.
k9s:
cluster: prod-eu-west
skin: danger
C'est le seul garde-fou visuel réellement efficace contre l'erreur de cluster. Le bandeau texte, on finit par ne plus le lire ; une couleur qui change, non.
Inverser un skin
k9s --invert
Bascule un skin sombre en clair, ou l'inverse, en préservant les teintes. Pratique quand vous passez d'un terminal sombre à une projection en salle de réunion.
Alias, hotkeys, vues personnalisées et plugins
Quatre mécanismes d'extension, quatre fichiers, souvent confondus. Voici la distinction.
Les alias : raccourcir une commande
~/.config/k9s/aliases.yaml associe un nom court à un type de ressource :
aliases:
dp: deployments
sec: v1/secrets
jo: jobs
cr: clusterroles
crb: clusterrolebindings
ro: roles
rb: rolebindings
np: networkpolicies
Vous tapez ensuite :dp au lieu de :deployments. C'est particulièrement utile pour les CRD, dont les noms sont interminables : un alias :vs pour virtualservices.networking.istio.io se rentabilise vite.
Les hotkeys : une touche vers une vue
~/.config/k9s/hotkeys.yaml associe une touche à une commande complète :
hotKeys:
shift-0:
shortCut: Shift-0
description: Pods en erreur, tous namespaces
command: pod /-!Running
keepHistory: true
shift-1:
shortCut: Shift-1
description: Events du cluster
command: events
shift-2:
shortCut: Shift-2
description: Nodes
command: node
Les champs disponibles sont shortCut, description, command, keepHistory et override. Ce dernier permet d'écraser un raccourci existant de k9s, à manier avec précaution : écraser d ou l vous privera de Describe ou de Logs sans prévenir.
Les vues personnalisées : choisir les colonnes
~/.config/k9s/views.yaml définit les colonnes affichées par type de ressource :
views:
v1/pods:
columns:
- NAME
- READY
- STATUS
- RESTARTS
- NODE
- AGE
sortColumn: AGE:desc
Si vous en avez assez de taper ctrl-w à chaque ouverture pour voir la colonne NODE, mettez-la ici une fois pour toutes.
Les plugins : appeler une commande externe
C'est le mécanisme le plus puissant. Un plugin lie une touche, dans un contexte donné, à une commande shell qui reçoit la ressource sélectionnée.
~/.config/k9s/plugins.yaml :
plugins:
stern:
shortCut: Ctrl-L
description: Logs stern
scopes:
- pods
command: stern
background: false
args:
- --tail
- "50"
- $NAME
- -n
- $NAMESPACE
- --context
- $CONTEXT
dive:
shortCut: Ctrl-I
description: Inspecter l'image
scopes:
- pods
command: sh
background: false
args:
- -c
- "dive $(kubectl get pod $NAME -n $NAMESPACE --context $CONTEXT -o jsonpath='{.spec.containers[0].image}')"
rollout-undo:
shortCut: Ctrl-U
description: Rollback du deployment
scopes:
- deployments
command: kubectl
background: true
dangerous: true
confirm: true
args:
- rollout
- undo
- deployment/$NAME
- -n
- $NAMESPACE
- --context
- $CONTEXT
Les variables disponibles sont $NAME, $NAMESPACE, $CONTEXT, $CLUSTER, $USER, $RESOURCE_NAME, $COL-<NOM> pour la valeur d'une colonne, et $FILTER pour le filtre courant.
Les champs qui comptent :
scopes: les vues où le plugin s'active.pods,deployments, ouall.background:trueexécute sans reprendre le terminal,falserend la main à la commande.dangerous: true: le plugin est désactivé en mode lecture seule. Posez-le sur tout ce qui écrit.confirm: true: demande confirmation avant exécution.overwriteOutput: remplace la sortie plutôt que de l'ajouter.inputs: nouveauté 0.51, permet de demander des valeurs à l'utilisateur avant l'exécution, avecname,label,type,required,defaultetoptions. C'est ce qui rend possible un plugin de redimensionnement de PVC, livré en exemple dans cette version.
Un point qui piège : dangerous: true sans confirm: true désactive le plugin en lecture seule mais l'exécute sans rien demander en mode écriture. Mettez les deux.
Le mode lecture seule et l'accès à la production
C'est la section à ne pas sauter si k9s doit toucher un cluster de production.
En mode écriture, k9s expose ctrl-d pour supprimer, ctrl-k pour tuer sans confirmation, e pour éditer en direct, r pour redémarrer un deployment, s pour scaler. Toutes ces actions sont à une frappe. Une main mal placée sur un clavier suffit.
Le mode lecture seule s'active de trois manières, par ordre de robustesse croissante :
k9s --readonly
Le drapeau, à mettre dans un alias shell. Facile à oublier.
k9s:
readOnly: true
Le réglage global dans config.yaml. Plus fiable, mais il s'applique aussi à vos clusters de développement, où vous voulez pouvoir agir. Le drapeau --write permet de le lever ponctuellement, ce qui est le bon compromis : par défaut on lit, on demande explicitement à écrire.
k9s:
cluster: prod-eu-west
readOnly: true
Le réglage par contexte, sous ~/.local/share/k9s/clusters/. C'est le bon endroit. Il suit le cluster, pas votre humeur.
Quelques principes qui vont avec :
- Le vrai garde-fou est RBAC, pas k9s. Un ServiceAccount en lecture seule côté cluster empêche l'action ; un réglage local dans un fichier YAML de votre poste ne fait que masquer un bouton. k9s affiche d'ailleurs les vues
:rbac,:usret:grppour vérifier vos droits effectifs. - Un skin distinct par environnement, comme vu plus haut. La couleur passe avant le texte.
- Ne mettez pas k9s sur un bastion partagé en mode écriture avec un kubeconfig d'admin. La combinaison est mauvaise.
--aset--as-grouppermettent d'usurper une identité pour tester des droits RBAC. Excellent pour valider une politique avant de la livrer.
Dépannage
k9s ne trouve pas mon cluster
Vérifiez d'abord que kubectl fonctionne :
kubectl config current-context
kubectl get nodes
Si kubectl passe et pas k9s, c'est un problème de kubeconfig lu. k9s suit $KUBECONFIG puis ~/.kube/config. En cas de doute, forcez :
k9s --kubeconfig ~/.kube/prod-config
Les métriques sont vides
Les colonnes CPU et mémoire affichent n/a ou restent vides. Ce n'est pas un bug de k9s : le metrics-server n'est pas installé ou ne répond pas. Vérifiez avec kubectl top nodes. Si cette commande échoue, k9s ne peut rien afficher de plus.
Les caractères sont cassés ou les icônes illisibles
Deux causes possibles. Soit TERM n'annonce pas les couleurs :
export TERM=xterm-256color
Soit votre police ne contient pas les emoji utilisés. Dans ce cas :
k9s:
ui:
noIcons: true
Un raccourci ne fait pas ce qui est documenté
Le premier réflexe est ?, qui affiche les raccourcis réellement actifs dans la vue courante. Le deuxième est k9s version : les raccourcis changent entre versions mineures, et beaucoup de tutoriels en ligne datent de la série 0.2x.
Vérifiez aussi que vous n'avez pas un hotKeys ou un plugin avec override: true qui écrase la touche.
k9s est lent ou fait ramer l'API server
Montez refreshRate à 10, désactivez disablePodCounting si vous avez des namespaces énormes, et évitez de laisser :pulse ouvert en permanence. Sur un cluster à plusieurs milliers de pods, une vue all namespaces est coûteuse par nature.
Le shell sur node ne marche pas
Le feature gate est désactivé par défaut. Activez-le dans le fichier du contexte concerné :
k9s:
featureGates:
nodeShell: true
Et vérifiez que l'image de shellPod est accessible depuis le cluster. Si votre registre est privé, busybox:1.37.0 depuis Docker Hub ne sera peut-être pas tirable.
Tableau des erreurs courantes
| Symptôme | Cause probable | Correction |
|---|---|---|
Unable to connect to context | kubeconfig invalide ou expiré | Renouveler les credentials, tester avec kubectl |
| Colonnes CPU/MEM vides | metrics-server absent | Installer metrics-server |
s ne fait rien sur un pod | Image sans shell, ou mode lecture seule | kubectl debug, ou lever le readOnly |
| Rectangles opaques avec un skin transparent | Un bgColor oublié | Mettre default sur tous les bgColor |
You don't have enough RBAC permissions | Droits insuffisants | Vérifier avec :rbac |
| Port-forward qui tombe | Session k9s fermée | Utiliser kubectl port-forward pour un tunnel durable |
| Vue vide sur un CRD existant | Alias mal résolu | ctrl-a pour retrouver le bon nom |
k9s se ferme sur ctrl-c | Comportement par défaut | noExitOnCtrlC: true |
Et quand rien de tout ça ne suffit, les logs :
k9s --logLevel debug
tail -f ~/.local/state/k9s/k9s.log
À retenir
| Commande ou touche | Pour quoi |
|---|---|
k9s info | Où k9s lit et écrit tous ses fichiers |
? | Les raccourcis actifs dans la vue courante |
ctrl-a | Tous les alias de ressources disponibles |
:ctx | Changer de contexte |
:pf | Les port-forwards actifs |
:xray deploy | Arbre de dépendances des deployments |
:wk | Vue agrégée de toutes les charges de travail |
/-!Running | Tout ce qui n'est pas dans l'état Running |
ctrl-z | Ne montrer que les ressources en défaut |
ctrl-w | Colonnes larges, équivalent de -o wide |
w | Basculer dans le namespace de la ligne sélectionnée |
l puis p | Logs courants, puis logs de l'instance précédente |
shift-f | Port-forward depuis un conteneur |
--readonly | Le mode par défaut sur un cluster de production |
FAQ
Comment installer k9s sur Linux ?
Le plus simple est de télécharger le binaire depuis les releases GitHub et de le poser dans ~/.local/bin : curl -sL https://github.com/derailed/k9s/releases/download/v0.51.0/k9s_Linux_amd64.tar.gz | tar xz -C /tmp k9s && install -m 0755 /tmp/k9s ~/.local/bin/k9s. Sur Arch, pacman -S k9s suit correctement les releases. Sur Debian et Ubuntu, il n'y a pas de paquet officiel à jour, prenez le .deb de la release ou le binaire. Sur macOS, brew install derailed/k9s/k9s avec le tap officiel, plus frais que homebrew-core.
Où se trouve le fichier de configuration de k9s ?
~/.config/k9s/config.yaml depuis la version 0.30. Les skins sont dans ~/.config/k9s/skins/, les plugins, hotkeys, alias et vues personnalisées dans des fichiers séparés du même dossier. L'état par cluster est ailleurs, dans ~/.local/share/k9s/clusters/, et les logs dans ~/.local/state/k9s/k9s.log. La commande k9s info affiche tous ces chemins pour votre installation, ne les devinez pas. Les tutoriels qui parlent de ~/.k9s/ sont obsolètes.
Comment voir les logs d'un pod dans k9s ?
Sélectionnez le pod et appuyez sur l. Si le pod a plusieurs conteneurs, k9s vous fait choisir. Dans la vue logs, s bascule l'autoscroll, w le retour à la ligne, t les timestamps, f le plein écran, et a affiche tous les conteneurs du pod à la fois. Pour un pod qui redémarre en boucle, p affiche les logs de l'instance précédente : c'est là que se trouve l'erreur qui a tué le processus, pas dans les logs courants.
Comment ouvrir un shell dans un conteneur avec k9s ?
Touche s sur le pod. k9s détecte le shell disponible, bash puis sh. Si l'image est distroless ou scratch, il n'y a pas de shell et l'action échoue : passez alors par un conteneur éphémère avec kubectl debug -it mon-pod --image=busybox:1.37.0 --target=mon-conteneur. La touche s est désactivée en mode lecture seule, c'est une action classée dangereuse.
Comment faire un port-forward dans k9s ?
Sélectionnez le pod et appuyez sur shift-f : le dialogue vous demande le port du conteneur, le port local et l'adresse d'écoute. Si le pod a plusieurs conteneurs et que vous voulez choisir lequel exposer, descendez d'abord avec enter. f affiche les forwards actifs sur la ressource sélectionnée, :pf les liste tous depuis n'importe quelle vue, et ctrl-d en coupe un depuis cette liste. Si :pf semble vide, c'est normal : elle ne montre que les forwards créés dans la session en cours. Attention aussi, les port-forwards meurent avec la session k9s. Pour un tunnel qui doit durer, utilisez kubectl port-forward dans une fenêtre tmux détachée.
Comment changer de namespace dans k9s ?
Les touches 0 à 9 basculent entre les namespaces favoris affichés en haut de l'écran, 0 étant toujours all. :ns ouvre la liste complète. La touche w vous téléporte dans le namespace de la ressource sélectionnée, ce qui est le moyen le plus rapide depuis une vue tous namespaces. La liste des favoris est mémorisée par contexte et se réorganise selon vos visites ; lockFavorites: true dans le fichier du contexte la fige.
Comment rendre k9s transparent pour voir le fond de mon terminal ?
Créez un skin dans ~/.config/k9s/skins/transparent.yaml où tous les champs bgColor valent default, y compris ceux de table.header, logs, xray et charts. La valeur default indique à k9s de ne rien peindre et de laisser passer le terminal. Référencez ensuite le skin dans config.yaml sous ui.skin: transparent. Activez ui.reactive: true pendant la mise au point pour voir chaque modification sans relancer. Un seul bgColor oublié suffit à produire un rectangle opaque.
Comment passer k9s en lecture seule ?
Trois façons. Le drapeau k9s --readonly pour une session. Le champ readOnly: true dans config.yaml pour tous les clusters, avec --write pour lever la restriction ponctuellement. Et surtout readOnly: true dans le fichier de contexte sous ~/.local/share/k9s/clusters/<cluster>/<contexte>/config.yaml, qui applique la restriction au seul cluster concerné. C'est cette dernière forme qu'il faut utiliser pour la production, parce qu'elle suit le cluster et non votre configuration globale. Rappelez-vous que le vrai garde-fou reste RBAC côté cluster.
k9s remplace-t-il kubectl ?
Non, et ce n'est pas son objectif. k9s utilise votre kubeconfig, vos contextes et vos droits RBAC : il parle à la même API avec les mêmes permissions. Il excelle pour explorer et diagnostiquer, là où kubectl reste indispensable pour tout ce qui doit être scripté, tracé ou reproduit. Le découpage qui fonctionne est k9s pour comprendre, kubectl pour agir et pour laisser une trace.
Quelles sont les alternatives à k9s ?
Headlamp d'abord : projet CNCF maintenu sous kubernetes-sigs, utilisable en desktop ou déployé dans le cluster, c'est le successeur officiellement recommandé de Kubernetes Dashboard, lui-même archivé depuis janvier 2026. Ensuite Lens et son fork communautaire le plus actif, Freelens. Aptakube pour une GUI commerciale multi-cluster soignée. Et l'option souvent suffisante : kubectl augmenté de kubectx, kubens et stern, qui élimine l'essentiel de la friction sans renoncer à la traçabilité.
Pour aller plus loin
- k9scli.io - la documentation officielle, à lire en parallèle du dépôt
- github.com/derailed/k9s - les releases, dont les notes signalent les changements de raccourcis
- Documentation Kubernetes - Debug Running Pods - les techniques que k9s automatise
k9s infoet?dans l'application - vos deux meilleures sources, toujours à jour avec votre version