Kilo + WireGuard méta-cloud Kubernetes (mesh WireGuard chiffré multi-cloud)

Kilo + WireGuard : construire un méta-cloud Kubernetes souverain

Comment un overlay réseau minimaliste basé sur WireGuard transforme des clusters Kubernetes éparpillés sur plusieurs clouds et datacenters en un seul plan de données unifié avec chiffrement bout-en-bout, tolérance aux NAT, et reprise d'activité multi-régions.

WireGuard le moteur cryptographique sous le capot

Avant de comprendre Kilo, il faut maîtriser ce qui le propulse : WireGuard. Introduit dans le kernel Linux 5.6 (mars 2020), WireGuard est un VPN de nouvelle génération qui rompt avec l'approche lourde d'OpenVPN ou IPSec. Son code source tient en moins de 4 000 lignes auditables, lisibles, vérifiables.

Discret, WireGuard est pourtant devenu une brique fondamentale de l'écosystème réseau open source : il propulse des projets aussi variés que Tailscale, Netbird, Cloudflare WARP, Cilium ou Kilo lui-même souvent sans que le grand public, ni même beaucoup d'ingénieurs, ne le réalisent. C'est l'infrastructure invisible derrière une large part du VPN et du mesh modernes.

<4K
lignes de code dans le kernel
ChaCha20
chiffrement symétrique + Poly1305 MAC
Curve25519
échange de clés Diffie-Hellman
UDP
transport exclusif port 51820 par défaut

Cryptographie moderne, surface d'attaque minimale

WireGuard utilise une suite cryptographique fixe et moderne : Noise Protocol Framework pour le handshake, Curve25519 pour l'échange ECDH, ChaCha20-Poly1305 pour le chiffrement authentifié des données, BLAKE2s pour les hachages et SipHash24 pour les tables de hachage. Pas de négociation d'algorithmes, pas de choix dangereux à la configuration.

Principe clé Roaming silencieux WireGuard garde en mémoire le dernier endpoint valide ayant envoyé un paquet authentifié. Un pair peut changer d'IP (4G → WiFi, NAT rebind) sans interruption de session. Kilo exploite ce mécanisme pour maintenir le mesh même derrière des NAT dynamiques.

Modèle de fonctionnement

Chaque nœud WireGuard possède une paire de clés (Curve25519). La clé publique est l'identité du pair. La configuration définit les AllowedIPs de chaque pair WireGuard se comporte alors comme une table de routage cryptographique : tout paquet sortant dont la destination correspond aux AllowedIPs d'une pair est automatiquement chiffré et envoyé à son endpoint.

# Interface locale du nœud
[Interface]
PrivateKey = eJ4bKpA7tRzCnMqL...
Address    = 10.5.0.1/24
ListenPort = 51820

# Pair distant (autre datacenter)
[Peer]
PublicKey           = IgDTEvasUvxisSAmfBKh8...
AllowedIPs          = 10.5.1.0/24, 10.2.4.0/24
Endpoint            = 34.120.45.12:51820
PersistentKeepalive = 25

La beauté du modèle : WireGuard est stateless du point de vue de l'application. Il n'y a pas de session TCP à maintenir, pas de renégociation périodique visible juste des paquets UDP chiffrés avec rotation automatique des clés de session toutes les 3 minutes (key rotation silencieuse).

Kilo Anatomie du projet k8s + wg = kg

Kilo (GitHub : squat/kilo) est un overlay réseau multi-cloud pour Kubernetes basé sur WireGuard. Son équation est simple : k8s + wg = kg. Il connecte des nœuds répartis sur plusieurs clouds ou datacenters au sein d'un seul et même cluster Kubernetes, en fournissant un réseau Layer 3 chiffré qui traverse NAT, pare-feux et frontières réseau.

Ce que Kilo n'est pas Kilo n'est pas un CNI complet au sens de Flannel ou Calico. Il peut fonctionner en mode add-on par-dessus un CNI existant : il prend en charge le trafic entre locations, et laisse le CNI existant gérer le trafic intra-location. C'est sa force : pas de migration, ajout chirurgical.

L'agent kg un DaemonSet qui gère tout

