Gérer et manipuler les namespaces et les ResourceQuotas

Dans ce chapitre, nous apprendrons à gérer plusieurs équipes et limiter l'utilisation des ressources de notre cluster grâce aux namespaces et aux ResourceQuotas.

Introduction

C'est quoi un namespace ?

Kubernetes prend en charge plusieurs clusters virtuels sauvegardés par le même cluster physique. Ces clusters virtuels sont appelés namespaces.

Un namespace fournit une étendue pour les noms des ressources Kubernetes. Ceci est utile lorsque de nombreux utilisateurs répartis dans plusieurs équipes ou projets utilisent le même cluster et qu'il existe un risque de collision de noms. Ils sont aussi un bon moyen pour diviser et limiter les ressources physiques du cluster entre plusieurs utilisateurs via un système de quota que nous verrons à travers ce chapitre.

Conseils et restrictions d'utilisation :

  • Il n'est pas nécessaire d'utiliser plusieurs namespaces simplement pour séparer des ressources légèrement différentes, telles que des versions différentes de la même application. Dans ce cas, préférez l'utilisation des labels de manière à distinguer les ressources.
  • Les noms de ressources doivent être uniques dans un namespace, mais pas entre les différents namespaces.
  • Les namespaces ne peuvent pas être imbriqués les uns dans les autres et chaque ressource Kubernetes ne peut figurer que dans un seul namespace.

Les namespaces par défauts

Vous ne le saviez peut-être pas, mais vous utilisiez des namespaces depuis le début de cours sans pour autant en être conscient. Afin de vérifier cela, nous allons répertorier la liste des namespaces actuels de votre cluster, en lançant la commande suivante :

kubectl get namespace

Résultat :

NAME              STATUS   AGE
default           Active   25d
kube-node-lease   Active   25d
kube-public       Active   25d
kube-system       Active   25d

Comme vous pouvez le constater, notre cluster k8s utilise trois namespaces par défaut dans Kubernetes, soit :

  • default : le namespace utilisé par défaut pour les objets Kubernetes dont on ne spécifie pas de namespace.
  • kube-system : le namespace pour les objets créés et utilisés par le système Kubernetes.
  • kube-public : ce namespace est créé automatiquement au cas où vous souhaitez que certaines de vos ressources soient visibles publiquement dans l'ensemble du cluster par tous les utilisateurs (y compris ceux non authentifiés).

Manipulation des namespaces

Créer des namespaces

Il existe deux façons pour créer notre namespace, soit en utilisant un template au format YAML, soit sans.

Dans cet exemple, nous allons créer un namespace nommé dev-team sans utiliser de template :

kubectl create namespace dev-team

Résultat :

namespace/dev-team created

Cette fois-ci, nous utiliserons la méthode avec le template au format YAML. Créez donc un fichier yaml et copiez le contenu suivant :

apiVersion: v1
kind: Namespace
metadata:
   name: prod-team

Ensuite, exécutez la commande suivante :

kubectl create -f namespace.yaml

Résultat :

namespace/prod-team created

Par la suite, vérifions si nos namespaces spécifiés plus haut ont bien été créés :

kubectl get namespace

C'est bien le cas :

NAME              STATUS   AGE
default           Active   25d
dev-team          Active   2m12s
kube-node-lease   Active   25d
kube-public       Active   25d
kube-system       Active   25d
prod-team         Active   8s

Utilisation des namespaces dans les objets Kubernetes

Là aussi, il existe deux manières pour utiliser vos ressources Kubernetes dans un namespace. Soit vous définissez dans la liste metadata le champ namespace, comme suit :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: prod-team
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

Après cela, créez votre objet Kubernetes :

kubectl create -f deploy-prod.yaml

Soit, il suffit juste de rajouter l'option -n ou --namespace dans vos commandes kubectl, comme par exemple :

kubectl run alpine --image=alpine  --namespace=prod-team -- sleep 1d

À présent, si on vérifie les pods disponibles dans notre namespace prod-team, nous aurons ainsi les trois pods créés précédemment :

kubectl get pods -n prod-team

Résultat :

NAME                     READY   STATUS    RESTARTS   AGE
alpine-56b95f459-scbnw   1/1     Running   0          17s
nginx-7bffc778db-272kx   1/1     Running   0          4m24s
nginx-7bffc778db-m7nds   1/1     Running   0          4m24s

Définition de la préférence d'un namespace

Vous pouvez enregistrer de manière permanente un namespace pour toutes les commandes kubectl, sans la nécessité d'utiliser l'option -n :

kubectl config set-context --current --namespace=prod-team

Résultat :

Context "Kubernetes-admin@Kubernetes" modified.

Vous pouvez examiner le namespace par défaut grâce à la commande suivante :

kubectl config view | grep namespace

Résultat :

namespace: prod-team

Voici la commande pour revenir au namespace par défaut :

kubectl config set-context --current --namespace=default

Suppression d'un namespace

Si vous n'avez plus besoin de votre namespace, alors vous pouvez le supprimer avec la commande suivante :

kubectl delete namespaces prod-team

Définir des quotas

Introduction à l'objet Kubernetes ResourceQuotaobjet

Lorsque plusieurs utilisateurs ou équipes partagent un cluster, Il se peut qu'une équipe puisse utiliser plus que sa juste part de ressources. Dans ce cas de figure, il est recommandé d'utiliser l'objet ResourceQuotaobjet permettant aux administrateurs de résoudre ce type problème, en limitant la consommation ou la quantité de ressources définies dans votre namespace.

Fonctionnement d'un ResourceQuotaobjet dans un namespace

  1. L'administrateur crée un ResourceQuotaobjet pour chaque namespace.
  2. Les utilisateurs créent des objets Kubernetes (pods, services, etc.) dans un namespace et le système de quotas surveille la consommation des ressources pour s'assurer que celle-ci ne dépasse pas les limites matérielles définies dans le ResourceQuotaobjet.
  3. Si la création ou la mise à jour d'une ressource viole une contrainte de quota, la demande échouera et l'API renvoie le code HTTP 403 FORBIDDEN avec un message expliquant la contrainte qui aurait été violée.

Voici un exemple de quelques types de ressources qui sont pris en charge :

Nom de la ressource Description
limits.cpu Pour tous les pods dans un état non terminal, la somme des limites de la CPU ne peut pas dépasser cette valeur.
requests.cpu Pour tous les pods dans un état non terminal, la somme des requêtes de CPU ne peut pas dépasser cette valeur.
limits.memory Pour tous les pods dans un état non terminal, la somme des limites de mémoire ne peut pas dépasser cette valeur.
requests.memory Pour tous les pods dans un état non terminal, la somme des requêtes en mémoire ne peut pas dépasser cette valeur.
pods Nombre total de pods dans un état non terminal.
services Nombre total de services pouvant exister.

Création d'un ResourceQuota

Pour cet exemple, nous allons mettre en place les exigences suivantes :

  • Le nombre total de pods ne doit pas dépasser 2 pods.
  • Le total de demandes de mémoire pour tous les conteneurs ne doit pas dépasser 1 Go.
  • Le total de la limite de mémoire pour tous les conteneurs ne doit pas dépasser 2 Go.
  • Le nombre total de demandes d'UC (niveau d'utilisation du processeur central) pour tous les conteneurs ne doit pas dépasser 1 UC.
  • Le nombre total de processeurs pour tous les conteneurs ne doit pas dépasser 2 cpu.

Créons notre ResourceQuota avec les contraintes définies plus haut, via le template YAML suivant :

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-quota
spec:
  hard:
    pods: "2"
    requests.cpu: "1"
    limits.cpu: "2"
    requests.memory: 1Gi
    limits.memory: 2Gi

Ensuite, nous allons définir notre ResourceQuota dans notre namespace dev-team, de la façon suivante :

kubectl apply -f quota.yaml -n=dev-team

Comme d'habitude, nous vérifions si notre ResourceQuota est disponible dans notre namespace dev-team :

kubectl get resourcequota -n dev-team

Résultat :

NAME            CREATED AT
mem-cpu-quota   2019-09-01T17:48:57Z

Dès à présent, nous allons créer un Pod qui demande une consommation de 700 Mio de mémoire, dans le namespace dev-team :

apiVersion: v1
kind: Pod
metadata:
  namespace: dev-team
  name: nginx1
spec:
  containers:
  - name: nginx1
    image: nginx
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"      
      requests:
        memory: "700Mi"
        cpu: "400m"
kubectl create -f pod.yaml

