Toutes les briques sont en place : trois nœuds, du stockage répliqué, une adresse d'entrée et un domaine wildcard. Le moment est venu de vérifier que cet assemblage tient sa promesse — déployer une vraie application, avec sa base de données, puis regarder le cluster vivre.
Une application complète en un fichier
L'exemple retenu est un wiki : une application web plus une base PostgreSQL, donc deux composants et deux volumes. Tout tient dans un seul manifeste, qui décrit successivement :
- un Namespace dédié, pour isoler proprement l'application ;
- un Secret contenant les identifiants de la base ;
- deux PersistentVolumeClaim en classe
longhorn— un pour la base, un pour les données du wiki ; - deux Deployment et deux Service ;
- un Ingress déclarant le nom
wiki.cluster.labk3s.ev1.
kubectl apply -f wikijs.yaml
Aucune modification DNS n'est nécessaire : le wildcard couvre déjà ce nom. Quelques dizaines de secondes plus tard, l'application répond.
Le détail qui fait perdre une soirée
Un piège classique mérite d'être signalé, parce qu'il ne concerne pas que PostgreSQL. Un volume fraîchement formaté en ext4 contient un répertoire lost+found. PostgreSQL, lui, refuse de s'initialiser dans un répertoire non vide. Le conteneur redémarre alors en boucle avec un message peu explicite.
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
La parade tient en une variable : demander à la base de s'installer dans un sous-répertoire du volume plutôt qu'à sa racine. La règle générale à retenir : ne jamais supposer qu'un volume persistant est vierge.
Superviser : voir avant de subir
Un cluster sans supervision, c'est un cluster dont on découvre les problèmes par les utilisateurs. La pile standard tient en un chart Helm — kube-prometheus-stack — qui installe d'un coup Prometheus, Grafana, les exportateurs de métriques des nœuds et l'état de tous les objets Kubernetes.
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update
Les valeurs qui comptent dans la configuration :
grafana:
persistence:
enabled: true
storageClassName: longhorn # les tableaux de bord survivent au pod
size: 5Gi
service:
type: ClusterIP # exposé par Ingress, pas en direct
prometheus:
prometheusSpec:
retention: 7d # au-delà, ça ne sert qu'à remplir le disque
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: longhorn
resources:
requests:
storage: 20Gi
Deux choix méritent d'être expliqués. Prometheus et Grafana stockent sur Longhorn : sans cela, la perte d'un pod effacerait l'historique des métriques et les tableaux de bord — une supervision amnésique ne sert à rien. Et Prometheus n'est pas exposé : seule Grafana l'est, via un Ingress. La base de métriques n'a aucune raison d'être accessible depuis le réseau.

Consommation processeur et mémoire par nœud et par espace de noms : de quoi voir venir une saturation au lieu de la découvrir.
Les tableaux de bord fournis d'origine couvrent l'essentiel : consommation par nœud, par espace de noms et par pod, état des volumes, santé du plan de contrôle. C'est aussi ce qui permet de dimensionner correctement les demandes de ressources des applications, au lieu de les deviner.
Les commandes qu'on finit par connaître par cœur
# État global kubectl get nodes -o wide kubectl cluster-info kubectl get pods -A | grep -v Running # tout ce qui ne va pas, en une ligne # Réseau et exposition kubectl get svc -A kubectl get ingress -A kubectl -n metallb-system get ipaddresspools kubectl -n kube-system logs deploy/traefik # Stockage kubectl -n longhorn-system get pods kubectl get pvc -A # Diagnostic d'une application kubectl -n wikijs describe pod <nom> kubectl -n wikijs logs <nom> --previous # les logs d'avant le redémarrage
Deux d'entre elles sauvent régulièrement la mise : le grep -v Running, qui montre en une ligne tout ce qui ne tourne pas ; et le --previous, qui affiche les journaux du conteneur avant son dernier redémarrage — souvent le seul endroit où figure la vraie cause d'une boucle de redémarrage.
Rancher, pour voir le cluster autrement
En conclusion du lab, l'installation de Rancher — l'interface d'administration Kubernetes de référence — donne une vue graphique complète : espaces de noms, charges de travail, volumes, journaux, accès à un terminal dans un conteneur. Pratique pour explorer, et pour montrer un cluster à quelqu'un qui ne pratique pas la ligne de commande.
Comme pour le tableau de bord de Traefik, l'installation « de lab » n'est pas transposable telle quelle : en production, Rancher demande son propre Ingress, une base de données persistée et une authentification forte, typiquement via OIDC.
Ce que ce lab apprend vraiment
Au bout de la série, on n'a pas seulement « installé Kubernetes ». On a monté un réseau, une passerelle, un DNS, un cluster en quorum, un stockage répliqué, un point d'entrée réseau et un routage HTTP — et surtout on sait pourquoi chaque pièce est là. C'est précisément ce que ne donne pas un cluster managé, où tout cela existe déjà et reste invisible.
La meilleure façon de terminer, c'est encore de casser quelque chose : éteindre un nœud pendant que le wiki est ouvert, regarder les pods se déplacer, les volumes se reconstruire, l'adresse d'entrée basculer. Un lab ne sert pas à démontrer que ça marche : il sert à voir ce qui se passe quand ça ne marche plus.
Le pas à pas détaillé est sur le wiki
Cet article ne remplace pas la documentation : il en explique les choix. L'intégralité de la démarche — commandes, sorties d'écran, vérifications et captures — est publiée sur mon wiki, dans la section Datacenter / Cluster K3S. Pages correspondant à cet article :
- 8. Exemple de déploiement Wiki.js
- 10. Stack de supervision Prometheus / Grafana
- 9. Commandes d'exploitation
- 12. Rancher
La série « Lab Kubernetes maison »
Cet article fait partie d'une série qui monte, pas à pas, un cluster Kubernetes complet sur une seule machine physique :