Contactez-nous

Les Namespaces : Isolation logique des ressources

Découvrez comment les Namespaces Kubernetes permettent de diviser un cluster physique en plusieurs clusters virtuels pour organiser les ressources et gérer les accès.

Diviser pour mieux régner : l'organisation par Namespaces

Imaginez un cluster Kubernetes utilisé par plusieurs équipes, projets ou environnements (développement, staging, production). Sans mécanisme d'organisation, toutes les ressources (Pods, Services, Deployments, etc.) coexisteraient dans un seul grand espace partagé. Cela pourrait rapidement conduire à des conflits de noms, à des difficultés pour gérer les permissions d'accès et à une impossibilité d'allouer des ressources de manière équitable entre les différents groupes.

Kubernetes résout ce problème grâce aux Namespaces (ou espaces de noms). Un Namespace fournit un mécanisme pour créer des clusters virtuels au sein d'un même cluster physique Kubernetes. Il permet de partitionner les ressources du cluster en groupes logiquement isolés les uns des autres.

Pensez aux Namespaces comme à des dossiers dans un système de fichiers : ils vous permettent de regrouper des fichiers liés et d'éviter que deux fichiers dans des dossiers différents aient le même nom et entrent en conflit. De manière similaire, les Namespaces offrent une portée (scope) pour les noms des objets Kubernetes et constituent la base pour appliquer des politiques d'accès et de quotas.

Qu'est-ce qui est "namespacé" (et ce qui ne l'est pas) ?

La plupart des ressources fondamentales dans Kubernetes, en particulier celles liées aux applications (comme les Pods, Services, Deployments, ReplicaSets, StatefulSets, ConfigMaps, Secrets, PersistentVolumeClaims, Roles, RoleBindings), existent à l'intérieur d'un Namespace. Le nom d'une telle ressource doit être unique *au sein* de son Namespace, mais vous pouvez avoir des ressources avec le même nom dans des Namespaces différents.

Cependant, certaines ressources Kubernetes sont globales au cluster et n'appartiennent à aucun Namespace spécifique. On les appelle des ressources cluster-scoped. Les exemples les plus importants incluent :

  • Les Noeuds (`Node`)
  • Les Namespaces eux-mêmes (`Namespace`)
  • Les PersistentVolumes (`PersistentVolume`, PV) - bien que les `PersistentVolumeClaim` (PVC) soient namespacées.
  • Les objets de contrôle d'accès au niveau cluster : `ClusterRole`, `ClusterRoleBinding`.
  • Les `StorageClass`.
  • Les `CustomResourceDefinition` (CRD).
  • Les `PodSecurityPolicy` (obsolète) / `PodSecurityAdmissionConfiguration`.

Vous pouvez vérifier si un type de ressource est namespacé ou non avec la commande `kubectl api-resources`. La colonne `NAMESPACED` indiquera `true` ou `false`.

Principaux cas d'usage des Namespaces

L'utilisation des Namespaces est essentielle pour gérer efficacement un cluster Kubernetes partagé ou complexe. Voici les principaux avantages :

  • Organisation et portée des noms : Permet de regrouper les ressources appartenant à un même projet, équipe ou environnement. Un `Deployment` nommé `database` dans le namespace `projet-a` ne rentrera pas en conflit avec un autre `Deployment` nommé `database` dans le namespace `projet-b`.
  • Contrôle d'accès (RBAC) : Les autorisations définies par les `Roles` et `RoleBindings` sont spécifiques à un Namespace. Cela permet de définir des politiques d'accès granulaires : par exemple, l'équipe A ne peut voir et modifier que les ressources dans le namespace `team-a`, tandis que l'équipe B est limitée au namespace `team-b`.
  • Gestion des ressources (Quotas) : Vous pouvez définir des `ResourceQuotas` par Namespace pour limiter la quantité totale de ressources (CPU, mémoire, stockage) ou le nombre d'objets (Pods, Services) qu'un Namespace peut consommer. Cela évite qu'un projet ou une équipe n'accapare toutes les ressources du cluster. Des `LimitRanges` peuvent aussi être définis par Namespace pour imposer des contraintes de ressources par défaut aux conteneurs.
  • Isolation réseau (via Network Policies) : Bien que les Namespaces n'isolent pas le réseau par défaut (tous les Pods peuvent communiquer entre eux quel que soit leur Namespace), ils servent de sélecteur pour les `NetworkPolicies`. Vous pouvez ainsi créer des règles de pare-feu qui autorisent ou bloquent le trafic entre les Pods en fonction des Namespaces auxquels ils appartiennent.

Les Namespaces par défaut

Lorsqu'un cluster Kubernetes est créé, il contient généralement quelques Namespaces par défaut :

  • `default` : Le Namespace utilisé par défaut si vous ne spécifiez pas de Namespace lors de la création d'un objet. Il est souvent utilisé pour les premiers tests ou les petites applications, mais il est recommandé de créer des Namespaces spécifiques pour les projets réels afin de bénéficier des avantages d'isolation et d'organisation.
  • `kube-system` : Ce Namespace est réservé aux objets créés par le système Kubernetes lui-même, comme les Pods du Control Plane (API Server, Scheduler, etc. s'ils tournent en Pods), CoreDNS, Kube-proxy, les plugins CNI et CSI, etc. Ne touchez généralement pas aux ressources dans ce Namespace, sauf si vous savez ce que vous faites.
  • `kube-public` : Ce Namespace est spécial car il est lisible par tous les utilisateurs (y compris non authentifiés) par défaut. Il est destiné à exposer des informations sur le cluster qui doivent être publiquement visibles. Peu utilisé en pratique.
  • `kube-node-lease` : Contient des objets `Lease` utilisés par les Kubelets pour envoyer leurs heartbeats au Control Plane. Introduit pour améliorer la performance de la détection de l'état des noeuds à grande échelle.

Travailler avec les Namespaces : kubectl

Voici les commandes `kubectl` courantes pour gérer les Namespaces :

  • Lister les Namespaces :
    kubectl get namespaces  # ou kubectl get ns
  • Créer un Namespace :
    - Via `kubectl` :
    kubectl create namespace mon-namespace

    - Via un fichier YAML (méthode déclarative préférée) :
    # mon-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: mon-namespace
    Puis :
    kubectl apply -f mon-namespace.yaml
  • Spécifier un Namespace lors de la création/gestion d'objets :
    - Dans le YAML : Ajoutez le champ `namespace: mon-namespace` sous `metadata`.
    apiVersion: v1
    kind: Pod
    metadata:
      name: mon-pod
      namespace: mon-namespace # Important !
    spec:
      ...
    

    - Avec `kubectl` : Utilisez le flag `-n` ou `--namespace`.
    kubectl apply -f mon-pod.yaml -n mon-namespace
    kubectl get pods -n mon-namespace
    kubectl logs mon-pod -n mon-namespace
    Si vous ne spécifiez pas de namespace (ni dans le YAML, ni avec le flag `-n`), l'objet sera créé dans le namespace `default` du contexte courant.
  • Voir les objets dans un Namespace spécifique :
    kubectl get pods --namespace=kube-system  # ou kubectl get pods -n kube-system
  • Voir les objets dans tous les Namespaces : Utilisez le flag `-A` ou `--all-namespaces`.
    kubectl get pods -A
  • Changer le Namespace par défaut du contexte courant : Utile si vous travaillez principalement dans un namespace spécifique.
    kubectl config set-context --current --namespace=mon-namespace
    Après cela, `kubectl get pods` listera les Pods de `mon-namespace` sans avoir besoin de spécifier `-n`.
  • Décrire un Namespace : Utile pour voir les labels, annotations, et les éventuels ResourceQuotas ou LimitRanges appliqués.
    kubectl describe namespace mon-namespace
  • Supprimer un Namespace :
    kubectl delete namespace mon-namespace  # ou kubectl delete ns mon-namespace
    Attention : La suppression d'un Namespace est une opération irréversible qui supprime toutes les ressources qu'il contient ! Soyez extrêmement prudent. La suppression peut prendre du temps si le Namespace contient beaucoup d'objets ou des objets avec des finalizers. Vous ne pouvez généralement pas supprimer les namespaces système (`kube-system`, etc.).

Limites de l'isolation par Namespace

Il est crucial de comprendre que l'isolation fournie par les Namespaces est principalement logique et concerne la portée des noms et la gestion des accès/quotas. Par défaut, un Namespace ne fournit pas d'isolation réseau forte (un Pod dans le namespace A peut contacter un Pod dans le namespace B) ni d'isolation au niveau des noeuds (des Pods de différents Namespaces peuvent s'exécuter sur le même Noeud Worker et partager ses ressources CPU, mémoire, disque).

Pour une isolation réseau plus stricte, vous devez utiliser les Network Policies, qui s'appuient souvent sur les Namespaces (et les labels) pour définir les règles de communication.

Pour influencer le placement des Pods sur des noeuds spécifiques (et donc obtenir une forme d'isolation physique), vous devez utiliser des mécanismes comme les `nodeSelector`, l'affinité/anti-affinité de noeuds ou les taints/tolerations, qui ne sont pas directement liés aux Namespaces.

Conclusion : un outil essentiel d'organisation

Les Namespaces sont un concept fondamental et indispensable pour gérer efficacement tout cluster Kubernetes au-delà des cas d'utilisation les plus simples. Ils apportent une structure organisationnelle claire, permettent de mettre en place un contrôle d'accès granulaire via RBAC, et aident à contrôler la consommation des ressources grâce aux Quotas.

Même si vous travaillez seul sur un petit projet, prendre l'habitude d'utiliser des Namespaces spécifiques plutôt que de tout mettre dans `default` est une bonne pratique qui facilitera la gestion à mesure que votre application ou votre usage du cluster évoluera. Ils sont la première étape vers la construction d'environnements Kubernetes multi-locataires ou simplement bien organisés.