Ensuite, dans le même namespace, nous créerons un second Pod avec la même consommation, soit un pod qui dépasse le quota de la mémoire disponible (700 Mio + 700 Mio > 1 Gio)

apiVersion: v1
kind: Pod
metadata:
  namespace: dev-team
  name: nginx2
spec:
  containers:
  - name: nginx2
    image: nginx
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"      
      requests:
        memory: "700Mi"
        cpu: "400m"

Si, nous tentons de lancer la commande de création de ce nouveau pod, au sein de notre namespace dev-team, alors nous nous retrouverions avec l'erreur suivante :

kubectl create -f pod.yaml

Résultat :

Error from server (Forbidden): error when creating "pod.yaml": pods "nginx2" is forbidden: exceeded quota: mem-cpu-quota, requested: requests.memory=700Mi, used: requests.memory=700Mi, limited: requests.memory=1Gi

D'après le résultat, on s'aperçoit bien que nous dépassons la limite du ResourceQuota mem-cpu-quota défini dans le namespace dev-team.

Tous les objets ne sont pas dans un namespace

La plupart des objets Kubernetes se trouvent dans certains namespace. Cependant, les objets de bas niveau, tel que les nodes ou les persistentVolumes, ne figurent dans aucun namespace.

Voici la commande qui permet de lister les objets Kubernetes qui sont et ne sont pas dans un namespace :

kubectl api-resources --namespaced=true

Résultat :

NAME                        SHORTNAMES   APIGROUP                    NAMESPACED   KIND
...
pods                        po                                       true         Pod
...
deployments                 deploy       extensions                  true         Deployment
roles                                    rbac.authorization.k8s.io   true         Role
kubectl api-resources --namespaced=false

Résultat :

NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
componentstatuses                 cs                                          false        ComponentStatus
namespaces                        ns                                          false        Namespace
...
storageclasses                    sc           storage.k8s.io                 false        StorageClass
volumeattachments                              storage.k8s.io                 false        VolumeAttachment

Conclusion

Pour conclure, les namespaces restent un très bon moyen pour gérer les différentes équipes qui utilisent votre cluster. En plus de l'objet ResourceQuota combiné avec les namespaces qui vous permettront de limiter davantage l'utilisation des ressources de vos objets Kubernetes.

Comme à mon habitude voici un aide-mémoire des commandes liées aux namespaces :

# Afficher la liste des namespaces
kubectl get namespaces

# Créer un namespace
kubectl create namespace <NAMESPACE NAME>
kubectl create -f <template.yaml>

# Créer un deployment dans un namespace
kubectl run nginx --image=nginx  --namespace=<NAMESPACE NAME>

# Supprimer un namespace
kubectl delete namespaces <NAMESPACE NAME>

# Afficher les détails d'un namespace
kubectl describe namespaces <NAMESPACE NAME>

# Utiliser un namespace par défaut
kubectl config set-context --current --namespace=<NAMESPACE NAME>

# Examiner le namespace par défaut
kubectl config view | grep namespace

# Lister les objets Kubernetes qui sont et ne sont pas dans un namespace
kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=false

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

25 commentaires

ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Si vous avez d'autres blocages sur vos quotas ou vos namespaces, postez ici, mais vérifiez d'abord si vos metadata sont bien configurées.

09/09/2019 à 01:25
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est mort. Une fois supprimé, tout ce qu'il contenait est purgé. Sauvegarde toujours tes manifestes en git.

08/09/2019 à 20:22
cschneider
Membre Actif
Avatar de cschneider
cschneider
Membre Actif

J'ai supprimé un namespace par erreur. Y'a un moyen de le restaurer ou c'est mort ?

08/09/2019 à 13:04
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

requests c'est ce qui est garanti au conteneur, limits c'est le plafond max autorisé. Ton quota contrôle les deux séparément.

08/09/2019 à 06:29
cmathieu
Membre Actif
Avatar de cmathieu
cmathieu
Membre Actif

C'est quoi la différence entre limits.cpu et requests.cpu dans le quota ?

08/09/2019 à 01:14
texier-honore
Membre Actif
Avatar de texier-honore
texier-honore
Membre Actif

C'est marqué dans l'article : kubectl config set-context --current --namespace=default.

07/09/2019 à 20:36
paul75
Membre Actif
Avatar de paul75
paul75
Membre Actif