Le cœur de Kilo est l'agent kg, déployé comme DaemonSet sur chaque nœud. À son démarrage, il :

  1. Génère la paire de clés WireGuard du nœud Clé privée stockée localement, clé publique publiée comme annotation sur l'objet Node Kubernetes.
  2. Détecte la location du nœud Via le label standard topology.kubernetes.io/region ou l'annotation kilo.squat.ai/location. Les nœuds du même datacenter forment un segment.
  3. Élit un leader par segment Un nœud par location devient le gateway WireGuard vers les autres locations. Les autres nœuds du segment communiquent via le réseau interne (non chiffré, car intra-datacenter).
  4. Configure l'interface WireGuard locale Crée l'interface kilo0, configure les peers, injecte les routes ip route et règles iptables nécessaires.
  5. Surveille l'état du cluster en continu Via le watch Kubernetes API. Tout changement (nœud ajouté, IP modifiée, leader élu) déclenche une réconciliation automatique de la configuration WireGuard.

Les CRDs Kilo

Kilo introduit un CRD : peers.kilo.squat.ai. Il représente une paire WireGuard externe au cluster un développeur, un agent de monitoring, un autre cluster. Cela permet d'intégrer des entités non-Kubernetes dans le mesh chiffré.

apiVersion: kilo.squat.ai/v1alpha1
kind: Peer
metadata:
  name: admin-workstation
spec:
  allowedIPs:
    - 10.5.100.2/32
  publicKey: AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AAAA=
  persistentKeepalive: 10

L'outil CLI kgctl

Kilo fournit kgctl, un binaire (Linux/macOS/Windows) pour inspecter le mesh. La commande graph génère une représentation Graphviz de la topologie. La commande showconf exporte la configuration WireGuard d'un nœud ou pair utile pour l'onboarding de nouveaux pairs externes.

# Voir la topologie du mesh en Graphviz
kgctl graph | dot -Tsvg > mesh-topology.svg

# Exporter la config WireGuard d'un nœud
kgctl showconf node master-eu-west

# Exporter la config pour un peer externe
kgctl showconf peer admin-workstation

Le Méta-Cloud Un cluster Kubernetes qui transcende les clouds

Le scénario le plus puissant de Kilo est la construction d'un méta-cloud : un cluster Kubernetes unique dont les nœuds sont physiquement répartis sur plusieurs clouds (Scaleway, AWS, GCP, Azure) ou datacenters privés. Pour Kubernetes, tous ces nœuds semblent être sur le même réseau plat.

Le problème résolu Sans Kilo, un nœud sur Scaleway Paris ne peut pas atteindre directement le Pod d'un nœud sur AWS Frankfurt. Le réseau Pod CIDR de chaque cloud est isolé. Kilo crée le pont chiffré entre ces îles réseau.

Architecture d'un méta-cloud à 3 providers

Méta-Cloud Vue logique du plan données

Architecture d'un méta-cloud Kubernetes à 3 providers (Scaleway, AWS, On-Premise) reliés par WireGuard Full Mesh via Kilo

Mise en place des annotations des nœuds par location

# Annoter les nœuds Scaleway
for node in $(kubectl get nodes | grep scw | awk '{print $1}'); do
  kubectl annotate node $node kilo.squat.ai/location="scaleway-paris"
done

# Annoter les nœuds AWS
for node in $(kubectl get nodes | grep aws | awk '{print $1}'); do
  kubectl annotate node $node kilo.squat.ai/location="aws-euwest3"
done

# Annoter les nœuds on-premise
for node in $(kubectl get nodes | grep dc | awk '{print $1}'); do
  kubectl annotate node $node kilo.squat.ai/location="lyon-dc"
done

Cas d'usage concrets du méta-cloud

🎯
Workload placement stratégique
Scheduler Kubernetes place les GPU-intensive workloads sur AWS, les workloads réglementés sur l'on-premise, les edge sur Scaleway — un seul cluster, un seul pipeline GitOps.
💰
Optimisation coût / performance
Utiliser les spot instances AWS pour les jobs batch tout en gardant les services critiques sur infra dédiée, avec visibilité unifiée dans un seul plan de contrôle.
🔒
Souveraineté des données
Les données sensibles restent sur les nœuds on-premise français (RGPD), les traitements non sensibles bursting sur cloud public — routing Kubernetes via NodeAffinity et Taints.
Capacité élastique
Scale-out immédiat en cloud public lors des pics de charge, sans reconfiguration réseau. Le méta-cloud s'étend automatiquement à l'ajout de nouveaux nœuds.
🔁
Reprise d'activité intégrée
Production et secours partagent le même plan de données chiffré. Le tunnel WireGuard reste pré-établi en permanence : aucune reconfiguration réseau au moment du sinistre, et un RTO fortement réduit.

Reprise d'Activité DR avec Kilo comme fabric réseau

La reprise d'activité (Disaster Recovery) pour Kubernetes est historiquement complexe : synchronisation etcd, réplication des PersistentVolumes, basculement DNS, re-routage réseau. Kilo simplifie radicalement la couche réseau du DR en garantissant que les clusters de production et de reprise partagent le même plan de données chiffré.

Architecture DR active-passive avec Kilo

Topologie Kilo en mode DR : cluster Production Scaleway PAR-1 et cluster DR OVHcloud SBG reliés par un mesh WireGuard chiffré, avec réplication continue

Connexion inter-clusters via Kilo Peers

La clé du DR avec Kilo est d'utiliser les Kilo Peers pour connecter deux clusters distincts. Le cluster DR est déclaré comme pair WireGuard du cluster primaire. Les Pod CIDRs doivent être non-overlapping.

# Sur le cluster PRODUCTION déclarer le cluster DR comme peer
apiVersion: kilo.squat.ai/v1alpha1
kind: Peer
metadata:
  name: cluster-dr-ovhcloud
spec:
  allowedIPs:
    - 10.11.0.0/16    # Pod CIDR du cluster DR
    - 10.21.0.0/16    # Service CIDR du cluster DR
  publicKey: DrClusterPublicKeyBase64==
  endpoint: dr-gateway.example.com:51820
  persistentKeepalive: 25

Scénario de basculement

  1. Détection de panne (via Prometheus + AlertManager) Perte de heartbeat sur les nœuds production. Alerte critique déclenchée, runbook DR initié (manuel ou automatique via Temporal/Argo Workflows).
  2. Le réseau DR est déjà opérationnel Grâce à Kilo, le tunnel WireGuard entre les deux clusters tourne en permanence avec PersistentKeepalive. Pas de reconfiguration réseau à la bascule.
  3. Promotion du cluster DR ArgoCD sur le cluster DR déploie la dernière version des Applications (sync depuis le même repo Git). Velero restaure les PVs depuis le backup S3.
  4. Basculement DNS Mise à jour des enregistrements DNS (TTL court pré-configuré) vers les IPs du cluster DR. External-DNS + cert-manager re-provisionnent automatiquement.
  5. RTO atteint trafic sur le cluster DR L'ensemble des services critiques est opérationnel sur le cluster DR. Le cluster primaire peut être reconstruit sans urgence.
Avantage clé Le réseau Kilo étant maintenu actif en permanence, le DR ne nécessite aucune phase de "mise en place réseau" au moment du sinistre. C'est un avantage décisif sur le RTO par rapport aux approches où le VPN est provisionné à la demande.

Cloud Souverain Hybride On-Premise + Cloud Public

Pour les organisations soumises à des réglementations strictes (HDS, SecNumCloud, RGPD, NIS2), Kilo permet de construire un cloud hybride souverain : les données et traitements sensibles restent sur infrastructure maîtrisée (on-premise, colocation française), tandis que les charges non sensibles peuvent s'exécuter sur cloud public le tout géré par un seul control-plane Kubernetes.

Hybrid Sovereign Cloud Isolation par Taint + Location Kilo

Cloud souverain hybride : un seul cluster Kubernetes répartit les workloads sur 3 zones de souveraineté (ROUGE on-premise FR, ORANGE colocation EU, VERTE cloud public) via les Taints, reliées par le mesh WireGuard chiffré de Kilo

# Déploiement d'un service sensible forcé sur Zone ROUGE
apiVersion: apps/v1
kind: Deployment
metadata:
  name: patient-data-service
spec:
  template:
    spec:
      nodeSelector:
        kilo.squat.ai/location: "on-premise-fr"
      tolerations:
        - key: "sovereignty"
          value: "fr"
          effect: "NoSchedule"
      containers:
        - name: app
          image: registry.internal/patient-data:v2.1.0

Accès VPN sécurisé aux Pods Pour les développeurs et SRE

Kilo permet à des entités externes au cluster de rejoindre le mesh WireGuard comme pairs. Un développeur peut ainsi accéder directement aux Pods, Services et même au DNS cluster (cluster.local) depuis son poste sans exposer de NodePort ou d'Ingress. C'est le "zéro-trust developer access" natif Kubernetes.

# 1. Créer la paire de clés WireGuard sur le poste dev
wg genkey | tee dev-private.key | wg pubkey > dev-public.key

# 2. Déclarer le développeur comme Peer Kilo
cat <<EOF | kubectl apply -f -
apiVersion: kilo.squat.ai/v1alpha1
kind: Peer
metadata:
  name: seb-laptop
spec:
  allowedIPs:
    - 10.5.100.10/32
  publicKey: $(cat dev-public.key)
  persistentKeepalive: 25
EOF

# 3. Récupérer la config WireGuard pour le poste
kgctl showconf peer seb-laptop > /etc/wireguard/wg-cluster.conf
wg-quick up wg-cluster

# 4. Résoudre les noms DNS cluster depuis le poste
resolvectl dns wg-cluster 10.96.0.10   # CoreDNS svc IP
resolvectl domain wg-cluster cluster.local

# Accès direct aux pods !
curl http://my-service.default.svc.cluster.local
Cas d'usage SRE Un ingénieur de permanence peut déboguer directement un Pod en production depuis son poste, sans kubectl port-forward ni bastion SSH. Kilo + WireGuard fournit un accès réseau direct, chiffré, révocable instantanément (suppression du CRD Peer).

Services Multi-Cluster Consommation cross-cluster privée

Au-delà du cluster unique multi-location, Kilo supporte les multi-cluster services : des services exposés par un cluster Kubernetes consommés de manière privée par un autre cluster. Sans Kilo, cela nécessite un Ingress exposé publiquement ou un VPN custom. Avec Kilo, c'est une déclaration de Peer + un Service Kubernetes pointant vers les IPs du cluster distant.

Multi-Cluster Services GPU Cluster → App Cluster

Services multi-cluster privés avec Kilo : un app-pod du cluster APP (Scaleway) appelle un service d'inférence ML (ml-inference-svc) hébergé sur le cluster GPU (AWS p3.8xlarge) à travers le mesh WireGuard chiffré, sans exposition Internet ni Ingress

# Sur le cluster APP — créer un service pointant vers le cluster GPU
apiVersion: v1
kind: Service
metadata:
  name: ml-inference-svc
spec:
  ports:
    - port: 8080
---
apiVersion: v1
kind: Endpoints
metadata:
  name: ml-inference-svc
subsets:
  - addresses:
      - ip: 10.11.42.5   # Pod IP sur cluster GPU
    ports:
      - port: 8080

Déploiement pas-à-pas

Prérequis

Kilo requiert le module kernel WireGuard sur tous les nœuds. Depuis Linux 5.6, WireGuard est intégré au kernel. Pour les distributions plus anciennes, installation via le package manager. Le port UDP 51820 doit être ouvert entre les leaders de chaque location.

# Vérifier la présence du module WireGuard
lsmod | grep wireguard
# ou depuis kernel 5.6+ :
modinfo wireguard

# Ubuntu 20.04+ (kernel < 5.6)
apt-get install -y wireguard wireguard-tools

# Vérification du port 51820 (sur chaque nœud leader)
ufw allow 51820/udp

Installation de Kilo

Kilo propose des manifests préconfigurés pour les principales distributions Kubernetes. Le choix du manifest dépend du CNI déjà en place.

# Installer les CRDs Kilo
kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/crds.yaml

# Installation sur un cluster Kubeadm + Flannel
kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/kilo-kubeadm-flannel.yaml

# Installation sur K3s
kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/kilo-k3s.yaml

# Vérifier que les pods kg sont Running sur chaque nœud
kubectl -n kube-system get pods -l app.kubernetes.io/name=kilo -o wide

Configurer un leader dédié par location

Par défaut, Kilo élit un leader automatiquement. Il est possible de forcer le choix via l'annotation kilo.squat.ai/force-endpoint utile pour s'assurer que le nœud avec l'IP publique est bien le gateway.

# Forcer un nœud spécifique comme gateway Kilo pour sa location
kubectl annotate node node-scw-1 \
  kilo.squat.ai/force-endpoint="195.154.XX.XX:51820"

# Visualiser la topologie du mesh
kgctl graph | dot -Tpng -o mesh.png

# Vérifier la configuration WireGuard générée sur un nœud
kubectl -n kube-system exec ds/kilo -- wg show

Support des nœuds sans module kernel (userspace)

Pour les clusters avec des nœuds où le module kernel WireGuard ne peut pas être installé (OS immuables, contraintes sécurité), Kilo supporte une implémentation userspace via BoringTun.

# Installation hétérogène : kernel WireGuard + BoringTun (userspace)
kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/kilo-k3s-userspace-heterogeneous.yaml

# nkml détecte automatiquement la présence du module kernel
# et label chaque nœud en conséquence

Alternatives et positionnement

Kilo n'est pas le seul outil dans l'espace des overlays réseau multi-cloud pour Kubernetes. Voici comment il se positionne face aux alternatives les plus courantes :

Solution Protocole Multi-Cloud Multi-Cluster NAT Traversal Complexité
Kilo WireGuard ✓ natif ✓ via Peers Faible
Cilium ClusterMesh eBPF + WireGuard ✓ natif Moyenne
Submariner IPSec / WireGuard ✓ dédié Élevée
Tailscale Operator WireGuard ✗ limité Très faible
Istio Multi-Primary mTLS ✓ L7 Très élevée
Flannel natif VXLAN Très faible

Quand choisir Kilo ?

Kilo est idéal si…
Vous voulez relier des nœuds sur plusieurs clouds dans un cluster unique, avec le minimum de complexité opérationnelle. Kilo s'installe en quelques minutes sur n'importe quel cluster existant.
🤔
Préférer Cilium ClusterMesh si…
Vous avez déjà Cilium comme CNI et souhaitez une intégration native L7 avec GlobalServices, DNS failover automatique, et NetworkPolicies cross-cluster.
🔬
Préférer Submariner si…
Vous gérez plusieurs clusters Kubernetes *indépendants* (pas un seul cluster multi-location) et souhaitez une solution dédiée aux services cross-cluster avec broker centralisé.
Combinaison puissante pour la production Kilo + Flannel (ou Kilo + Calico) pour le réseau, Istio pour le service mesh L7, ArgoCD pour le GitOps, et Velero pour les backups constituent une stack complète et souveraine pour un méta-cloud de production. Kilo prend en charge la couche L3 multi-site ; Istio prend en charge la couche L7 intra-cluster.

Limitations à connaître

Kilo est un projet communautaire maintenu activement mais dont la surface fonctionnelle est volontairement restreinte. Il ne gère pas nativement le failover de route (si le leader d'une location tombe, l'élection d'un nouveau leader prend quelques secondes). Pour les cas d'usage nécessitant un BGP ou une gestion fine des politiques réseau L7, il faudra le combiner avec d'autres outils. Enfin, le projet ne prend pas en charge IPv6 dual-stack en dehors de configurations explicites.

Kilo Une brique fondamentale du méta-cloud souverain

Kilo illustre parfaitement la philosophie cloud-native : faire une seule chose, la faire bien, et s'intégrer dans l'écosystème existant sans friction. En s'appuyant sur WireGuard cryptographiquement moderne, kernel-native, NAT-traversant Kilo résout un problème fondamental : comment faire parler des nœuds Kubernetes répartis sur la planète comme s'ils étaient dans le même rack ?

Pour un architecte qui construit une plateforme SaaS souveraine ou multi-tenant, Kilo est la couche réseau qui permet de combiner librement les régions et les providers, d'implémenter un plan de reprise d'activité sans friction réseau, d'ouvrir un accès développeur sécurisé et révocable, et de fédérer des services entre clusters sans les exposer sur Internet.

Ce qu'il faut retenir k8s + wg = kg. Un méta-cloud commence par une couche réseau chiffrée, globale, et Kubernetes-native. Kilo est cette couche. Le reste — workload placement, GitOps, service mesh, observabilité peut s'empiler dessus sans friction.

Ressources

Ressource URL
GitHub — squat/kilo github.com/squat/kilo
Documentation officielle kilo.squat.ai/docs
WireGuard — site officiel wireguard.com
KubeCon EU 2019 — Talk Kilo YouTube : "Kilo: Multi-Cloud Kubernetes"
Userspace WireGuard (BoringTun) github.com/cloudflare/boringtun

Sébastien Pincemail

Je suis passionné par les infrastructures cloud, l'open source et les plateformes distribuées. Au cours de ma carrière, j'ai occupé plusieurs rôles, de DBA à architecte DevOps, en passant par le cloud engineering et l'automatisation. Aujourd'hui, j'accompagne les organisations dans la conception de plateformes ouvertes, souveraines et durables, du cloud privé aux hyperscalers.