## 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 :

```bash
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 :

```bash
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à :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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` :

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: team-c
  labels:
    tenant: team-c
    environment: production
```

Appliquez-le :

```bash
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` :

```yaml
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 :

```bash
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` :

```yaml
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 :

```yaml
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 :

```bash
kubectl apply -f role.yaml -f rolebinding.yaml
```

Vérifiez :

```bash
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` :

```yaml
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 :

```bash
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` :

```bash
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 :

```yaml
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 :

```bash
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 :

```bash
kubectl run web --image=nginx -n team-c
kubectl expose pod web --port=80 -n team-c
```

Depuis `team-b`, essayez de l'atteindre :

```bash
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 :

1. Vérifiez le statut du pod :

```bash
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.

2. Décrivez le pod :

```bash
kubectl describe pod <pod-name> -n team-c
```

Regardez la section `Events` pour des messages comme `FailedScheduling` ou `Insufficient memory`.

3. Consultez les journaux du pod :

```bash
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.

4. Vérifiez le statut du déploiement :

```bash
kubectl rollout status deployment/<deployment-name> -n team-c
```

Si le déploiement est bloqué, inspectez les réplicas et les événements.

5. Affichez l'utilisation du quota de ressources :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
kubectl get all -n team-c
```

- Forcez la suppression en patchant le namespace pour supprimer les finaliseurs (à utiliser avec une extrême prudence) :

```bash
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-i` en 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 :

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