Tout au long de la formation, vous allez construire, brique par brique, une véritable application distribuée : une application de vote composée de 5 services (deux interfaces web, une file d'attente, un consommateur et une base de données).
Pourquoi cette application ?
navigateur (voter) navigateur (résultats)
│ ▲
▼ │
┌───────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐
│ vote │ ───▶ │ redis │ ───▶ │ worker │ ───▶ │ db │ ───▶ │ result │
│ Flask :80 │ │ :6379 │ │ .NET │ │ Postgres │ │ Node :80 │
└───────────┘ └─────────┘ └──────────┘ │ :5432 │ └────────────┘
└──────────┘
votes de redis ;| Composant | Rôle | Image | Port | À savoir |
|---|---|---|---|---|
| vote | Interface web de vote (Python/Flask) | dockersamples/examplevotingapp_vote:latest |
80 | Les intitulés des boutons sont pilotés par les variables d'environnement OPTION_A et OPTION_B (par défaut « Cats » / « Dogs »). Le pied de page affiche Processed by container ID <hostname> : le load balancing est visible à l'œil nu. |
| redis | File d'attente des votes | redis:8-alpine |
6379 | Les votes s'accumulent dans la liste votes tant que personne ne les consomme. |
| worker | Consommateur (.NET) | dockersamples/examplevotingapp_worker:latest |
aucun | Pur consommateur : il n'aura jamais de Service. Il redémarre 1 à 2 fois tant que redis et db ne sont pas disponibles : c'est normal. |
| db | Base de données (PostgreSQL) | postgres:16-alpine |
5432 | Contient la table votes, créée automatiquement par le worker à la première connexion. |
| result | Interface web des résultats (Node.js) | dockersamples/examplevotingapp_result:latest |
80 | Affiche les pourcentages en temps réel (websockets). L'image fixe PORT=80 |
Deux commandes permettent de suivre un vote à la trace :
1. Le vote attend dans la file redis (tant que le worker n'existe pas) :
kubectl exec deploy/redis -- redis-cli LLEN votes
(integer) 3
2. Le vote est persisté dans PostgreSQL (dès que le worker tourne) :
kubectl exec deploy/db -- psql -U postgres -c 'SELECT vote, COUNT(*) FROM votes GROUP BY vote;'
vote | count
------+-------
a | 52
b | 3
(2 rows)
Dans la file, chaque vote est un petit document JSON : {"voter_id": "...", "vote": "a"} (a = première option, b = seconde). L'interface de vote n'accepte qu'un vote par navigateur (cookie voter_id) : revoter écrase le vote précédent dans la base.
Ces contraintes sont volontairement conservées : elles créent des situations pédagogiques réalistes.
redis et db sont codés en dur dans les applications (vote et worker cherchent l'hôte redis, worker et result cherchent l'hôte db). Vos Services doivent porter exactement ces noms : c'est la leçon centrale du TP 4 sur la Service Discovery.postgres / postgres). Le Secret que vous créerez au TP 6 provisionne donc ces valeurs imposées : le mécanisme est identique avec des identifiants forts, seules les valeurs changent.latest (multi-architecture) pour les images dockersamples/*. C'est une exception assumée à la règle « toujours épingler un tag précis » ; en production, épinglez toujours. Conséquence : les rolling updates « visibles » se font en changeant OPTION_A/OPTION_B, pas en changeant de tag d'image.31000 pour vote, 31001 pour result (et 31002 pour l'environnement de dev du TP 6).| TP | Brique ajoutée | État de l'application |
|---|---|---|
| TP 1 | Pods vote et redis + Service redis (en avant-première) |
On peut voter ; les votes s'accumulent dans la file |
| TP 2 | (observation seule) | L'architecture du cluster vue à travers nos pods |
| TP 3 | Deployments, namespace voting-app, rolling update, Job de génération de votes |
Application résiliente, scalée (3 réplicas de vote), file alimentée |
| TP 4 | Services redis et db, PostgreSQL, worker, NodePort 31000 |
Les votes arrivent en base (encore éphémère) ; load balancing visible |
| TP 5 | PVC puis StatefulSet pour db, application result (31001) | Application complète de bout en bout, données durables |
| TP 6 | ConfigMap voting-options, Secret db-credentials, environnement voting-dev (optionnel) |
Configuration externalisée proprement |
| TP 7 | Probes, HPA, RBAC, Network Policies | Application durcie, prête pour la production |
| TP 8 | Reconstruction complète en voting-prod (+ Gateway API en option) |
Synthèse finale : vous déployez tout, seul, à partir d'une spécification |
Les TP sont conçus pour le Killercoda Kubernetes Playground : un vrai cluster kubeadm à deux nœuds (controlplane + node01).
Les sessions Killercoda sont éphémères (environ 60 minutes) : le cluster est détruit entre deux TP. C'est pourquoi chaque TP (du TP 2 au TP 7) commence par une section « 🚀 Point de départ (Fil Rouge) » : un unique manifeste consolidé qui reconstruit en 2-3 minutes tout ce qui a été bâti dans les TP précédents.
Ce n'est pas une contrainte, c'est une leçon : votre cluster est jetable, vos manifestes sont la source de vérité (Infrastructure as Code). Appliquez le Point de départ dès la première minute du TP : les images se téléchargent pendant que vous faites le premier exercice.
Deux spécificités Killercoda à connaître :
kubectl port-forward doit écouter sur toutes les interfaces pour être joignable depuis le navigateur :kubectl port-forward pod/vote 8080:80 --address 0.0.0.0
8080, 31000, 31001…) pour ouvrir l'application dans un onglet.Enfin, inutile de nettoyer vos objets en fin de TP : la session disparaît d'elle-même. Si vous travaillez sur un cluster durable (Minikube, cluster d'entreprise), supprimez simplement les namespaces voting-app, voting-dev et voting-prod pour tout effacer.