Un cluster Kubernetes tout juste installé laisse par défaut tous les pods se parler entre eux, sans aucune restriction. Un attaquant qui compromet un seul microservice via une dépendance vérolée peut donc, en théorie, atteindre n’importe quel autre pod du cluster, y compris la base de données ou les secrets applicatifs. C’est exactement ce que corrige la microsegmentation réseau : cloisonner chaque service pour qu’il ne parle qu’à ce dont il a réellement besoin.
En 2026, ce chantier n’est plus optionnel en Europe. La directive NIS2 et le règlement DORA poussent les DSI à documenter et prouver la segmentation de leurs environnements critiques, cloud compris. Ce tutoriel vous montre comment déployer une microsegmentation Zero Trust sur Kubernetes avec Cilium et Calico, les deux CNI (Container Network Interface) les plus utilisés pour ce cas d’usage, du premier kubectl apply jusqu’à l’intégration dans votre pipeline CI/CD. Comptez environ 60 minutes pour suivre l’ensemble des 11 étapes sur un cluster de test.
Ce guide s’adresse aux équipes SRE, plateforme et sécurité qui gèrent déjà un cluster Kubernetes en production ou en préproduction, avec des connaissances de base en YAML et en kubectl. Vous n’avez pas besoin d’être expert eBPF pour suivre les étapes : chaque commande est expliquée et chaque manifeste est commenté pour que vous puissiez l’adapter à votre propre topologie de services.
Pourquoi la microsegmentation Kubernetes devient incontournable en 2026
Un cluster Kubernetes sans Network Policy fonctionne en mode “tout ouvert” : chaque pod peut initier une connexion vers n’importe quel autre pod, quel que soit le namespace. Ce comportement, hérité des débuts de Kubernetes où la priorité allait à la simplicité de déploiement, pose un problème de sécurité de fond dès que le cluster héberge plusieurs équipes ou plusieurs niveaux de sensibilité de données.
La microsegmentation consiste à appliquer le principe du moindre privilège au réseau : chaque service ne peut communiquer qu’avec les services qu’il est censé appeler, dans les deux sens (entrant et sortant). C’est la traduction concrète du modèle Zero Trust au niveau réseau Kubernetes : on ne fait confiance à aucun flux par défaut, on autorise explicitement ce qui est légitime.
Cette approche limite fortement les mouvements latéraux en cas de compromission. Si un attaquant obtient un accès à un pod frontend via une faille applicative, une politique réseau bien construite l’empêche d’atteindre directement la base de données ou les services d’administration internes. C’est également un point de contrôle que les auditeurs recherchent de plus en plus, notamment dans le cadre de la mise en conformité NIS2 pour les entités essentielles et importantes en France et dans l’Union européenne.
Sur le plan technique, deux projets dominent ce terrain en 2026 : Cilium, porté par eBPF et adopté par Google, AWS et de nombreux fournisseurs de Kubernetes managé, et Calico, historiquement très implanté en entreprise pour ses politiques réseau avancées. Ce tutoriel couvre les deux, avec un focus pratique sur Cilium pour le fil conducteur des 11 étapes.
Le coût d’un mouvement latéral non maîtrisé se mesure aussi en temps de détection. Sans segmentation, un attaquant qui a pris pied sur un pod peu sensible peut scanner silencieusement le reste du cluster pendant des jours avant qu’une alerte ne se déclenche, faute de journal de connexions bloquées à examiner. Avec une politique default-deny couplée à l’observabilité Hubble, chaque tentative de connexion hors périmètre autorisé génère un événement DROPPED immédiatement visible, ce qui raccourcit mécaniquement le temps de détection d’une intrusion en cours.
Les Network Policies Kubernetes : les fondamentaux
Avant de manipuler Cilium ou Calico, il faut comprendre le modèle natif de Kubernetes. Une NetworkPolicy est une ressource qui cible un ensemble de pods via un podSelector, puis définit des règles ingress (trafic entrant) et egress (trafic sortant) autorisées vers ou depuis ce groupe de pods.
Le point le plus mal compris par les équipes qui débutent : le modèle est additif, jamais restrictif par défaut. Tant qu’aucune NetworkPolicy ne cible un pod, ce pod reste totalement ouvert. Dès qu’une politique le cible pour l’ingress, seul le trafic explicitement autorisé passe, tout le reste est rejeté. C’est ce comportement qui permet de construire un modèle “default deny” : on crée une politique qui cible tous les pods d’un namespace sans autoriser aucun flux, puis on ajoute des règles d’exception une par une.
Trois éléments structurent chaque politique :
- podSelector : quels pods sont concernés par la règle (via des labels)
- policyTypes : Ingress, Egress, ou les deux
- from / to : les sources ou destinations autorisées, via podSelector, namespaceSelector ou ipBlock (plages CIDR)
Le CNI standard de Kubernetes ne suffit pas toujours : Flannel, par exemple, n’applique pas les NetworkPolicy du tout. C’est pour cela que le choix du CNI est la première décision technique à prendre avant de se lancer dans la microsegmentation.
Un autre piège de vocabulaire mérite d’être clarifié tout de suite : un namespaceSelector vide ({}) cible tous les namespaces du cluster, tandis qu’un podSelector vide au sein d’un bloc from ou to cible tous les pods du namespace concerné. Combiner les deux dans une seule règle revient donc à autoriser littéralement tout le trafic entrant, ce qui annule l’effet recherché. Relisez toujours vos manifestes en vous demandant “quel est le sous-ensemble réel de pods concerné” avant de les appliquer.
Cilium vs Calico : quel CNI choisir pour le Zero Trust
Cilium s’appuie sur eBPF pour appliquer les politiques réseau directement dans le noyau Linux, sans passer par iptables. Cette architecture réduit la latence et permet des fonctionnalités que le modèle NetworkPolicy standard n’offre pas : règles au niveau L7 (HTTP, gRPC, Kafka), chiffrement transparent des flux (WireGuard ou IPsec), et observabilité fine via Hubble, son module de visualisation des flux.
Calico, de son côté, reste une valeur sûre côté entreprise. Son CRD GlobalNetworkPolicy permet de définir des règles qui s’appliquent à l’ensemble du cluster sans devoir dupliquer une NetworkPolicy dans chaque namespace, un gain de temps réel en environnement multi-équipes. Calico propose aussi des logs de flux exploitables pour l’audit, un point apprécié des équipes conformité.
En pratique, les deux projets savent appliquer les NetworkPolicy Kubernetes natives. La différence se joue sur les besoins avancés : si vous visez du filtrage applicatif (L7) et du chiffrement de bout en bout, Cilium a l’avantage grâce à eBPF. Si votre priorité est la gestion centralisée de politiques à l’échelle d’un grand cluster multi-tenant avec des outils d’audit matures, Calico reste très compétitif.
Sachez aussi que Calico existe en deux déclinaisons : la version open source (Calico OSS), suffisante pour appliquer les GlobalNetworkPolicy présentées dans ce tutoriel, et une offre Calico Enterprise portée par Tigera, qui ajoute un tableau de bord graphique, des recommandations de politiques générées automatiquement et un moteur de conformité prêt à l’emploi. Pour un premier déploiement de microsegmentation, la version OSS couvre déjà largement les besoins décrits ici. Migrer vers l’offre payante ne devient pertinent que lorsque le nombre de politiques à gérer dépasse ce qu’une équipe peut maintenir à la main en YAML brut.
| Critère | Cilium | Calico |
|---|---|---|
| Moteur réseau | eBPF (noyau Linux) | iptables / eBPF (mode optionnel) |
| NetworkPolicy native K8s | Oui | Oui |
| Filtrage L7 (HTTP, gRPC, Kafka) | Oui (CiliumNetworkPolicy) | Limité |
| Politiques cluster-wide | CiliumClusterwideNetworkPolicy | GlobalNetworkPolicy |
| Observabilité intégrée | Hubble (flux en temps réel) | Calico Flow Logs |
| Chiffrement inter-pods | WireGuard / IPsec natif | WireGuard (add-on) |
| Version stable (août 2026) | 1.20.1 | Dernière branche stable Tigera Calico |
La documentation officielle de Cilium 1.20.1 détaille l’ensemble des mécanismes d’import de politiques, en CLI comme via l’API Kubernetes. Une branche de développement, 1.21.0-dev, introduit un support préliminaire pour k8sClusterNetworkPolicy, activable via le flag --enable-k8s-cluster-network-policy=true. Cette branche n’est pas destinée à la production : gardez Cilium 1.20.x pour un déploiement stable.
Prérequis : outils et versions pour ce tutoriel
Ce tutoriel part du principe que vous disposez déjà d’un cluster Kubernetes fonctionnel, en local ou dans le cloud. Si ce n’est pas le cas, notre guide Minikube en 12 étapes vous permet de monter un cluster de test en une demi-heure. Vérifiez les versions suivantes avant de démarrer :
| Outil | Version utilisée dans ce guide | Rôle |
|---|---|---|
| Kubernetes | 1.30 ou supérieur | Cluster cible (local ou managé) |
| Cilium | 1.20.1 (stable) | CNI et moteur de politiques eBPF |
| Helm | 3.x | Installation de Cilium |
| cilium-cli | Dernière version | Diagnostic et statut du CNI |
| Hubble CLI | Dernière version | Observation des flux réseau |
| kubectl | Compatible avec votre version de cluster | Application des manifestes |
| calicoctl | Dernière version (si vous testez Calico) | Gestion des GlobalNetworkPolicy |
Un accès administrateur au cluster est nécessaire pour installer un CNI. Sur un cluster managé (EKS, AKS, GKE), vérifiez au préalable que le CNI par défaut peut être remplacé par Cilium sans perturber les nœuds existants : chaque fournisseur documente sa procédure de migration. Sur un cluster de test local, partez d’une base propre pour éviter les conflits entre deux CNI actifs.
Prévoyez également la capacité machine nécessaire à l’agent Cilium lui-même : comptez environ 100 à 200 Mo de RAM et un cœur CPU partagé par nœud pour le DaemonSet Cilium en fonctionnement standard, un peu plus si vous activez le chiffrement WireGuard ou le filtrage L7 sur un volume de trafic important. Sur un cluster de test à trois nœuds, ces besoins restent négligeables face aux ressources déjà allouées à vos workloads applicatifs.
Étapes 1 à 3 : préparer le cluster et observer les flux
Étape 1 : Installer Cilium avec Helm
Ajoutez le dépôt Helm officiel puis déployez Cilium 1.20.1 sur votre cluster :
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium \
--version 1.20.1 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true
Une fois le déploiement lancé, vérifiez l’état des pods Cilium avec le CLI dédié :
cilium status --wait
Sortie attendue une fois l’installation terminée :
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: OK
\__/¯¯\__/ Hubble Relay: OK
\__/ ClusterMesh: disabled
Deployment cilium-operator Desired: 2, Ready: 2/2
DaemonSet cilium Desired: 3, Ready: 3/3
Containers: cilium Running: 3
cilium-operator Running: 2
Cluster Pods: 12/12 managed by Cilium
Si les pods restent en CrashLoopBackOff, direction la section dépannage plus bas : c’est le symptôme le plus courant à ce stade, généralement lié à la version du noyau Linux.
Étape 2 : Activer Hubble pour l’observabilité
Hubble a déjà été activé dans la commande Helm ci-dessus. Exposez son interface pour visualiser les flux réseau en temps réel :
cilium hubble port-forward &
hubble status
hubble observe --namespace production --follow
Cette commande affiche en continu chaque connexion établie entre vos pods : source, destination, port, verdict (FORWARDED ou DROPPED). C’est l’outil qui va vous servir à l’étape suivante pour cartographier les dépendances réelles de vos services, plutôt que de deviner leurs communications à partir de la documentation applicative, souvent incomplète ou obsolète.
Étape 3 : Cartographier les flux existants avant de sévir
C’est l’étape la plus souvent sautée, et celle qui cause le plus d’incidents en production. Avant d’appliquer la moindre restriction, laissez Hubble collecter les flux pendant 7 à 14 jours sur un environnement représentatif du trafic réel (pics de charge, jobs batch nocturnes, synchronisations périodiques inclus). Exportez les résultats pour construire un graphe de dépendances :
hubble observe --namespace production \
--since 168h \
--output json > flux-production.json
Ce fichier devient votre référence pour écrire les règles d’autorisation aux étapes suivantes. Sans cette cartographie, le risque de casser un flux légitime (un job de sauvegarde mensuel, par exemple) est élevé, et il ne se révèle souvent qu’au pire moment.
Un script simple permet de transformer ce JSON en une liste de paires source/destination uniques, plus facile à relire qu’un flux brut de milliers de lignes :
cat flux-production.json | jq -r '[.source.pod_name, .destination.pod_name, .destination_port] | @tsv' \
| sort -u > dependances-uniques.tsv
Le fichier dependances-uniques.tsv obtenu sert directement de base de travail pour rédiger vos NetworkPolicy aux étapes 7 et suivantes : chaque ligne devient potentiellement une règle d’autorisation explicite.
Étapes 4 à 6 : construire la politique default-deny
Étape 4 : Appliquer un default-deny par namespace
La base de toute microsegmentation Zero Trust : une politique qui cible tous les pods d’un namespace sans autoriser aucun flux entrant ni sortant.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Notez le podSelector: {} vide : il cible tous les pods du namespace, contrairement à l’absence totale de podSelector qui n’aurait ici aucun sens dans une NetworkPolicy. Appliquez d’abord cette règle sur un namespace de staging, jamais directement en production.
kubectl apply -f default-deny-all.yaml -n staging
kubectl get networkpolicy -n staging
Étape 5 : Autoriser le DNS pour tous les pods
Dès que le default-deny est actif, la résolution DNS cesse de fonctionner pour tous les pods du namespace : c’est l’incident numéro un rencontré par les équipes qui découvrent la microsegmentation. Ajoutez immédiatement une règle d’autorisation vers CoreDNS.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Étape 6 : Autoriser les communications avec kube-system
Au-delà du DNS, vos pods ont besoin d’atteindre d’autres services système : metrics-server pour l’autoscaling, les webhooks d’admission, parfois l’API server directement. Listez ces dépendances à partir de votre cartographie Hubble de l’étape 3, puis ajoutez une règle ciblée plutôt qu’une autorisation large vers tout kube-system.
Le label kubernetes.io/metadata.name utilisé dans les manifestes ci-dessus est ajouté automatiquement par Kubernetes depuis la version 1.21 sur chaque namespace, avec pour valeur le nom du namespace lui-même. C’est le moyen le plus fiable de cibler un namespace précis dans un namespaceSelector, plutôt que de dépendre d’un label personnalisé que quelqu’un pourrait supprimer par erreur lors d’un futur nettoyage.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-kube-system-metrics
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: metrics-server
ports:
- protocol: TCP
port: 443
Étapes 7 à 9 : sécuriser les communications internes et sortantes
Étape 7 : Définir les règles entre microservices
Vient ensuite le cœur du travail : autoriser précisément chaque appel légitime entre vos propres services. Prenons un exemple classique à trois niveaux, frontend, API, base de données. Seule l’API doit pouvoir joindre la base de données, jamais le frontend directement.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-to-database
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api-backend
ports:
- protocol: TCP
port: 5432
Répétez ce schéma pour chaque paire de services autorisée à communiquer. C’est fastidieux à écrire manuellement sur un grand cluster, ce qui justifie souvent le passage aux CiliumNetworkPolicy ou GlobalNetworkPolicy pour factoriser les règles communes, abordées plus bas.
Préférez toujours nommer les ports plutôt que de coder en dur un numéro, quand votre définition de service le permet. Un port nommé dans le manifeste du Deployment (name: postgres plutôt que 5432 seul) reste valide même si l’équipe applicative décide de changer le port d’écoute plus tard, ce qui évite une NetworkPolicy silencieusement obsolète après une migration technique mineure.
Étape 8 : Restreindre l’egress vers Internet
Un pod compromis qui garde un accès sortant illimité vers Internet peut exfiltrer des données ou récupérer un second payload d’attaque. Limitez l’egress externe aux seules destinations nécessaires, et bloquez explicitement l’accès au point de métadonnées cloud 169.254.169.254, une cible classique pour l’élévation de privilèges via les credentials d’instance.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-egress-internet
namespace: production
spec:
podSelector:
matchLabels:
app: api-backend
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32
ports:
- protocol: TCP
port: 443
Étape 9 : Tester en staging avant la bascule
Appliquez l’ensemble de vos politiques sur staging, puis laissez tourner le trafic normal pendant au moins 48 heures en surveillant les métriques d’erreur applicatives et les logs Hubble pour repérer les flux rejetés à tort.
hubble observe --namespace staging --verdict DROPPED --follow
Chaque ligne DROPPED correspond à un flux bloqué par vos politiques. Si vous en voyez apparaître pour des connexions attendues, ajustez la règle concernée avant de passer à la production. Cette phase de validation est ce qui différencie un déploiement réussi d’un incident de disponibilité en pleine nuit.
Étapes 10 et 11 : intégrer au CI/CD et basculer en production
Étape 10 : Imposer les Network Policies avec Kyverno
Une fois le modèle validé, évitez qu’un futur déploiement crée un namespace sans politique associée. Kyverno permet d’imposer cette règle directement dans le pipeline CI/CD, en rejetant toute création de namespace applicatif dépourvu de default-deny.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-default-deny-networkpolicy
spec:
validationFailureAction: Enforce
rules:
- name: check-default-deny-exists
match:
any:
- resources:
kinds:
- Namespace
selector:
matchLabels:
environment: production
validate:
message: "Un namespace de production doit avoir une NetworkPolicy default-deny."
deny:
conditions:
- key: "{{ request.object.metadata.name }}"
operator: NotIn
value: "{{ networkpolicies.production.[?spec.podSelector == `{}`].metadata.namespace }}"
Une alternative plus simple à démarrer : OPA Gatekeeper permet le même type de garde-fou via des contraintes déclaratives, si votre organisation utilise déjà Rego pour ses autres politiques de conformité.
Étape 11 : Bascule en production avec rollback automatique
Déployez d’abord en mode observation (Cilium le permet via l’annotation audit-mode sur certaines versions, ou en surveillant Hubble sans bloquer), puis basculez au mode enforce namespace par namespace, jamais en une seule fois sur tout le cluster. Gardez sous la main la commande de retrait immédiat :
kubectl delete networkpolicy default-deny-all -n production
kubectl get networkpolicy -n production
Configurez une alerte sur le taux de connexions DROPPED observées par Hubble juste après la bascule : un pic soudain signale une règle manquante et déclenche le rollback avant que les utilisateurs ne le remarquent.
Procédez par vagues : un premier namespace à faible criticité pendant 24 heures, puis les namespaces suivants un par un sur plusieurs jours plutôt qu’en une seule fenêtre de maintenance. Cette approche progressive limite le rayon d’impact d’une règle mal écrite à un seul service plutôt qu’à l’ensemble de votre plateforme, et donne à l’équipe d’astreinte le temps de repérer un problème avant qu’il ne s’accumule sur plusieurs namespaces en parallèle.
Calico : les GlobalNetworkPolicy pour aller plus loin
Si votre cluster tourne sous Calico plutôt que Cilium, le principe reste identique mais la ressource change. Le CRD GlobalNetworkPolicy de Calico permet d’appliquer une règle à l’ensemble du cluster sans la dupliquer dans chaque namespace, un vrai gain de maintenance sur un cluster multi-équipes.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-metadata-endpoint
spec:
selector: all()
types:
- Egress
egress:
- action: Deny
destination:
nets:
- 169.254.169.254/32
- action: Allow
Pour auditer les politiques déjà en place sur un cluster Calico existant, la commande suivante liste l’ensemble des règles actives sur un namespace donné :
calicoctl get networkpolicy -n production -o yaml
Calico expose aussi des logs de flux exportables vers un SIEM externe, un atout pour les équipes qui doivent produire des preuves d’audit régulières dans le cadre de NIS2 ou d’une certification C5 côté hébergeurs allemands.
L’agent responsable de l’application des règles côté Calico s’appelle Felix : il tourne en DaemonSet sur chaque nœud et traduit les GlobalNetworkPolicy en règles iptables ou eBPF selon le mode choisi à l’installation. Si une politique semble ne pas s’appliquer, un premier réflexe consiste à vérifier les logs de ce composant plutôt que ceux du contrôleur central, car c’est Felix qui exécute concrètement le filtrage sur chaque nœud.
Projet complet : sécuriser une application 3 tiers de bout en bout
Pour ancrer l’ensemble du tutoriel, voici l’arborescence d’un projet de démonstration complet, déployable tel quel sur un cluster de test, qui applique toutes les politiques vues plus haut à une application frontend / API / base de données :
zero-trust-demo/
├── namespace.yaml
├── deployments/
│ ├── frontend.yaml
│ ├── api-backend.yaml
│ └── database.yaml
├── network-policies/
│ ├── 00-default-deny-all.yaml
│ ├── 01-allow-dns.yaml
│ ├── 02-allow-kube-system.yaml
│ ├── 03-frontend-to-api.yaml
│ ├── 04-api-to-database.yaml
│ └── 05-restrict-egress-internet.yaml
└── kyverno/
└── require-default-deny.yaml
L’ordre de déploiement compte : appliquez d’abord les workloads, puis le default-deny, puis chaque règle d’autorisation une par une en vérifiant les flux Hubble entre chaque application. Un script minimal automatise l’ensemble :
kubectl apply -f namespace.yaml
kubectl apply -f deployments/
kubectl apply -f network-policies/00-default-deny-all.yaml
sleep 5 && hubble observe --namespace production --verdict DROPPED --last 20
kubectl apply -f network-policies/01-allow-dns.yaml
kubectl apply -f network-policies/02-allow-kube-system.yaml
kubectl apply -f network-policies/03-frontend-to-api.yaml
kubectl apply -f network-policies/04-api-to-database.yaml
kubectl apply -f network-policies/05-restrict-egress-internet.yaml
kubectl apply -f kyverno/require-default-deny.yaml
Ce squelette couvre déjà la majorité des cas rencontrés en environnement de production : frontend public, API interne, base de données isolée, et garde-fou CI/CD pour empêcher toute régression future.
Pour valider que le projet fonctionne comme prévu, ajoutez un pod de test temporaire qui tente de joindre la base de données directement depuis le namespace frontend, en contournant l’API. Cette connexion doit échouer si vos politiques sont correctement écrites :
kubectl run test-frontend --rm -it --image=busybox -n production \
--labels="app=frontend" -- sh -c "nc -zv -w 3 database 5432"
Une sortie du type nc: database (10.0.0.12:5432): Connection timed out confirme que la politique api-to-database bloque bien l’accès direct depuis le frontend, alors que le même test lancé depuis un pod labellisé app: api-backend doit réussir. Ce test croisé, simple à automatiser dans une étape de pipeline, constitue une bonne validation de non-régression à chaque modification future des politiques réseau.
Erreurs courantes à éviter
Ces erreurs reviennent systématiquement dans les retours d’expérience des équipes qui déploient leur première microsegmentation Kubernetes :
- Appliquer le default-deny directement en production, sans être passé par staging ni avoir cartographié les flux : c’est la cause numéro un des incidents liés aux Network Policies.
- Oublier la règle DNS juste après le default-deny : sans elle, tous les pods perdent instantanément la résolution de noms, y compris vers les services internes.
- Confondre
podSelector: {}et l’absence de podSelector : le premier cible tous les pods du namespace, le second est syntaxiquement invalide dans une NetworkPolicy. - Négliger l’egress en ne filtrant que l’ingress : un pod compromis avec un egress libre peut exfiltrer des données sans qu’aucune règle ne s’y oppose.
- Ne jamais tester en staging, ou tester sur un trafic non représentatif (pas de jobs batch, pas de pics de charge).
- Ignorer l’accès au endpoint de métadonnées cloud (
169.254.169.254), une cible privilégiée pour voler des credentials d’instance depuis un pod compromis. - Mélanger CiliumNetworkPolicy (CRD) et NetworkPolicy standard sans comprendre que la première offre des capacités L7 que la seconde ne gère pas, ce qui crée des incohérences de compréhension dans les équipes.
Dépannage : les problèmes les plus fréquents
Voici les incidents les plus signalés lors du déploiement d’une microsegmentation Cilium ou Calico, avec leur cause probable et la correction à appliquer. Gardez cette liste ouverte pendant votre bascule en production : la plupart de ces situations se règlent en quelques minutes une fois la cause identifiée, mais elles paraissent alarmantes la première fois qu’on les rencontre sans référence sous la main.
| Symptôme | Cause probable | Correction |
|---|---|---|
| Les pods ne résolvent plus les noms de domaine après default-deny | Règle allow-dns manquante | Appliquer la NetworkPolicy DNS de l’étape 5 avant toute autre restriction |
| Les health checks du kubelet échouent après application des politiques | Le podSelector ne couvre pas le trafic issu du nœud (kubelet) | Ajouter une règle ipBlock ciblant le CIDR interne des nœuds |
| cilium status affiche CrashLoopBackOff sur le DaemonSet | Version de noyau Linux incompatible avec eBPF requis par Cilium | Vérifier le noyau (5.4+ recommandé) et les modules eBPF chargés |
| Hubble UI inaccessible après port-forward | Le pod hubble-relay n’est pas prêt ou le port est déjà utilisé localement | Vérifier kubectl get pods -n kube-system et changer de port local |
| Les NetworkPolicy semblent totalement ignorées | Le CNI en place (ex. Flannel) n’implémente pas l’application des NetworkPolicy | Migrer vers un CNI qui applique les politiques, comme Cilium ou Calico |
| Les pulls d’images depuis un registre externe échouent après restriction egress | La règle egress ne couvre pas l’IP ou le port du registre d’images | Ajouter le registre dans les destinations autorisées avant d’activer la restriction |
| calicoctl renvoie une erreur de connexion au datastore | Mauvais mode de datastore configuré (etcd vs Kubernetes API) | Vérifier la variable DATASTORE_TYPE dans la configuration calicoctl |
| Un sidecar de service mesh (Istio) perd la connectivité après une politique Cilium | Le podSelector ne prend pas en compte le port du proxy sidecar | Ajouter explicitement les ports du sidecar dans les règles ingress et egress |
| Une politique appliquée en staging ne produit aucun effet visible | Le CNI applique la politique correctement mais aucun trafic ne la teste réellement | Générer du trafic de test avec un pod temporaire (kubectl run –rm -it) avant de conclure |
Si un incident survient malgré ces vérifications, la commande la plus rapide pour reprendre la main reste de lister toutes les politiques actives sur le namespace concerné, puis de les retirer une par une jusqu’à identifier la règle fautive :
kubectl get networkpolicy -n production -o name
kubectl describe networkpolicy NOM_DE_LA_POLITIQUE -n production
Astuces avancées : multi-cluster, service mesh et FinOps
Une fois le socle en place sur un cluster unique, plusieurs extensions valent le détour. Cilium ClusterMesh permet d’étendre les politiques réseau à plusieurs clusters, utile pour les architectures multi-région fréquentes chez les entreprises européennes soumises à des contraintes de résidence des données. Les règles CiliumNetworkPolicy s’appliquent alors de façon cohérente entre un cluster en France et un cluster en Allemagne, par exemple.
Côté service mesh, Cilium propose un mode sans sidecar (via eBPF directement) qui réduit la surcharge par rapport à un mesh classique type Istio avec proxy Envoy sur chaque pod. Si votre organisation utilise déjà Istio, les CiliumNetworkPolicy et les politiques d’autorisation Istio peuvent coexister, mais testez soigneusement les interactions entre les deux couches avant la bascule en production.
Sur le filtrage L7, Cilium permet d’aller plus loin que le simple blocage par port. Une CiliumNetworkPolicy peut, par exemple, n’autoriser qu’un sous-ensemble de méthodes HTTP vers un chemin précis d’une API interne, ce qui revient à faire une partie du travail habituellement dévolu à une passerelle API, directement au niveau réseau. C’est particulièrement utile pour des services legacy dont vous ne pouvez pas modifier le code applicatif, mais dont vous voulez tout de même restreindre les endpoints exposés en interne.
Enfin, un angle souvent négligé : le lien entre microsegmentation et FinOps. Cartographier précisément les flux réseau, comme à l’étape 3, révèle souvent des communications inter-zones ou inter-régions inutiles, facturées au gigaoctet par les fournisseurs cloud. Réduire ces flux via des politiques bien pensées a un effet direct sur la facture, en plus du bénéfice sécurité. Les benchmarks IT 2026 sur les solutions de FinOps évoquent des gains de 20 à 40 % sur la facture cloud grâce à une meilleure visibilité et à l’élimination des ressources et flux inutiles.
Foire aux questions
Une NetworkPolicy Kubernetes standard suffit-elle sans Cilium ni Calico ?
Non. La ressource NetworkPolicy fait partie de l’API Kubernetes, mais son application dépend entièrement du CNI installé. Sans un CNI qui l’implémente, comme Cilium ou Calico, les règles sont acceptées par l’API server mais n’ont aucun effet réel sur le trafic.
Peut-on migrer un cluster de Calico vers Cilium sans interruption ?
C’est possible mais délicat, car deux CNI actifs en parallèle créent des conflits réseau. La méthode la plus sûre consiste à migrer nœud par nœud avec un cordon/drain progressif, ou à reconstruire le cluster si votre infrastructure le permet facilement (cluster éphémère, Infrastructure as Code).
Combien de temps faut-il pour sécuriser un cluster de production existant ?
Comptez au minimum deux à trois semaines pour un cluster de taille moyenne : une à deux semaines de collecte des flux via Hubble, puis une phase de tests en staging avant la bascule progressive en production, namespace par namespace.
La microsegmentation ralentit-elle les performances réseau ?
Avec Cilium et son moteur eBPF, l’impact est marginal comparé à une approche iptables classique, car les vérifications se font directement dans le noyau sans passer par de longues chaînes de règles. C’est justement l’un des arguments techniques qui a poussé de nombreux fournisseurs de Kubernetes managé à proposer Cilium par défaut.
Faut-il une NetworkPolicy par pod ou peut-on grouper par label ?
Toujours grouper par label via le podSelector plutôt que cibler des pods individuels. C’est le principe même de Kubernetes : les pods sont éphémères, les règles doivent s’appliquer à des groupes logiques (par exemple app: api-backend) qui survivent aux redéploiements.
Les Network Policies suffisent-elles pour la conformité NIS2 ?
Elles constituent un élément de preuve important pour la segmentation réseau exigée par NIS2, mais ne couvrent pas à elles seules l’ensemble des obligations (gestion des vulnérabilités, réponse à incident, gouvernance). Consultez la directive NIS2 officielle pour le périmètre complet applicable à votre secteur.
Que se passe-t-il si deux NetworkPolicy contradictoires ciblent le même pod ?
Il n’y a pas de conflit possible au sens strict, car le modèle est additif : Kubernetes fusionne les règles de toutes les politiques qui ciblent un pod donné. Si une politique autorise un flux et qu’une autre ne mentionne pas ce flux, il reste autorisé. Le seul moyen de bloquer un flux est de ne l’inclure dans aucune règle d’autorisation une fois le default-deny actif, jamais de le “refuser” explicitement dans une NetworkPolicy standard.
Quelle est la différence entre CiliumNetworkPolicy et NetworkPolicy standard ?
CiliumNetworkPolicy est un CRD propre à Cilium qui étend le modèle standard avec le filtrage L7 (règles HTTP par chemin ou méthode, par exemple), les politiques cluster-wide via CiliumClusterwideNetworkPolicy, et des capacités DNS-aware pour filtrer l’egress par nom de domaine plutôt que par IP fixe.
Pour approfondir les bonnes pratiques de durcissement Kubernetes au-delà du réseau, consultez également le Kubernetes Security Cheat Sheet de l’OWASP et le dépôt officiel Cilium sur GitHub pour suivre les évolutions du projet.
Pour aller plus loin
La microsegmentation réseau n’est qu’une brique du durcissement Kubernetes global. Elle se combine avec la gestion des secrets, le scan des images, les profils seccomp et le RBAC pour former une défense en profondeur cohérente. Les articles suivants complètent ce tutoriel sur les autres piliers de la sécurité de votre cluster.
Related Coverage
- Minikube : Kubernetes en Local en 12 Étapes, 30 Min [2026]
- Secrets Kubernetes : 12 Étapes, 90 Min [2026]
- Durcir Kubernetes : 5 CVE Containerd en 12 Étapes [2026]
- CRA + C5:2026 : Conteneurs Passent de 121 à 168 Critères
- FinOps AWS : 12 Étapes Contre 29% de Gaspillage [2026]
Retrouvez l’ensemble de nos guides sur le cloud computing pour suivre les prochaines évolutions de la sécurité Kubernetes en 2026.




