Kubernetes avec Vagrant – Talos & kubeadm

Posted by: Valentin Comments: 0

Kubernetes avec Vagrant – Talos & kubeadm

Il peut être utile de monter rapidement un cluster Kubernetes de laboratoire pour explorer une solution ou faire un POC.
Chez OPS, nous avons répondu à cette question avec deux dépôts jumeaux : Vagrant-kubeadm et Vagrant-Talos.

Deux labs, deux systèmes d’exploitation radicalement opposés — et une couche applicative strictement identique, partagée entre les deux sous la forme d’un sous-module git. Voici comment ils s’articulent.

Deux OS opposés, un plan d’adressage commun

Les deux dépôts font tourner des machines VirtualBox (bientôt dispo pour libvirt/KVM) pilotées par Vagrant, sur le même réseau host-only 192.168.56.0/24, avec la même VIP d’API et le même pool LoadBalancer. Ce qui les sépare, c’est le modèle d’exploitation du système sous-jacent.

Vagrant-kubeadmVagrant-Talos
OS des nodesDebian 13Talos Linux (immuable)
Accès nodevagrant ssh, apt, systemdaucun SSH — API talosctl
Bootstrapkubeadm init / jointalosctl bootstrap
VIP de l’APIkeepalived (VRRP)VIP native Talos
kube-proxyremplaçable en eBPFposé par Talos

Dans les deux cas, la topologie va du control plane unique au HA complet à 3 control planes derrière une VIP, avec le nombre de workers souhaité.

Vagrant-kubeadm — l’installation vanilla

Ce lab n’est délibérément pas un installeur clé en main. Chaque VM est une Debian ordinaire avec SSH et apt ; chaque étape des scripts est une commande kubeadm que l’on pourrait taper soi-même, et la documentation les montre une par une.

Ce que le dépôt apporte, c’est la part ingrate et casse-figure du travail : la VIP qui doit exister avant le kubeadm init, la bonne node-ip , la configuration de containerd 2.x, et les SAN de certificats qu’on ne peut plus ajouter après coup.

git clone --recurse-submodules https://github.com/OPS-NC/Vagrant-kubeadm.git
cd Vagrant-kubeadm
cp lab.env.example lab.env      # choix de la topologie
vagrant up                      # crée et PRÉPARE les VM (pas encore de cluster)
./kubeadm/cluster-up.sh         # kubeadm init + join + kubeconfig
./_k8s/platform-up.sh           # CNI, Envoy Gateway, metrics-server, TLS wildcard

En quelques commandes simples vous avez votre cluster kubeadm proche d’une installation de production disponible.

Vagrant-Talos — l’OS immuable, piloté par API

À l’exact opposé : Talos Linux n’a ni shell, ni SSH, ni gestionnaire de paquets. Le système de fichiers est en lecture seule, et toute la configuration passe par l’API talosctl depuis la machine hôte. Vagrant se contente ici de créer et démarrer les VM, qui bootent sur une ISO en mode maintenance.

git clone --recurse-submodules https://github.com/OPS-NC/Vagrant-Talos.git
cd Vagrant-Talos
vagrant up                      # les VM démarrent en mode maintenance
./talos/cluster-up.sh           # config + bootstrap etcd + kubeconfig + health
export TALOSCONFIG="$PWD/_out/talosconfig" KUBECONFIG="$PWD/kubeconfig"
./_k8s/platform-up.sh

Le contraste pédagogique est le vrai bénéfice de la paire : la même plateforme applicative, déployée sur deux modèles d’exploitation que tout oppose.
On mesure alors très concrètement ce que l’immuabilité coûte et ce qu’elle apporte.

lab.env — une seule source de vérité

Chaque lab se configure par un unique fichier lab.env, copié depuis un modèle versionné et ignoré par git. Il est lu par le Vagrantfile, par le script de bootstrap et par la couche applicative : il n’y a plus rien à « garder aligné à la main » entre les trois étages.

CONTROL_PLANES=3          # 1 = simple, 3 = HA (quorum etcd)
WORKERS=3
CP_MEM=3072
CNI=cilium                # cilium (défaut), calico ou flannel
KUBE_PROXY_REPLACEMENT=true
LAB_DOMAIN=k8s.mon-domaine.tld
SELF_SIGNED=true          # false = Let's Encrypt DNS-01 via Cloudflare

La règle de précédence est constante partout : variable d’environnement réelle > lab.env > défaut. Une surcharge ponctuelle ne demande donc jamais d’éditer le fichier :

WORKERS=1 vagrant up

_k8s/ — la couche applicative, écrite une seule fois

C’est le cœur du dispositif. Tout ce qui vient après le bootstrap — CNI, Gateway API, stockage, bases de données, secrets, observabilité, sécurité, etc.
Ce code vit dans un troisième dépôt, k8s-playground, monté dans chaque lab comme sous-module git sur le chemin _k8s/.

Monté ainsi, il fonctionne sans qu’on lui déclare quoi que ce soit : il remonte au dossier parent, le reconnaît comme lab à son Vagrantfile, et en déduit la distribution. Les divergences entre Talos et Debian sont concentrées dans deux fichiers de profil.

La plateforme de base, en une commande

