Imposer des quotas CPU et RAM par namespace dans Kubernetes

Dans Kubernetes, il est essentiel de contrôler l’utilisation des ressources, en particulier dans des environnements multi-tenant où plusieurs équipes ou services partagent les mêmes ressources. Pour cela, Kubernetes fournit un mécanisme appelé ResourceQuota qui permet d’imposer des limites sur la consommation des ressources (comme le CPU et la RAM) à l’échelle d’un namespace. Cela garantit que les Pods dans un namespace donné ne dépassent pas une certaine consommation et empêche une saturation des ressources du cluster.

Dans cet article, nous allons explorer :

  1. Comment configurer un quota CPU et RAM pour un namespace.
  2. Comment automatiser l’application des quotas à tous les namespaces.

Partie 1 : Imposer des quotas de ressources dans un namespace

Les ResourceQuotas sont des objets Kubernetes qui vous permettent de définir des limites maximales d’utilisation de certaines ressources (comme le CPU, la RAM ou le nombre de Pods) dans un namespace.

Étape 1 : Créer un fichier ResourceQuota YAML

Pour commencer, vous devez définir un fichier YAML contenant le quota de ressources que vous souhaitez imposer.

Créez un fichier nommé resource-quota.yaml avec le contenu suivant :

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-cpu-mem
  namespace: <nom-du-namespace>  # Remplacez par votre namespace
spec:
  hard:
    requests.cpu: "4"        # Maximum de 4 CPU demandés dans le namespace
    requests.memory: "8Gi"   # Maximum de 8 Gi de mémoire demandée
    limits.cpu: "8"          # Limite maximale de 8 CPU
    limits.memory: "16Gi"    # Limite maximale de 16 Gi de mémoire

Explication :

  • requests.cpu et requests.memory : Ce sont les ressources réservées que les Pods peuvent demander. Si ces limites sont atteintes, plus aucun Pod ne pourra être programmé dans le namespace sans dépasser le quota.
  • limits.cpu et limits.memory : Ces valeurs définissent la consommation maximale de CPU et de mémoire qu’un Pod peut atteindre.

Étape 2 : Appliquer le ResourceQuota

Une fois le fichier YAML créé, appliquez-le à votre namespace avec la commande suivante :

kubectl apply -f resource-quota.yaml

Cela imposera des quotas à ce namespace spécifique. Les nouveaux Pods qui demanderont plus de ressources que le quota ne pourront pas être créés.

Étape 3 : Vérifier les quotas appliqués

Pour vérifier les quotas appliqués à un namespace, utilisez la commande suivante :

kubectl get resourcequota -n <nom-du-namespace>

Cela affichera le quota de ressources appliqué ainsi que l’utilisation actuelle des ressources.

Exemple de retour :

NAME             CREATED AT
quota-cpu-mem    2024-10-01T10:30:00Z

Pour obtenir des détails sur l’utilisation des ressources par rapport aux quotas :

kubectl describe resourcequota quota-cpu-mem -n <nom-du-namespace>

Partie 2 : Appliquer automatiquement des quotas à tous les namespaces

Si vous gérez un cluster où plusieurs équipes ou services créent régulièrement de nouveaux namespaces, il peut être fastidieux d’appliquer manuellement les quotas à chaque namespace. Pour automatiser cette tâche, vous pouvez utiliser un script Bash ou un Admission Controller comme OPA Gatekeeper ou Kyverno.

Option 1 : Utiliser un script Bash pour appliquer les quotas à tous les namespaces existants

Voici un exemple de script qui applique un quota de ressources à tous les namespaces existants dans le cluster :

#!/bin/bash
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}')
do
  kubectl apply -f <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-cpu-mem
  namespace: $ns
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
EOF
done

Explication :

  • Ce script parcourt tous les namespaces du cluster et applique un ResourceQuota identique à chacun d’eux.
  • Vous pouvez exécuter ce script régulièrement pour vous assurer que les quotas sont appliqués même sur les nouveaux namespaces créés après l’exécution initiale.

Option 2 : Utiliser Kyverno pour automatiser l’application

Un autre moyen plus puissant et flexible pour appliquer automatiquement des quotas est d’utiliser OPA Gatekeeper ou Kyverno. Ces outils permettent de définir des politiques d’admission qui forcent certaines configurations à être appliquées à chaque namespace.

Voici un exemple de politique Kyverno qui impose un quota à tous les namespaces :

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: enforce-quota
spec:
  rules:
  - name: enforce-resourcequota
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: ResourceQuota
      name: quota-cpu-mem
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      spec:
        hard:
          requests.cpu: "4"
          requests.memory: "8Gi"
          limits.cpu: "8"
          limits.memory: "16Gi"

Étapes d’installation pour Kyverno :

  1. Installez Kyverno avec Helm (si vous ne l’avez pas déjà fait) :
   helm repo add kyverno https://kyverno.github.io/kyverno/
   helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace
  1. Appliquez la politique avec la commande suivante :
   kubectl apply -f enforce-quota.yaml

Avec cette politique, chaque fois qu’un nouveau namespace est créé, un quota sera automatiquement appliqué.


Conclusion

Les quotas de ressources sont essentiels pour garantir une utilisation équitable des ressources dans un cluster Kubernetes multi-tenant. En utilisant des ResourceQuotas, vous pouvez contrôler la consommation de CPU et de mémoire dans chaque namespace. Si vous devez appliquer ces quotas à plusieurs namespaces, vous pouvez utiliser des scripts d’automatisation ou des outils comme Kyverno pour imposer ces quotas automatiquement dès la création d’un namespace.

Avec ces outils et techniques, vous assurez que votre cluster Kubernetes reste performant et que les ressources sont réparties équitablement entre les différents utilisateurs ou services.


Pour aller plus loin