Namespaces Kubernetes : organiser et isoler logiquement vos ressources
Organisez votre cluster avec les namespaces Kubernetes : séparer équipes et environnements, puis renforcer l'isolation par quotas, RBAC et NetworkPolicy.
L’issue s’ouvre déjà remplie avec le titre et l’adresse de cette page.
Un namespace Kubernetes organise votre cluster en espaces logiques distincts. Il permet de séparer les ressources par équipe, projet ou environnement, d'éviter les conflits de noms, et de cibler facilement des politiques (quotas, permissions). Pour une vraie séparation d'équipe en production, vous irez plus loin avec RBAC, ResourceQuota et NetworkPolicy, mais commençons par comprendre ce qu'est un namespace et comment l'utiliser au quotidien.
Imaginez un cluster utilisé par plusieurs équipes : backend, frontend, data, ops. Sans namespaces, toutes les ressources, Pods, Services et ConfigMaps, cohabitent dans un espace unique. Le résultat : plus personne ne sait qui a déployé quoi.
Un namespace crée un répertoire logique pour regrouper les ressources liées. C'est comme avoir des dossiers sur un disque dur : chaque équipe travaille dans son espace sans polluer celui des autres.
Deux équipes veulent créer un Service nommé api. Sans namespaces, c'est impossible : le nom est unique dans le cluster. Avec des namespaces séparés, team-backend et team-frontend, chaque équipe dispose de son propre Service api, sans conflit.
Fenêtre de terminal
# Deux services "api" coexistent dans des namespaces différents
L'approche déclarative utilise des fichiers YAML versionnés. C'est la méthode recommandée pour la production et les workflows GitOps.
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
environment: production
cost-center: "12345"
annotations:
owner: "equipe-backend@example.com"
description: "Namespace pour les services backend de production"
Appliquez ce fichier avec :
Fenêtre de terminal
kubectlapply-fnamespace.yaml
Les labels sont particulièrement utiles pour les NetworkPolicies (sélection par namespace) et pour l'organisation (filtrage, reporting de coûts).
Un label vous est d'ailleurs donné sans que vous ayez à le poser. Kubernetes ajoute automatiquement kubernetes.io/metadata.name à tout namespace, avec son nom pour valeur :
C'est ce label que les NetworkPolicies utilisent pour désigner un namespace par son nom, sans dépendre d'un étiquetage que quelqu'un pourrait oublier ou modifier.
Tous vos kubectl get pods, kubectl get services, etc. s'exécuteront
désormais dans team-backend sans avoir à le spécifier.
Deux drapeaux couvrent le reste des cas, et méritent d'entrer dans vos réflexes.
-n <namespace> cible un autre namespace pour une seule commande, sans
toucher au contexte. -A, ou --all-namespaces, interroge tous les
namespaces d'un coup et ajoute une colonne NAMESPACE à la sortie : c'est la
commande à taper quand vous cherchez un Pod dont vous ignorez où il tourne.
Fenêtre de terminal
kubectlgetpods-nkube-system# un autre namespace, ponctuellement
kubectlgetpods-A# tous les namespaces, avec la colonne NAMESPACE
La suppression n'est pas instantanée, et cela bloque
C'est le piège qui casse les pipelines. kubectl delete namespacerend la main immédiatement, mais le namespace passe d'abord en état Terminating le temps que Kubernetes supprime son contenu. Pendant cet intervalle, il existe encore, et il refuse toute création :
error: failed to create configmap: configmaps "trop-tard" is forbidden:
unable to create new content in namespace lab-term because it is being terminated
Recréer le namespace lui-même échoue tout autant, avec un message qui déroute : il parle d'existence là où vous venez de demander une suppression.
Sortie
Error from server (AlreadyExists): object is being deleted: namespaces "lab-term" already exists
Un enchaînement delete puis create dans un script échoue donc une fois sur deux. La parade tient en un drapeau : --wait=true est le défaut de kubectl delete, mais il est souvent désactivé dans les scripts.
Fenêtre de terminal
kubectldeletenamespacelab-term--wait=true# rend la main quand c'est fini
kubectlcreatenamespacelab-term
Sur un namespace contenant un Pod, la suppression a pris 10 secondes sur le cluster de la formation. Comptez davantage dès qu'il y a des volumes à démonter.
Rassurez-vous sur un point : une faute de frappe ne peut pas emporter kube-system. L'API refuse la suppression des namespaces initiaux, y compris default.
Sortie
Error from server (Forbidden): namespaces "kube-system" is forbidden:
Quand vous tapez kubectl get ns sur un cluster fraîchement créé, vous voyez
quatre namespaces créés par Kubernetes lui-même. Chacun a un rôle précis.
Vous en verrez souvent un ou deux de plus, ajoutés par votre distribution :
sur un cluster kind, local-path-storage héberge le provisionneur de volumes.
Ces namespaces ne sont pas standards, ne vous étonnez pas de ne pas les
retrouver ailleurs.
Le namespace default accueille toutes les ressources qui n'en précisent aucun. C'est commode pour un test rapide, problématique en production : tout s'y mélange sans aucune organisation.
N'utilisez pas le namespace default en production. Créez des namespaces dédiés pour chaque équipe ou application. La raison est concrète : tout ce qui atterrit dans default y arrive par omission, jamais par décision. Vous ne pouvez donc ni lui appliquer un quota qui ait du sens, ni y poser un RBAC ciblé, puisque son contenu est par nature imprévisible.
Ce namespace contient les composants de Kubernetes lui-même : kube-apiserver, kube-controller-manager, kube-scheduler, CoreDNS, kube-proxy et les plugins CNI. Tous sont critiques : le cluster ne fonctionne pas sans eux.
Fenêtre de terminal
# Voir les composants système
kubectlgetpods-nkube-system
Ne déployez jamais vos applications dans kube-system. Une erreur de configuration ou une surconsommation de ressources pourrait impacter les composants critiques et déstabiliser tout le cluster. De plus, certaines mises à jour de cluster peuvent réinitialiser ce namespace.
Ce namespace est lisible par tous les utilisateurs, même non authentifiés. Il porte donc ce qui doit être accessible publiquement, comme le ConfigMapcluster-info lu au démarrage d'un nœud.
Fenêtre de terminal
# Le ConfigMap cluster-info est accessible sans authentification
Introduit dans Kubernetes 1.14, ce namespace contient des objets Lease pour chaque nœud. Ces Leases permettent au kubelet d'envoyer des heartbeats (signaux de vie) sans surcharger l'API Server avec des mises à jour fréquentes de l'objet Node.
Fenêtre de terminal
# Voir les leases des nœuds
kubectlgetlease-nkube-node-lease
Ce mécanisme accélère la détection de défaillance des nœuds tout en réduisant la charge sur etcd. Vous n'avez pas à intervenir dans ce namespace.
Maintenant que vous savez créer et utiliser des namespaces, voyons précisément ce qu'ils isolent. Un namespace crée une frontière logique avec des effets concrets sur plusieurs aspects de vos ressources.
Le premier rôle d'un namespace est de créer un scope pour les noms. Deux ressources peuvent porter le même nom si elles sont dans des namespaces différents.
Les ConfigMaps et les Secrets sont scopés par namespace. Un pod dans team-dev ne peut pas monter un Secret créé dans team-qa. Cette isolation protège les données sensibles entre équipes.
Fenêtre de terminal
# Un secret créé dans team-dev...
kubectlcreatesecretgenericdb-password\
--from-literal=password=secret123-nteam-dev
# ...n'est pas visible depuis team-qa
kubectlgetsecretdb-password-nteam-qa
Sortie
Error from server (NotFound): secrets "db-password" not found
Cette isolation s'étend aux ServiceAccounts. Chaque namespace possède
automatiquement un ServiceAccount default, et les pods d'un namespace
utilisent les ServiceAccounts de ce namespace uniquement.
Elle s'étend aussi au sélecteur d'un Service : un Service ne peut cibler que
des Pods de son propre namespace, quels que soient les libellés portés
ailleurs. Le comportement est silencieux, ce qui le rend déroutant : le Service
est créé, son sélecteur est accepté, et sa liste d'endpoints reste simplement
vide.
Les Role et RoleBinding s'appliquent à un namespace spécifique. Vous pouvez donner à une équipe les droits complets sur son namespace sans lui accorder l'accès aux autres namespaces.
# Un Role qui donne tous les droits... mais seulement dans team-dev
Les ResourceQuota et LimitRange sont des ressources namespacées. Ils permettent de limiter la consommation de ressources par namespace, évitant qu'une équipe ne monopolise le cluster.
Fenêtre de terminal
# Voir les quotas et limites appliqués à un namespace
kubectldescribenamespaceteam-dev
Sortie
Name: team-dev
Labels: kubernetes.io/metadata.name=team-dev
Status: Active
Resource Quotas
Name: team-dev-quota
Resource Used Hard
-------- --- ---
pods 1 30
requests.cpu 0 4
requests.memory 0 8Gi
Resource Limits
Type Resource Min Max Default Request Default Limit
La colonne Used est celle à surveiller : c'est la consommation réelle
comparée au plafond. Une seule commande vous donne donc les deux moitiés du
dispositif, le quota global du namespace et les valeurs appliquées par défaut à
chaque conteneur.
Comprendre les limites de l'isolation par namespace est crucial pour éviter de faux sentiments de sécurité. Le diagramme ci-dessous illustre la frontière entre ce qui est isolé et ce qui est partagé.
Par défaut, tous les pods de tous les namespaces peuvent communiquer entre eux. Un pod dans team-dev peut atteindre un pod dans team-qa ou même dans kube-system. Le namespace seul n'apporte aucune isolation réseau, et c'est la source de faux sentiment de sécurité la plus fréquente : découper en namespaces donne l'impression d'avoir cloisonné, alors que le réseau, lui, est resté plat.
Pour tester cette communication inter-namespace :
Fenêtre de terminal
# Depuis un pod dans team-dev, on peut joindre un service dans team-qa
La résolution DNS fonctionne car Kubernetes utilise le format <service>.<namespace>.svc.cluster.local pour tous les Services. Sans NetworkPolicy explicite, le trafic passe sans restriction.
Pour lister toutes les ressources non-namespacées de votre cluster :
Fenêtre de terminal
kubectlapi-resources--namespaced=false
La proportion surprend : sur le cluster de la formation, 37 types de ressources sont cluster-wide contre 34 namespacés. Plus de la moitié de l'API échappe donc au découpage, et aucun namespace ne vous protégera de ce qu'on y fait.
Les pods de différents namespaces qui s'exécutent sur le même nœud partagent ses ressources physiques :
CPU et mémoire : Sans quotas, un pod peut consommer toutes les ressources du nœud
Espace disque : Les volumes ephemeral et les logs partagent le même disque
Bande passante réseau : Pas d'isolation réseau au niveau nœud par défaut
Cette cohabitation crée le problème du voisin bruyant, le « noisy neighbor » : un Pod mal configuré dégrade les performances des autres Pods du même nœud.
Le même registre d'images sert tous les namespaces. Une image malveillante poussée sur un registre partagé devient utilisable depuis n'importe quel namespace. Isoler les images demande des politiques au niveau du registre ou des admission controllers.
Vous savez maintenant ce qu'un namespace isole et ce qu'il n'isole pas. Reste à le rendre exploitable en production : un namespace vide ne suffit pas, il faut y déposer un ensemble cohérent de ressources.
Créer le namespace avec des labels appropriés
Les labels permettent d'identifier le namespace et sont utilisés par les NetworkPolicies.
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
environment: production
Ajouter un ResourceQuota pour limiter la consommation globale
Le ResourceQuota protège le cluster contre la surconsommation par une équipe.
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-backend-quota
namespace: team-backend
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "30"
services: "10"
configmaps: "30"
secrets: "30"
persistentvolumeclaims: "10"
Ajouter un LimitRange pour les valeurs par défaut
Le LimitRange n'est pas un confort, c'est ce qui rend le ResourceQuota
utilisable. Dès qu'un quota porte sur requests ou limits, un Pod qui ne
les déclare pas est refusé à la création, et non pas créé puis laissé en
attente : il n'existe jamais, et chercher un Pod Pending fait perdre du
temps. Le message ne laisse pourtant aucun doute.
Sortie sans LimitRange
Error from server (Forbidden): pods "sans-requests" is forbidden:
failed quota: q: must specify limits.cpu for: sans-requests;
Cette étape mérite d'être vérifiée plutôt que supposée, car son échec est
totalement silencieux. Une NetworkPolicy n'est qu'une déclaration : c'est le
CNI (Container Network Interface) qui l'applique, ou pas. Avec un CNI qui ne
les gère pas, kubectl get networkpolicies affiche vos règles, kubectl describe
les détaille, et le trafic passe quand même. Vous obtenez alors exactement la
fausse sécurité que ce guide cherche à éviter, avec en prime la preuve apparente
que tout est en place.
Calico, Cilium et kindnet, le CNI par défaut de kind, les appliquent.
Vérifié sur le cluster de la formation : un Pod de team-dev obtenait un
HTTP 200 sur un Service de team-qa, et n'obtient plus rien après un
default-deny-all posé sur team-qa. Flannel seul, en revanche, ne les
applique pas.
Pour savoir à quoi vous avez affaire, regardez ce qui tourne dans kube-system :
Après avoir appliqué toutes ces ressources, vérifiez leur présence :
Fenêtre de terminal
# Le namespace avec ses quotas et limites
kubectldescribenamespaceteam-backend
# Les NetworkPolicies
kubectlgetnetworkpolicies-nteam-backend
# Le RBAC
kubectlgetroles,rolebindings-nteam-backend
Un kubectl describe namespace team-backend affiche à la fois les Resource Quotas et les LimitRanges, vous permettant de valider la configuration en une commande.
k9s offre une interface en terminal pour explorer et gérer les ressources. On navigue entre namespaces au clavier et on déclenche les actions directement, sans retaper de commande.
Pour filtrer par namespace dans k9s, tapez :ns pour lister les namespaces, puis Entrée pour sélectionner. Le namespace actif s'affiche dans le header.
Lorsqu'un namespace reste en état Terminating indéfiniment, c'est généralement dû à des finalizers qui ne peuvent pas être traités. Identifiez la cause :
Si des ressources portant des finalizers persistent, il faut les supprimer à la main, ou patcher le namespace pour retirer ces finalizers. Cette seconde voie est risquée : elle abandonne le nettoyage que le finalizer devait faire.
Si vos pods restent en état Pending avec un événement mentionnant des quotas :
Fenêtre de terminal
# Voir l'utilisation actuelle vs les limites
kubectldescriberesourcequota-nteam-backend
Deux lectures possibles : soit ce Pod à lui seul dépasse le quota, soit le namespace a atteint sa limite globale. Ajustez le quota, ou réduisez les requests et limits de vos charges de travail.
Attention au diagnostic : selon le quota franchi, le Pod n'a pas le même sort. Un quota sur le nombre d'objets refuse la création, et vous ne trouverez aucun PodPending à examiner. Le message donne les trois chiffres qui comptent, le demandé, l'utilisé et le plafond.
Sortie
Error from server (Forbidden): pods "p2" is forbidden: exceeded quota: q,
Un namespace Kubernetes est un outil d'organisation avant d'être un outil d'isolation :
Utilisez-le pour : organiser vos ressources, séparer équipes et environnements, éviter les conflits de noms, cibler des politiques
Le namespace isole : les noms de ressources, les Secrets/ConfigMaps, le périmètre RBAC, le sélecteur d'un Service, et permet d'appliquer des quotas
Le namespace N'isole PAS : le réseau (sans NetworkPolicy), les ressources cluster-wide (Nodes, PV, StorageClass), les ressources physiques du nœud
Une NetworkPolicy ne vaut que ce que le CNI en fait : vérifiez-la en tentant la connexion, ne la supposez jamais active
Le pack minimum d'équipe comprend : Namespace + ResourceQuota + LimitRange + NetworkPolicy + RBAC, et sans LimitRange le quota refuse les Pods à la création
Évitez default en production et ne touchez pas à kube-system pour vos workloads
Sept questions sur ce qu'un namespace sépare vraiment, ce qu'il ne sépare pas,
et les namespaces système à ne pas confondre.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
7 questions
5 min.
90% requis
Informations
Le chronomètre démarre au clic sur Démarrer
Questions à choix multiples, vrai/faux et réponses courtes
Vous pouvez naviguer entre les questions
Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
⏱️--:--
0 / 7
Vérification
(0/0)
--:--
0%
0Correctes
0À revoir
0:00Temps
-Niveau
Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.