Un seul script pose le socle, dans l’ordre des dépendances : pas d’IP LoadBalancer sans annonceur L2, pas de HTTPS sans Gateway, pas d’interface web sans certificat.

  1. CNI — Cilium par défaut, avec pool d’IP LoadBalancer et annonce L2 (ARP)
  2. Envoy Gateway — contrôleur + main-gateway avec listeners :80 et :443
  3. metrics-server — l’API metrics.k8s.io (kubectl top, HPA)
  4. TLS wildcard — AC locale auto-signée, ou Let’s Encrypt en DNS-01 Cloudflare

Le catalogue, entièrement opt-in

./_k8s/install.sh list                      # le catalogue complet
./_k8s/install.sh longhorn vault argocd     # ce dont on a besoin
./_k8s/install.sh all                       # tout, dans l'ordre des dépendances

./_k8s/install.sh kubeadm longhorn          # la distribution, explicitement
./_k8s/longhorn/longhorn-up.sh talos        # un composant seul, hors du point d'entrée

La distribution s’écrit en premier argument, talos ou kubeadm, et elle est transmise telle quelle à chaque script de composant. Depuis la racine d’un lab elle est optionnelle : le point d’entrée la déduit de la structure du dépôt parent. La passer reste utile pour lever toute ambiguïté — et c’est elle qui l’emporte sur la détection.

Le catalogue compte aujourd’hui vingt et un composants, répartis en huit familles. La liste ci-dessous est celle du dépôt à l’instant où ces lignes sont écrites ; ./_k8s/install.sh list en donne toujours la version à jour, et all les enchaîne dans l’ordre des dépendances.

🌐 Réseau et TLS

ComposantCe qu’il déploiePrérequis
ciliumCNI par défaut, pool d’IP LoadBalancer et annonce L2 (ARP)
calicoCNI alternatif via l’opérateur Tigera — CNI seul, sans annonce L2
envoy-gatewaycontrôleur Envoy et main-gateway (listeners :80 et :443)via platform
self-signedmode TLS par défaut : wildcard signé par une AC locale (openssl)via platform
cert-managerwildcard TLS automatique, ACME DNS-01 Cloudflarevia platform si SELF_SIGNED=false

💾 Stockage

ComposantCe qu’il déploiePrérequis
longhornstockage bloc répliqué — prérequis iSCSI différent selon la distroSC longhorn, longhorn-r1
local-pathstockage local dynamique (hostPath) — chemin différent selon la distroSC local-path
minioMinIO standalone : S3 et console, 1 nœud
minio-clusterMinIO distribué 4 nœuds (EC:2) — la cible des sauvegardes

🐘 Bases de données

ComposantCe qu’il déploiePrérequis
cnpgCloudNativePG : opérateur PostgreSQL HA, cluster 3 nœuds, bascule automatique, sauvegardes S3 et PITRSC longhorn-r1

🪪 Identité

ComposantCe qu’il déploiePrérequis
keycloakKeycloak déployé par son opérateur, realm lab déclaré, émetteur OIDC sur keycloak.<LAB_DOMAIN>cnpg
dexDex devant Keycloak : connexion kubectl en OIDC (oidc-login), droits pilotés par un groupekeycloak

🔐 Secrets

ComposantCe qu’il déploiePrérequis
vaultHashiCorp Vault HA (Raft), 3 nœuds, UI et API en HTTPSSC longhorn
vsoVault Secrets Operator : secrets Vault projetés en Secret Kubernetes natifs (KV statique, base dynamique, PKI)Vault descellé

📈 Observabilité

ComposantCe qu’il déploiePrérequis
observabilitykube-prometheus-stack (Prometheus, Grafana, Alertmanager) avec Loki et AlloySC longhorn-r1, CP ≥ 4 Go
npdnode-problem-detector : santé des nodes remontée depuis le noyau
chaoschaoskube : supprime un pod au hasard, toutes les heures

🛡️ Sécurité

ComposantCe qu’il déploiePrérequis
kyvernomoteur de policies et Policy Reporter (UI) — policies pédagogiques livrées en mode Auditmain-gateway
trivyTrivy Operator : scan continu des CVE, de la configuration, des secrets et du RBACkyverno (UI partagée)

🧪 Démonstrations

ComposantCe qu’il déploiePrérequis
argocdArgo CD (GitOps), UI HTTPS sur argo.<LAB_DOMAIN>
wordpress-exampleWordPress et MariaDB sur Longhorn, exposés par Envoykubectl apply, cf. README

Chaque composant reste lançable seul, et chaque dossier embarque un parcours guidé : la même installation, commande par commande, avec ce qu’il faut observer à chaque étape. Le script tout-en-un et le parcours font exactement la même chose — l’un pour aller vite, l’autre pour comprendre.

Petit bonus, si vous utilisez Tailscale, un simple tailscale up --advertise-routes '192.168.56.0/24' vous permettra de contacter votre API k8s et votre Envoy-gateway depuis n’importe quelle machine de votre Tailnet.

Pour aller voir

Les trois dépôts sont publics, sous licence libre, et documentés en anglais comme en français.

Toutes les versions de charts sont épinglées et surchargeables par variable d’environnement.

Un seul avertissement pratique : --recurse-submodules n’est pas optionnel.

Un git clone ordinaire laisse le dossier _k8s/ vide.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *