Introduction
La multi-location Kubernetes permet à plusieurs équipes, applications ou clients de partager un même cluster tout en restant isolés les uns des autres. Maîtriser les bases ne se résume pas à copier des commandes. Vous devez savoir ce que fait chaque commande, quelle sortie attendre et quoi faire en cas de problème.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui ont besoin de compétences pratiques en ligne de commande pour gérer des clusters multi-locataires. Il couvre les commandes essentielles avec des exemples réels, les sorties attendues, les signaux d'échec et les étapes de récupération. Vous apprendrez à inspecter votre environnement, appliquer des changements de configuration en toute sécurité, vérifier l'isolation des locataires et diagnostiquer les problèmes courants.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et savoir récupérer si l'état attendu n'est pas atteint.
Inventaire de version et d'environnement
Avant d'exécuter toute commande de multi-location, sachez avec quoi vous travaillez. Vérifiez votre version de Kubernetes, le contexte actuel et les namespaces existants. Cela vous évite d'exécuter des commandes sur le mauvais cluster ou d'impacter accidentellement d'autres locataires.
Vérifier la version du cluster et la disponibilité de l'API
Exécutez :
kubectl version --short
La sortie attendue ressemble à :
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
La version du serveur indique quelles ressources d'API sont disponibles. Les fonctionnalités de multi-location comme ResourceQuota et NetworkPolicy sont stables depuis les premières versions, mais des fonctionnalités plus récentes comme les namespaces hiérarchiques (HNC) nécessitent la v1.20+ et ne sont pas activées par défaut.
Vérifier le contexte actuel
Confirmez toujours sur quel cluster et namespace vous opérez :
kubectl config current-context
Exemple de sortie attendue :
gke_my-project_us-central1-a_production-cluster
Si cela affiche un cluster de développement ou de test alors que vous attendiez la production, arrêtez-vous. Changer de contexte par erreur est une cause fréquente d'impact accidentel sur les locataires.
Lister les namespaces existants
La multi-location commence souvent par une isolation au niveau des namespaces. Voyez quels namespaces existent déjà :
kubectl get namespaces
Exemple de sortie attendue :
NAME STATUS AGE
default Active 210d
kube-system Active 210d
kube-public Active 210d
team-a Active 45d
team-b Active 45d
Chaque locataire doit avoir au moins un namespace dédié. Évitez de placer des charges de travail des locataires dans default ou kube-system.
Inspecter la répartition actuelle des pods et services
Voyez une vue globale des pods :
kubectl get pods --all-namespaces -o wide
Cela montre quels pods appartiennent à quel namespace et nœud. Cela vous aide à repérer les locataires qui sont colocalisés ou consomment des ressources inhabituelles.
Pour un examen plus approfondi d'un pod spécifique :
kubectl describe pod <pod-name> -n <namespace>
Recherchez Node-Selectors, Tolerations et Resource Requests/Limits. Dans un environnement multi-locataire, ils doivent être définis pour éviter les problèmes de voisin bruyant.
Vérifier les quotas de ressources
Les quotas de ressources sont essentiels pour un partage équitable. Listez-les dans tous les namespaces :
kubectl get resourcequota --all-namespaces
Exemple de sortie attendue :
NAMESPACE NAME AGE REQUEST LIMIT
team-a team-a-quota 10d requests.cpu: 0/4, requests.memory: 0/8Gi limits.cpu: 0/8, limits.memory: 0/16Gi
team-b team-b-quota 10d requests.cpu: 0/2, requests.memory: 0/4Gi limits.cpu: 0/4, limits.memory: 0/8Gi
Si aucun quota n'existe, les locataires peuvent consommer des ressources illimitées et affamer les autres.
Inspecter les liaisons RBAC
Le contrôle d'accès basé sur les rôles (RBAC) détermine qui peut faire quoi dans chaque namespace de locataire. Listez les liaisons de rôles pour un namespace :
kubectl get rolebindings -n team-a
Sortie attendue :
NAME ROLE AGE
team-a-admins ClusterRole/admin 30d
team-a-devs Role/developer 30d
Cela vous indique quels utilisateurs ou groupes ont accès. Trop de liaisons vers des rôles hautement privilégiés est un risque de sécurité.
Chemin de configuration sécurisé
Faire des changements dans un cluster partagé requiert de la prudence. Suivez un chemin qui minimise les risques : définissez l'état souhaité dans un manifeste, validez-le, appliquez-le à un namespace de test et vérifiez le résultat avant de déployer sur les locataires de production.
Utilisez des manifestes YAML, jamais des commandes impératives ponctuelles
Les commandes impératives comme kubectl create namespace team-c sont rapides mais non reproductibles. Utilisez des manifestes déclaratifs stockés dans un contrôle de version.
Exemple de manifeste de namespace team-c-namespace.yaml :
apiVersion: v1
kind: Namespace
metadata:
name: team-c
labels:
tenant: team-c
environment: production
Appliquez-le :
kubectl apply -f team-c-namespace.yaml
Sortie attendue :
namespace/team-c created
Maintenant kubectl get namespace team-c devrait afficher Active.
Définir des quotas de ressources pour un locataire
Créez une ResourceQuota pour limiter le CPU et la mémoire des pods dans team-c :
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-c-quota
namespace: team-c
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
Appliquez et vérifiez :
kubectl apply -f team-c-quota.yaml
kubectl get resourcequota -n team-c
Sortie attendue :
NAME AGE REQUEST LIMIT
team-c-quota 5s requests.cpu: 0/4, requests.memory: 0/8Gi limits.cpu: 0/8, limits.memory: 0/16Gi, pods: 0/20
Restreindre l'accès avec RBAC
Créez un rôle qui autorise la lecture seule des pods dans team-c :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-c
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Liez-le à un groupe d'équipe de développement :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-c-devs-read-pods
namespace: team-c
subjects:
- kind: Group
name: team-c-devs
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Appliquez les deux :
kubectl apply -f role.yaml -f rolebinding.yaml
Vérifiez :
kubectl auth can-i get pods -n team-c --as system:serviceaccount:default:test-user
Sortie attendue si autorisé :
yes
Isoler le trafic réseau avec NetworkPolicy
Par défaut, tous les pods d'un cluster peuvent communiquer entre eux. Dans les environnements multi-locataires, vous devez refuser tout trafic entre namespaces sauf autorisation explicite.
Exemple de refus par défaut pour team-c :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: team-c
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Cela bloque tout trafic entrant et sortant pour les pods dans team-c. Vous ajoutez ensuite des règles d'autorisation spécifiques.
Tester d'abord dans un namespace de préproduction
N'appliquez jamais les changements de multi-location directement aux namespaces de production. Utilisez une copie du namespace de production avec un suffixe comme -staging. Après avoir appliqué et vérifié en préproduction, déployez en production.
Exemple de flux :
kubectl create namespace team-c-staging
kubectl apply -f team-c-namespace.yaml -n team-c-staging
kubectl apply -f team-c-quota.yaml -n team-c-staging
kubectl apply -f role.yaml -n team-c-staging
kubectl apply -f rolebinding.yaml -n team-c-staging
kubectl apply -f networkpolicy.yaml -n team-c-staging
Ensuite, exécutez des tests pour confirmer que l'isolation fonctionne comme prévu.
Vérification et diagnostic
Après avoir appliqué la configuration, vérifiez que chaque mécanisme d'isolation fonctionne. Ne supposez pas que parce qu'un manifeste s'est appliqué sans erreur, la politique est correctement appliquée. Testez activement les limites.
Vérifier l'isolation des namespaces
Vérifiez que les pods d'un namespace ne peuvent pas être listés depuis un autre namespace en utilisant un compte de service qui n'a pas les permissions inter-namespaces.
Créez un compte de service dans team-a et essayez de lister les pods dans team-b :
kubectl create serviceaccount sa-test -n team-a
kubectl auth can-i list pods -n team-b --as system:serviceaccount:team-a:sa-test
Sortie attendue :
no
Si yes, les permissions RBAC sont trop larges.
Tester l'application des quotas de ressources
Essayez de créer un pod dans team-c qui dépasse le quota de mémoire. Exemple de pod avec une demande de mémoire de 20Gi alors que la limite du quota est de 16Gi :
apiVersion: v1
kind: Pod
metadata:
name: test-memory-exceed
namespace: team-c
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
memory: 20Gi
limits:
memory: 20Gi
Tentez de le créer :
kubectl apply -f test-pod.yaml
Erreur attendue :
Error from server (Forbidden): error when creating "test-pod.yaml": pods "test-memory-exceed" is forbidden: exceeded quota: team-c-quota, requested: limits.memory=20Gi, used: limits.memory=0, limited: limits.memory=16Gi
Cela prouve que le quota fonctionne.
Tester l'application des politiques réseau
Déployez deux pods dans des namespaces différents et vérifiez la connectivité.
Dans team-c, exécutez un pod serveur web simple :
kubectl run web --image=nginx -n team-c
kubectl expose pod web --port=80 -n team-c
Depuis team-b, essayez de l'atteindre :
kubectl run test-pod --image=busybox -n team-b --restart=Never -- sleep 3600
kubectl exec -n team-b test-pod -- wget -qO- --timeout=5 http://web.team-c.svc.cluster.local
Résultat attendu : la commande expire ou échoue car la politique de refus par défaut dans team-c bloque l'entrée depuis team-b.
Commandes de diagnostic pour les problèmes courants
Lorsque quelque chose échoue, rassemblez les informations de manière systématique :
- Vérifiez le statut du pod :
kubectl get pods -n team-c
Si un pod est en Pending, cela peut être dû à l'épuisement du quota de ressources ou à la pression sur les nœuds.
- Décrivez le pod :
kubectl describe pod <pod-name> -n team-c
Regardez la section Events pour des messages comme FailedScheduling ou Insufficient memory.
- Consultez les journaux du pod :
kubectl logs <pod-name> -n team-c --previous
Cela montre les journaux d'un conteneur précédemment planté, utile pour diagnostiquer les boucles de crash.
- Vérifiez le statut du déploiement :
kubectl rollout status deployment/<deployment-name> -n team-c
Si le déploiement est bloqué, inspectez les réplicas et les événements.
- Affichez l'utilisation du quota de ressources :
kubectl describe resourcequota team-c-quota -n team-c
Cela montre l'utilisation actuelle par rapport aux limites, vous aidant à voir si un locataire est à pleine capacité.
Modes d'échec et récupération
Même avec une planification minutieuse, des problèmes surviennent. Voici des modes d'échec courants dans la multi-location Kubernetes et comment récupérer.
Épuisement du quota
Symptôme : Les nouveaux pods dans un namespace de locataire restent en état Pending avec des événements comme :
FailedScheduling: 0/3 nodes are available: 3 Insufficient cpu.
Ou vous obtenez une erreur lors de la création d'un pod :
Error from server (Forbidden): pods "my-pod" is forbidden: exceeded quota: team-c-quota
Cause : Le locataire a atteint ses limites de CPU ou de mémoire.
Récupération :
- Identifiez quelle ressource est épuisée :
kubectl describe resourcequota team-c-quota -n team-c. - Vérifiez l'utilisation réelle :
kubectl top pods -n team-c(si le serveur de métriques est installé). - Décidez s'il faut augmenter le quota ou réduire les charges de travail.
- Pour augmenter temporairement le quota, modifiez la ResourceQuota :
kubectl edit resourcequota team-c-quota -n team-c
Augmentez requests.cpu de 4 à 6 et enregistrez. Mais cela doit être une action délibérée, pas un défaut.
Accès réseau inter-locataires
Symptôme : Un pod dans team-b peut atteindre les services dans team-a alors que vous vouliez l'isolation.
Cause : NetworkPolicy manquante ou permissive, ou une politique qui autorise tout le trafic entrant.
Récupération :
- Listez les NetworkPolicies dans les deux namespaces :
kubectl get networkpolicy -n team-a
kubectl get networkpolicy -n team-b
- Si aucune n'existe, appliquez des politiques de refus par défaut.
- Si des politiques existent, inspectez-les :
kubectl describe networkpolicy <policy-name> -n team-a
- Ajustez la politique pour refuser le trafic inter-namespaces tout en autorisant les communications nécessaires (par exemple, depuis le contrôleur d'entrée).
RBAC trop permissif
Symptôme : Un utilisateur ou un compte de service peut lister les secrets ou supprimer des pods dans un namespace auquel il ne devrait pas avoir accès.
Cause : Une liaison de rôle a attribué un rôle de cluster comme admin ou cluster-admin à un groupe large.
Récupération :
- Examinez les liaisons de rôles :
kubectl get rolebindings -n team-a
kubectl get clusterrolebindings | grep team-a
- Trouvez le sujet qui ne devrait pas avoir accès et supprimez la liaison :
kubectl delete rolebinding <binding-name> -n team-a
- Remplacez par un rôle ou une liaison de rôle plus restrictif.
Suppression de namespace bloquée
Symptôme : kubectl delete namespace team-c se bloque et le namespace reste en état Terminating.
Cause : Des finaliseurs ou des ressources dans le namespace qui ne peuvent pas être supprimés.
Récupération :
- Vérifiez le statut du namespace :
kubectl get namespace team-c -o yaml
- Cherchez le champ
finalizers. S'il y a un finaliseur personnalisé, vous devrez peut-être le supprimer après vous être assuré que les tâches de nettoyage sont terminées. - Listez les ressources restantes :
kubectl get all -n team-c
- Forcez la suppression en patchant le namespace pour supprimer les finaliseurs (à utiliser avec une extrême prudence) :
kubectl patch namespace team-c -p '{"spec":{"finalizers":[]}}' --type=merge
Cela ne doit être fait que lorsque vous êtes sûr qu'aucune ressource externe n'en dépend.
Liste de contrôle des opérations
Utilisez cette liste de contrôle avant, pendant et après avoir apporté des modifications de multi-location. Attribuez un responsable à chaque élément et révisez la liste au moins une fois par mois, ou après tout incident.
Liste de contrôle avant modification
- [ ] Confirmer le contexte de cluster correct :
kubectl config current-context. Responsable : Priya Shah, responsable ingénierie. Révision : mensuelle. - [ ] Sauvegarder les RBAC, quotas et politiques réseau actuels :
kubectl get rolebindings,resourcequota,networkpolicy -n <namespace> -o yaml > backup.yaml. Responsable : DevOps de garde. Révision : hebdomadaire. - [ ] Identifier le rayon d'impact : quels autres namespaces ou services pourraient être affectés ? Responsable : DevOps de garde. Révision : à chaque modification.
- [ ] Préparer un plan de retour en arrière : enregistrer les manifestes originaux dans git. Responsable : DevOps de garde. Révision : à chaque modification.
- [ ] Obtenir l'approbation du propriétaire du locataire si la modification affecte son namespace. Responsable : responsable du locataire (par exemple, responsable de l'équipe A). Révision : à chaque modification.
Pendant la modification
- [ ] Appliquer d'abord au namespace de préproduction :
kubectl apply -f manifest.yaml -n team-c-staging. Responsable : DevOps de garde. Révision : immédiate. - [ ] Vérifier la sortie attendue : exécuter les commandes de vérification listées ci-dessus. Responsable : DevOps de garde. Révision : immédiate.
- [ ] Surveiller les métriques du cluster pour des changements inattendus :
kubectl top pods --all-namespaces. Responsable : SRE de garde. Révision : continue.
Après la modification
- [ ] Confirmer que les quotas de ressources sont appliqués : essayer de créer un pod qui dépasse le quota et s'attendre à un échec. Responsable : DevOps de garde. Révision : après chaque modification.
- [ ] Tester les permissions RBAC : utiliser
kubectl auth can-ien tant que compte de service de test. Responsable : ingénieur sécurité (par exemple, Marcus Lee). Révision : trimestrielle. - [ ] Tester l'isolation réseau : tenter une connexion inter-namespaces depuis un pod de test. Responsable : ingénieur sécurité. Révision : trimestrielle.
- [ ] Documenter tout écart par rapport au comportement attendu. Responsable : DevOps de garde. Révision : après chaque modification.
- [ ] Mettre à jour les procédures avec les nouvelles étapes de récupération. Responsable : rédacteur technique (par exemple, Alex Kim). Révision : mensuelle.
Pièges courants et comment les éviter
Évitez ces erreurs fréquentes dans la multi-location Kubernetes.
Piège 1 : Utiliser un seul namespace pour tous les locataires
Pourquoi cela arrive : Plus facile à gérer au début, mais conduit à des conflits de ressources et des problèmes de sécurité.
Comment l'éviter : Créez un namespace par locataire dès le premier jour. Appliquez avec un contrôleur d'admission ou un moteur de politiques.
Récupération : Si déjà dans un seul namespace, planifiez une migration. Créez de nouveaux namespaces, définissez des quotas et des RBAC, puis déplacez les charges de travail progressivement.
Piège 2 : Ignorer les demandes et limites de ressources
Pourquoi cela arrive : Les équipes les omettent pour simplifier le YAML, mais cela permet à un voisin bruyant de consommer toutes les ressources.
Comment l'éviter : Exigez des demandes et limites de ressources via des politiques d'admission (par exemple, LimitRange). Exemple de LimitRange :
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-c
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 250m
memory: 256Mi
type: Container
Appliquez et vérifiez : kubectl get limitrange -n team-c.
Récupération : Ajoutez des LimitRange aux namespaces existants et mettez à jour les déploiements pour inclure les ressources.
Piège 3 : Rôles RBAC trop larges
Pourquoi cela arrive : Réutiliser cluster-admin par commodité.
Comment l'éviter : Suivez le principe du moindre privilège. Utilisez Role pour les permissions limitées au namespace ; ne liez jamais cluster-admin au groupe d'un locataire.
Récupération : Auditez avec kubectl get clusterrolebindings -o yaml et supprimez les liaisons risquées.
Piège 4 : Pas de politiques réseau
Pourquoi cela arrive : Par défaut, Kubernetes autorise tout le trafic de pod à pod, et beaucoup supposent que l'isolation est automatique.
Comment l'éviter : Définissez des politiques de refus par défaut pour chaque namespace de locataire et autorisez explicitement le trafic requis.
Récupération : Appliquez des NetworkPolicies et testez la connectivité comme décrit précédemment.
Piège 5 : Ne pas tester en préproduction
Pourquoi cela arrive : La pression de livrer rapidement conduit à des modifications directes en production.
Comment l'éviter : Faites de la préproduction une exigence dans votre processus de modification et utilisez CI/CD pour l'appliquer.
Récupération : Si une modification casse la production, revenez au manifeste précédent depuis le contrôle de version : kubectl apply -f previous-manifest.yaml après avoir annulé dans git.
Conclusion
Les commandes de multi-location Kubernetes ne sont utiles que si elles sont limitées à la version, observables et réversibles. Copier des commandes sans comprendre les prérequis et la sortie attendue n'est pas une pratique opérationnelle fiable.
Commencez par une vérification à faible risque : choisissez un namespace de locataire, enregistrez son état actuel, exécutez les vérifications documentées, comparez le résultat avec le signal attendu et examinez les dépendances comme le Namespace, la Resource Quota et le RBAC.
Un flux de travail fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. En appliquant les commandes et les listes de contrôle de cet article, vous pouvez maintenir un cluster multi-locataire stable et sécurisé.