Comment je reviens au namespace default après avoir fait un kubectl config set-context --current --namespace=prod-team ?

07/09/2019 à 13:32
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie que tes pods ont bien des resources.limits définis dans leur manifest. Si le pod n'a pas de limite, le quota ne peut pas calculer la somme totale correctement.

07/09/2019 à 06:41
vasseur-alexandria
Membre Actif
Avatar de vasseur-alexandria
vasseur-alexandria
Membre Actif

J'ai un souci avec mon ResourceQuota. J'ai défini limits.cpu: "2" mais je peux quand même lancer des pods qui demandent plus. Une idée ?

06/09/2019 à 23:15
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Non, la doc est claire là-dessus : les namespaces ne peuvent pas être imbriqués. Utilise plutôt des labels pour structurer tes ressources.

06/09/2019 à 16:40
oceane11
Membre Actif
Avatar de oceane11
oceane11
Membre Actif

Est-ce que je peux avoir des namespaces imbriqués ? Le besoin est de faire des sous-groupes par projet dans dev-team.

06/09/2019 à 09:28
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Édite ton fichier quota.yaml et applique la modification avec kubectl apply -f quota.yaml -n=dev-team. Le contrôleur mettra à jour la limite à chaud.

06/09/2019 à 02:08
marc20
Membre Actif
Avatar de marc20
marc20
Membre Actif

Mon ResourceQuota bloque tout, même les petits pods de test. Je veux l'augmenter, je fais comment ?

05/09/2019 à 20:56
techer-frederic
Membre Actif
Avatar de techer-frederic
techer-frederic
Membre Actif

Ajoute juste -A ou --all-namespaces à ta commande habituelle : kubectl get pods -A.

05/09/2019 à 15:02
pineau-stephane
Membre Actif
Avatar de pineau-stephane
pineau-stephane
Membre Actif

C'est quoi la commande pour voir tous les pods de tous les namespaces d'un coup ?

05/09/2019 à 10:35
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Parce que les PersistentVolumes sont des objets globaux, ils ne sont pas dans un namespace. Seuls les PersistentVolumeClaims peuvent être soumis à des quotas.

05/09/2019 à 05:02
hoareau-lorraine
Membre Actif
Avatar de hoareau-lorraine
hoareau-lorraine
Membre Actif

J'ai mis en place un quota sur le namespace dev-team mais il prend pas en compte mes PersistentVolumes. Pourquoi ?

04/09/2019 à 21:59
camus-sophie
Membre Actif
Avatar de camus-sophie
camus-sophie
Membre Actif

Utilise grep tout simplement, comme expliqué pour kubectl config view plus haut : kubectl api-resources --namespaced=true | grep pods.

04/09/2019 à 17:55
danielle56
Membre Actif
Avatar de danielle56
danielle56
Membre Actif

J'ai essayé de lister les objets avec kubectl api-resources --namespaced=true, mais ça me sort une liste énorme. Comment filtrer pour voir juste les pods ?

04/09/2019 à 12:00
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Non, c'est impossible. Un pod est lié à son namespace à la création. Il faut le supprimer et le recréer au bon endroit.

04/09/2019 à 04:51
timothee-bodin
Membre Actif
Avatar de timothee-bodin
timothee-bodin
Membre Actif

Est-ce qu'on peut changer le namespace d'un pod déjà actif sans le supprimer ?

03/09/2019 à 23:19
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est normal. Ton 403 signifie que tu as dépassé les limites définies dans ton ResourceQuota. Vérifie tes valeurs requests.memory par rapport à ce qui est déjà déployé.

03/09/2019 à 16:37
stephane38
Membre Actif
Avatar de stephane38
stephane38
Membre Actif

J'ai testé les ResourceQuota, mais je me fais jeter à chaque fois par le serveur. C'est bien du 403 Forbidden que je reçois.

03/09/2019 à 10:01
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie l'indentation de ton YAML. Le champ metadata doit être aligné correctement avec kind. Poste ton fichier ici si ça persiste.

03/09/2019 à 05:37
josette76
Membre Actif Secouriste
Avatar de josette76
josette76
Membre Actif Secouriste

Super article. Par contre j'ai un souci, quand je lance kubectl create -f namespace.yaml pour mon prod-team, ça me renvoie une erreur de syntaxe alors que mon fichier semble correct.

03/09/2019 à 00:17

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire