Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Namespaces Kubernetes : organiser et isoler logiquement vos ressources

22 min de lecture

logo kubernetes

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.

À la fin de ce guide, vous saurez :

  • Comprendre le rôle d’un namespace : organiser un cluster, séparer équipes et environnements
  • Créer et gérer des namespaces : commandes impératives, manifestes déclaratifs, changement de contexte
  • Identifier les namespaces système : default, kube-system, kube-public, kube-node-lease
  • Connaître les limites : ce qu’un namespace isole vraiment et ce qu’il n’isole pas
  • Sécuriser un namespace d’équipe avec le pack minimum : quotas, limites, NetworkPolicy, RBAC

Avant de créer votre premier namespace, comprenons pourquoi cette ressource existe et quels problèmes elle résout.

Imaginez un cluster Kubernetes utilisé par plusieurs équipes : backend, frontend, data, ops. Sans namespaces, toutes les ressources (pods, services, configmaps) cohabitent dans un espace unique. Le résultat ? Un chaos où il devient difficile de savoir 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 peut avoir son propre service api sans conflit.

Fenêtre de terminal
# Deux services "api" coexistent dans des namespaces différents
kubectl get service api -n team-backend
kubectl get service api -n team-frontend

Les namespaces permettent de faire cohabiter plusieurs environnements sur le même cluster :

NamespaceUsage
devDéveloppement, tests rapides
stagingPré-production, tests d’intégration
prodProduction

Cette séparation facilite l’application de politiques différenciées : quotas généreux en dev, stricts en prod ; accès large en dev, restreint en prod.

Un namespace sert de périmètre pour les politiques :

  • RBAC : donner à une équipe les droits complets sur son namespace, sans accès aux autres
  • ResourceQuota : limiter la consommation CPU/mémoire par namespace
  • LimitRange : définir des valeurs par défaut pour les conteneurs
  • NetworkPolicy : contrôler le trafic réseau entrant et sortant

Sans namespace, vous ne pourriez pas cibler ces politiques — elles s’appliqueraient à tout le cluster.

Passons à la pratique. Kubernetes offre deux approches pour créer un namespace, chacune adaptée à des cas d’usage différents.

L’approche impérative utilise des commandes kubectl directes. Elle convient pour les tests rapides et l’exploration.

Fenêtre de terminal
# Créer un namespace
kubectl create namespace mon-namespace
# Lister tous les namespaces
kubectl get namespaces
# Voir les détails (quotas, labels, annotations)
kubectl describe namespace mon-namespace
# Supprimer un namespace (supprime TOUTES ses ressources !)
kubectl delete namespace mon-namespace

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
kubectl apply -f namespace.yaml

Les labels sont particulièrement utiles pour les NetworkPolicies (sélection par namespace) et pour l’organisation (filtrage, reporting de coûts).

Pour éviter d’ajouter -n mon-namespace à chaque commande, configurez le namespace par défaut de votre contexte kubectl :

Fenêtre de terminal
# Définir le namespace par défaut
kubectl config set-context --current --namespace=team-backend
# Vérifier le namespace actuel
kubectl config view --minify | grep namespace:

Tous vos kubectl get pods, kubectl get services, etc. s’exécuteront désormais dans team-backend sans avoir à le spécifier.

Quand vous tapez kubectl get ns sur un cluster fraîchement créé, vous voyez quatre namespaces. Chacun a un rôle spécifique qu’il est important de comprendre.

Le namespace default est l’espace par défaut pour toutes les ressources qui ne spécifient pas de namespace. C’est pratique pour les tests rapides, mais problématique en production car toutes les ressources s’y mélangent sans organisation.

Ce namespace contient les composants essentiels de Kubernetes lui-même : kube-apiserver, kube-controller-manager, kube-scheduler, CoreDNS, kube-proxy, et les plugins CNI. Ces composants sont critiques pour le fonctionnement du cluster.

Fenêtre de terminal
# Voir les composants système
kubectl get pods -n kube-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 est principalement utilisé pour les ressources qui doivent être accessibles publiquement, comme le ConfigMap cluster-info utilisé lors du bootstrap.

Fenêtre de terminal
# Le ConfigMap cluster-info est accessible sans authentification
kubectl get configmap cluster-info -n kube-public -o yaml

En pratique, ce namespace est peu utilisé. Il existe principalement pour des cas d’usage spécifiques liés au bootstrapping du cluster.

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
kubectl get lease -n kube-node-lease

Ce mécanisme optimise la détection de défaillance des nœuds tout en réduisant la charge sur etcd. Vous n’avez généralement pas besoin d’interagir avec 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.

Fenêtre de terminal
# Créer deux namespaces
kubectl create namespace team-dev
kubectl create namespace team-qa
# Créer un pod "api" dans chaque namespace
kubectl run api --image=nginx -n team-dev
kubectl run api --image=nginx -n team-qa
# Vérifier : les deux pods coexistent sans conflit
kubectl get pods api -n team-dev
kubectl get pods api -n team-qa

Les deux pods api existent simultanément, chacun dans son propre espace.

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...
kubectl create secret generic db-password \
--from-literal=password=secret123 -n team-dev
# ...n'est pas visible depuis team-qa
kubectl get secret db-password -n team-qa
# Error: 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.

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
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: full-access
namespace: team-dev
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]

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
kubectl describe namespace team-dev

Cette commande affiche les quotas configurés et leur utilisation actuelle.

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é.

Isolation des namespaces Kubernetes

Pour tester cette communication inter-namespace :

Fenêtre de terminal
# Depuis un pod dans team-dev, on peut joindre un service dans team-qa
kubectl exec -it mon-pod -n team-dev -- curl http://mon-service.team-qa.svc.cluster.local

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.

Certaines ressources Kubernetes ne sont pas scopées par namespace. Ces ressources cluster-wide sont partagées par tous :

RessourceDescriptionImpact sur l’isolation
NodesNœuds du clusterTous les pods partagent les mêmes nœuds
PersistentVolumesStockage persistantUn PV peut être réclamé depuis n’importe quel namespace
StorageClassesClasses de stockagePartagées globalement
ClusterRoleRôles RBAC cluster-widePermissions globales
NamespacesEux-mêmesVisibles par tous
IngressClassClasses d’IngressPartagées globalement
PriorityClassesPriorités de schedulingAffectent le scheduling global

Pour lister toutes les ressources non-namespacées de votre cluster :

Fenêtre de terminal
kubectl api-resources --namespaced=false

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 “noisy neighbor” (voisin bruyant) : un pod mal configuré peut dégrader les performances des autres pods sur le même nœud.

Le même registry d’images est utilisé par tous les namespaces. Si un développeur push une image malveillante sur un registry partagé, elle peut être utilisée par n’importe quel namespace. L’isolation des images nécessite des politiques au niveau du registry ou des admission controllers.

Maintenant que vous connaissez ce qu’un namespace isole et ses limites, voici comment le rendre vraiment exploitable en production. Créer un namespace vide ne suffit pas — vous devez déployer un ensemble cohérent de ressources.

  1. 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
  2. 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"
  3. Ajouter un LimitRange pour les valeurs par défaut

    Sans LimitRange, les pods sans requests/limits définis ne seront pas schedulés si un ResourceQuota est en place. Le LimitRange définit des valeurs par défaut automatiques.

    apiVersion: v1
    kind: LimitRange
    metadata:
    name: team-backend-limits
    namespace: team-backend
    spec:
    limits:
    - default:
    cpu: "500m"
    memory: "512Mi"
    defaultRequest:
    cpu: "100m"
    memory: "128Mi"
    max:
    cpu: "2"
    memory: "4Gi"
    min:
    cpu: "50m"
    memory: "64Mi"
    type: Container
  4. Isoler le réseau avec des NetworkPolicies

    Par défaut, bloquez tout le trafic, puis autorisez sélectivement.

    # Politique par défaut : tout bloquer
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: default-deny-all
    namespace: team-backend
    spec:
    podSelector: {}
    policyTypes:
    - Ingress
    - Egress
    ---
    # Autoriser le trafic interne au namespace + DNS
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: allow-internal
    namespace: team-backend
    spec:
    podSelector: {}
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
    - namespaceSelector:
    matchLabels:
    kubernetes.io/metadata.name: team-backend
    egress:
    - to:
    - namespaceSelector:
    matchLabels:
    kubernetes.io/metadata.name: team-backend
    - to: # Autoriser les requêtes DNS
    - namespaceSelector:
    matchLabels:
    kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
    port: 53
  5. Configurer le RBAC pour l’équipe

    Créez un Role avec les permissions nécessaires et liez-le au groupe de l’équipe.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
    name: team-backend-developer
    namespace: team-backend
    rules:
    - apiGroups: ["", "apps", "batch"]
    resources: ["pods", "deployments", "services", "configmaps", "secrets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    - apiGroups: [""]
    resources: ["pods/log", "pods/exec"]
    verbs: ["get", "create"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
    name: team-backend-developers
    namespace: team-backend
    subjects:
    - kind: Group
    name: team-backend-devs # Groupe dans votre IdP
    apiGroup: rbac.authorization.k8s.io
    roleRef:
    kind: Role
    name: team-backend-developer
    apiGroup: rbac.authorization.k8s.io

Après avoir appliqué toutes ces ressources, vérifiez leur présence :

Fenêtre de terminal
# Le namespace avec ses quotas et limites
kubectl describe namespace team-backend
# Les NetworkPolicies
kubectl get networkpolicies -n team-backend
# Le RBAC
kubectl get roles,rolebindings -n team-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.

Travailler avec plusieurs namespaces implique de nombreux changements de contexte. Plusieurs outils simplifient cette navigation.

L’outil kubens permet de changer de namespace en une commande, sans manipuler la configuration kubectl.

Fenêtre de terminal
# Lister les namespaces disponibles
kubens
# Changer de namespace
kubens team-backend
# Revenir au namespace précédent
kubens -

kubens colore le namespace actuel, facilitant le repérage visuel. Il fait partie du projet kubectx qui fournit aussi kubectx pour changer de cluster.

k9s offre une interface terminal complète pour explorer et gérer les ressources Kubernetes. Il permet de naviguer entre namespaces avec les raccourcis clavier et d’exécuter des actions directement.

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.

Certains problèmes courants avec les namespaces ont des solutions bien documentées.

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 :

Fenêtre de terminal
# Voir ce qui bloque
kubectl get namespace mon-namespace -o json | jq '.status'
# Rechercher les ressources avec des finalizers
kubectl api-resources --verbs=list --namespaced -o name | \
xargs -n 1 kubectl get --show-kind --ignore-not-found -n mon-namespace

Si des ressources avec des finalizers persistent, vous devrez peut-être les supprimer manuellement ou patcher le namespace pour retirer les finalizers (opération risquée, à faire avec précaution).

Si vos ressources apparaissent systématiquement dans default alors que vous pensiez les créer ailleurs :

Fenêtre de terminal
# Vérifier le namespace par défaut de votre contexte
kubectl config view --minify | grep namespace:
# Si vide, le namespace par défaut est "default"
# Corrigez avec :
kubectl config set-context --current --namespace=team-backend

Une autre cause fréquente : les fichiers YAML qui ne spécifient pas de namespace dans leur metadata. Ajoutez explicitement le namespace dans le manifeste ou utilisez -n lors du kubectl apply.

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
kubectl describe resourcequota -n team-backend

Soit vous demandez plus de ressources que le quota autorise pour un pod unique, soit le namespace a atteint sa limite globale. Ajustez le quota ou réduisez les requests/limits de vos workloads.

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

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, 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
  • Le pack minimum d’équipe comprend : Namespace + ResourceQuota + LimitRange + NetworkPolicy + RBAC
  • Évitez default en production et ne touchez pas à kube-system pour vos workloads

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn