## Introduction

Kubernetes Server-Side Apply (SSA) modifie la façon dont la configuration est fusionnée et stockée, ce qui transforme la planification de capacité. Au lieu d’un patch côté client qui peut silencieusement abandonner des champs, SSA envoie une intention entièrement spécifiée au serveur d’API, qui la fusionne ensuite avec l’état existant de l’objet en utilisant la gestion des champs. Cela offre une meilleure détection des conflits et une propriété prévisible, mais cela signifie aussi plus de travail pour le serveur d’API, plus de données stockées dans etcd et plus de précautions lors des déploiements à grande échelle.

Cet article est un guide pratique de planification de capacité pour Server-Side Apply. Il s’adresse aux développeurs, consultants DevOps et équipes de plateforme de startups qui exploitent déjà Kubernetes et souhaitent adopter ou opérer SSA en toute sécurité. Vous apprendrez à évaluer votre environnement actuel, dimensionner les ressources pour les charges de travail SSA, définir des limites et vérifier que votre cluster reste sain sous charge.

Nous utiliserons des commandes concrètes et des exemples de sorties tout au long de l’article. Nous nous référerons à un petit cluster de référence (trois nœuds du plan de contrôle, etcd colocalisé, 50 nœuds de travail, environ 2 000 namespaces). Tous les chiffres sont illustratifs et doivent être adaptés à votre environnement.

## 1. Inventaire des versions et de l’environnement

Avant d’apporter des modifications, sachez exactement ce que vous exécutez. Server-Side Apply est en version bêta depuis Kubernetes 1.16 et stable depuis 1.22, mais son comportement a subtilement changé entre les versions. Le drapeau `kubectl apply --server-side` utilise SSA, et l’implémentation de la gestion des champs dépend de la version du serveur d’API.

### Vérifier la version de Kubernetes

Exécutez ceci sur un nœud du plan de contrôle ou via kubectl :

```bash
kubectl version --short
```

Sortie attendue (exemple) :

```
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.3
```

Si votre serveur est antérieur à 1.22, SSA est toujours disponible en bêta, mais envisagez une mise à niveau. Pour la planification de capacité en production, considérez que SSA n’est stable qu’à partir de 1.22.

### Identifier l’utilisation de SSA

SSA est utilisé implicitement par de nombreux outils (`kubectl apply --server-side`, kustomize avec application côté serveur, les outils GitOps comme Argo CD et Flux, et les contrôleurs). Pour voir si votre cluster utilise activement SSA, vérifiez le champ `managedFields` sur n’importe quel objet. Chaque objet créé via SSA possède des entrées de champs gérés avec un nom de gestionnaire.

Exemple :

```bash
kubectl get deployment my-app -o yaml | grep -A5 managedFields
```

Si vous voyez des entrées comme `manager: kubectl-client-side-apply` ou `manager: argocd-application-controller`, cela indique une utilisation de SSA. Le nom du gestionnaire vous indique quel outil applique la configuration.

### Prérequis pour une exploitation sûre de SSA

- **Kubernetes 1.22+** : SSA stable.
- **kubectl 1.22+** : nécessaire pour le drapeau `--server-side`.
- **API Priority and Fairness (APF)** : les requêtes SSA sont des requêtes API normales, mais si vous prévoyez de nombreuses applications simultanées, vérifiez la configuration APF.
- **Capacité etcd** : SSA écrit plus de données dans etcd en raison des champs gérés. Surveillez la taille de la base de données etcd.

Vérifiez le statut APF :

```bash
kubectl get flowschemas.flowcontrol.apiserver.k8s.io
```

Si aucune ressource n’est retournée, votre cluster utilise peut-être les paramètres par défaut ; assurez-vous d’avoir au moins les flowschemas par défaut.

### Observation en lecture seule d’abord

Ne changez rien pour l’instant. Capturez les métriques de référence :

- Taux de requêtes et latence du serveur d’API
- Taille de la base de données etcd
- Nombre d’entrées de champs gérés par type d’objet

Utilisez les commandes suivantes pour vous faire une idée de l’état actuel :

```bash
kubectl get --raw /metrics | grep apiserver_request_total
kubectl get --raw /metrics | grep etcd_db_total_size_in_bytes
```

Enregistrez ces valeurs avant de déployer largement SSA.

### Rayon d’impact et chemin de récupération

Les changements SSA ne sont pas intrinsèquement plus dangereux que l’application côté client, mais ils peuvent créer des conflits si plusieurs gestionnaires tentent de posséder le même champ. Commencez par un seul namespace de test et un seul Deployment avant d’activer SSA pour l’ensemble de votre pipeline GitOps.

## 2. Chemin de configuration sûr

L’adoption de SSA doit être progressive. Le chemin suivant minimise les risques et vous donne un retour d’information précoce.

### Étape 1 : Activer SSA pour un seul objet

Prenez un manifeste de Deployment existant et appliquez-le avec le drapeau côté serveur :

```bash
kubectl apply --server-side -f deployment.yaml
```

Sortie attendue :

```
deployment.apps/my-app serverside-applied
```

Si vous voyez `deployment.apps/my-app configured` ou `unchanged`, c’est également acceptable. Mais notez : avec `--server-side`, kubectl n’affiche pas d’avertissement si l’objet est inchangé.

### Étape 2 : Vérifier les champs gérés

Vérifiez que le gestionnaire est correctement enregistré :

```bash
kubectl get deployment my-app -o yaml | grep -B2 -A10 managedFields
```

Recherchez une entrée avec `manager: kubectl-client-side-apply` (ou le nom que vous avez défini). Confirmez que l’opération est `Apply`.

### Étape 3 : Éviter les conflits

Les conflits SSA surviennent lorsqu’un autre gestionnaire possède un champ que vous essayez de modifier et que vous ne forcez pas le changement. Testez la détection de conflit :

Appliquez une modification à un champ possédé par un autre gestionnaire sans `--force-conflicts` :

```bash
kubectl apply --server-side -f modified-deployment.yaml
```

Sortie attendue (conflit) :

```
error: Apply failed with 1 conflict: conflict with "kubectl-client-side-apply" using apps/v1: .spec.replicas
```

C’est une bonne chose : cela vous indique exactement quel champ est contesté. Résolvez en vous coordonnant avec l’autre gestionnaire ou, si vous êtes certain, ajoutez `--force-conflicts`.

### Étape 4 : Utiliser un nom de gestionnaire dédié

En production, ne vous fiez pas au nom de gestionnaire par défaut dérivé de l’outil. Définissez un nom de gestionnaire significatif pour suivre la propriété :

```bash
kubectl apply --server-side --field-manager=platform-team -f deployment.yaml
```

Vérifiez ensuite :

```bash
kubectl get deployment my-app -o yaml | grep 'manager: platform-team'
```

### Étape 5 : Intégrer avec GitOps

Si vous utilisez Argo CD, activez l’application côté serveur dans la spécification de l’Application :

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
spec:
  syncPolicy:
    syncOptions:
    - ServerSideApply=true
```

Pour Flux, définissez `--server-side-apply` dans les drapeaux du kustomize-controller ou du helm-controller.

### Considérations de capacité pendant le déploiement

SSA génère des objets plus volumineux en raison des métadonnées de champs gérés. Un Deployment qui faisait 2 Ko avec l’application côté client peut devenir 3 à 4 Ko avec SSA. Multipliez cela par le nombre d’objets que vous gérez et vous pouvez estimer le stockage etcd supplémentaire. Pour notre cluster de référence (2 000 namespaces, en moyenne 50 objets par namespace = 100 000 objets), une augmentation de 2 Ko par objet signifie 200 Mo de données etcd supplémentaires. C’est généralement gérable, mais vous devez surveiller la taille d’etcd.

Vérifiez la taille d’etcd :

```bash
kubectl get --raw /metrics | grep etcd_db_total_size_in_bytes
```

Comparez avant et après l’activation de SSA pour un sous-ensemble d’objets.

## 3. Vérification et diagnostics

Après avoir appliqué SSA, vérifiez que vos objets sont sains et que le serveur d’API n’est pas submergé.

### Vérification au niveau de l’objet

Pour chaque objet critique, vérifiez :

- Les conditions d’état
- Les événements
- Le nombre de réplicas

Exemple pour un Deployment :

```bash
kubectl rollout status deployment/my-app
kubectl describe deployment my-app
kubectl get events --field-selector involvedObject.name=my-app
```

### Performance du serveur d’API

SSA charge davantage le serveur d’API car il doit calculer la propriété des champs et fusionner. Surveillez ces métriques :

- `apiserver_request_duration_seconds` (p99)
- `apiserver_request_total`
- `apiserver_current_inflight_requests`

Obtenez un aperçu rapide :

```bash
kubectl get --raw /metrics | grep apiserver_current_inflight_requests
```

Exemple de sortie attendue :

```
# HELP apiserver_current_inflight_requests Maximal number of currently used inflight request limit of this apiserver per request kind in last second.
# TYPE apiserver_current_inflight_requests gauge
apiserver_current_inflight_requests{requestKind="mutating"} 12
apiserver_current_inflight_requests{requestKind="readOnly"} 5
```

Si les requêtes mutantes en vol sont constamment élevées (par exemple, > 80 % de votre limite APF), vous devrez peut-être ajuster APF ou faire évoluer le serveur d’API.

### Diagnostiquer les conflits SSA

Les conflits peuvent provoquer des échecs de synchronisation dans GitOps. Lorsqu’une synchronisation échoue, inspectez le statut de l’Application et les événements :

```bash
kubectl get application my-app -o yaml | grep -A20 status.conditions
kubectl get events --field-selector involvedObject.name=my-app
```

Recherchez des messages comme `Apply failed with N conflicts`. Identifiez les champs en conflit et les gestionnaires, puis décidez s’il faut forcer ou ajuster la propriété.

### Test de stress de capacité

Pour comprendre comment SSA affecte votre cluster, effectuez un test de charge contrôlé. Créez un script qui applique une centaine de ConfigMaps avec SSA en boucle et mesurez la latence du serveur d’API et la croissance d’etcd.

Boucle simplifiée (à exécuter dans un namespace de test) :

```bash
for i in {1..100}; do
  kubectl apply --server-side -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-$i
  namespace: test-ssa
data:
  key: value$i
EOF
done
```

Pendant l’exécution, surveillez les métriques du serveur d’API et la taille d’etcd. Cela vous donne des données empiriques pour la planification de capacité.

### Liste de contrôle pour le diagnostic

- [ ] Objet appliqué avec succès avec `--server-side` ?
- [ ] Les champs gérés affichent le bon gestionnaire ?
- [ ] Pas de conflits inattendus ?
- [ ] Latence p99 du serveur d’API dans les limites du SLI ?
- [ ] Taille d’etcd augmentée approximativement comme prévu ?
- [ ] Synchronisation GitOps terminée sans problème ?

## 4. Modes de défaillance et récupération

Même avec une planification minutieuse, des échecs surviennent. Voici les modes de défaillance courants de SSA et comment les récupérer.

### Mode de défaillance 1 : Conflit lors de l’application

**Symptôme** : `kubectl apply --server-side` renvoie une erreur listant les champs en conflit.

**Cause** : Un autre gestionnaire possède déjà ces champs. Cela peut être un contrôleur, une application côté client précédente ou l’outil GitOps d’une autre équipe.

**Récupération** :

- Identifiez le propriétaire actuel : `kubectl get <resource> -o yaml | grep -A10 managedFields`
- Si le propriétaire ne devrait pas gérer le champ, coordonnez-vous avec lui ou utilisez `--force-conflicts` pour prendre possession.
- S’il s’agit d’un champ système (par exemple, le statut), ne forcez pas ; structurez plutôt votre manifeste pour éviter de définir ce champ.

### Mode de défaillance 2 : Objet non appliqué en raison d’une erreur de dry-run

**Symptôme** : Le dry-run de SSA (par défaut pour kubectl apply) échoue avec une erreur de validation.

**Cause** : Le manifeste contient un champ ou un type invalide.

**Récupération** :

- Exécutez `kubectl apply --server-side --dry-run=server -f manifest.yaml -o yaml` pour voir la réponse du serveur.
- Corrigez le manifeste en fonction du message d’erreur.

### Mode de défaillance 3 : Surcharge du serveur d’API

**Symptôme** : Augmentation de la latence du serveur d’API, délais d’attente ou réponses 503 lors d’applications massives.

**Cause** : Trop de requêtes SSA simultanées, en particulier avec de grands objets ou de nombreux champs gérés, épuisant les files d’attente APF ou le CPU.

**Récupération** :

- Réduisez la concurrence dans votre outil GitOps (par exemple, les paramètres de parallélisme d’Argo CD).
- Augmentez les ressources du serveur d’API ou ajoutez des réplicas.
- Examinez les niveaux de priorité APF et ajustez si nécessaire.
- Envisagez de regrouper les applications ou d’utiliser l’application côté serveur uniquement pour les objets qui en bénéficient.

### Mode de défaillance 4 : Croissance trop rapide de la base de données etcd

**Symptôme** : La taille de la base de données etcd augmente rapidement, pouvant atteindre le quota par défaut de 8 Go.

**Cause** : Métadonnées de champs gérés ajoutées à chaque objet, surtout si de nombreux objets ont plusieurs gestionnaires.

**Récupération** :

- Réduisez le nombre de gestionnaires par objet en standardisant sur un seul outil GitOps.
- Utilisez `kubectl apply-set` (si disponible) pour élaguer les anciens gestionnaires ?
- Supprimez manuellement les entrées de champs gérés obsolètes en utilisant `kubectl patch` avec un patch de fusion stratégique sur `metadata.managedFields`.
- Si le quota est dépassé, effectuez une compaction et une défragmentation d’etcd, et augmentez le quota si nécessaire.

### Vérification de la récupération

Après toute action de récupération, vérifiez que le système est stable :

```bash
kubectl get --raw /metrics | grep etcd_db_total_size_in_bytes
kubectl get --raw /metrics | grep apiserver_request_duration_seconds_bucket | tail -5
kubectl get pods -n kube-system
```

Assurez-vous que les pods du serveur d’API sont sains, que la taille d’etcd est inférieure à 80 % du quota et qu’aucun conflit en attente ne subsiste.

## 5. Liste de contrôle des opérations

Utilisez cette liste de contrôle pour exécuter SSA en production avec confiance. Chaque élément a un propriétaire et un intervalle de révision.

| # | Élément de la liste | Commande de vérification | Propriétaire | Périodicité de révision |
|---|---|---|---|---|
| 1 | Version Kubernetes >= 1.22 | `kubectl version --short` | Responsable de l’équipe plateforme (Priya Shah) | Mensuelle (ou après les mises à niveau) |
| 2 | Flowschemas APF présents | `kubectl get flowschemas` | Ingénieur plateforme (Alex Chen) | Hebdomadaire |
| 3 | Taille d’etcd inférieure à 70 % du quota | `kubectl get --raw /metrics \| grep etcd_db_total_size_in_bytes` | Ingénieur plateforme (Alex Chen) | Hebdomadaire |
| 4 | Aucun conflit SSA non résolu sur les charges de travail critiques | `kubectl get events --all-namespaces \| grep "Apply failed"` | Responsable DevOps (Sam Rivera) | Quotidienne (alerte automatisée) |
| 5 | Latence p99 du serveur d’API < 200 ms | Interroger les métriques depuis Prometheus | Responsable de l’équipe plateforme (Priya Shah) | Revue hebdomadaire des tableaux de bord |
| 6 | Santé de la synchronisation GitOps pour toutes les applications | Interface Argo CD ou `kubectl get applications` | Ingénieur DevOps (Jamie Lee) | Surveillance continue, rapport hebdomadaire |
| 7 | Plan de retour arrière testé | Exécuter un conflit et une récupération simulés dans l’environnement de staging | Ingénieur plateforme (Alex Chen) | Trimestrielle |

### Préparation avant changement

Avant tout nouveau déploiement de SSA, exécutez cette session terminal rapide :

```bash
# 1. Vérifier la santé du cluster
kubectl get nodes
kubectl get pods -n kube-system

# 2. Vérifier le statut APF
kubectl get flowschemas

# 3. Vérifier la taille d’etcd
kubectl get --raw /metrics | grep etcd_db_total_size_in_bytes

# 4. Appliquer un objet de test avec SSA dans un namespace dédié
kubectl create ns ssa-test
kubectl apply --server-side -f test-deployment.yaml -n ssa-test

# 5. Vérifier les champs gérés
kubectl get deployment test-app -n ssa-test -o yaml | grep -A5 managedFields
```

Si toutes les vérifications passent, vous êtes prêt pour un déploiement progressif.

## 6. Pièges courants et comment les éviter

### Piège 1 : Ignorer le gonflement des champs gérés

**Pourquoi cela arrive** : Les équipes appliquent avec plusieurs gestionnaires (kubectl, Argo CD, scripts CI) et n’élaguent jamais les anciens gestionnaires.

**Impact** : Les objets deviennent volumineux, etcd se remplit, et le coût de sérialisation du serveur d’API augmente.

**Évitement** : Standardisez sur un seul gestionnaire par classe d’objet. Utilisez explicitement `--field-manager`. Examinez périodiquement `managedFields` sur les objets à forte rotation.

### Piège 2 : Abuser de `--force-conflicts`

**Pourquoi cela arrive** : Les développeurs rencontrent un conflit et forcent immédiatement, pensant que c’est un raccourci.

**Impact** : Vole silencieusement la propriété des contrôleurs ou d’autres équipes, provoquant des retours inattendus ultérieurs.

**Évitement** : Traitez les conflits comme des signaux. Étudiez l’autre gestionnaire. Ne forcez qu’après avoir confirmé que vous devez posséder le champ.

### Piège 3 : Ne pas surveiller API Priority and Fairness

**Pourquoi cela arrive** : APF est invisible jusqu’à ce qu’il commence à mettre en file d’attente ou à rejeter des requêtes.

**Impact** : Lors d’une grande vague d’applications, les requêtes de basse priorité (y compris les applications SSA) peuvent être limitées, provoquant des délais d’attente.

**Évitement** : Configurez des alertes sur `apiserver_flowcontrol_rejected_requests_total` et `apiserver_flowcontrol_current_inqueue_requests`. Ajustez les flowschemas si nécessaire.

### Piège 4 : Appliquer SSA à d’énormes ressources personnalisées

**Pourquoi cela arrive** : Les équipes activent SSA globalement sans considérer la taille des objets.

**Impact** : Les CRD volumineux (par exemple, 1 Mo ou plus) avec SSA provoquent des pics de CPU et de mémoire importants sur le serveur d’API et etcd.

**Évitement** : Testez d’abord SSA sur de grands objets dans l’environnement de staging. Surveillez la mémoire du serveur d’API et la durée des requêtes. Excluez les très grands CR de SSA si nécessaire.

### Piège 5 : Absence de stratégie de retour arrière

**Pourquoi cela arrive** : SSA est considéré comme une simple méthode d’application, et le retour arrière n’est pas planifié.

**Impact** : Si une mauvaise configuration est appliquée avec SSA et que des conflits surviennent, revenir en arrière est plus complexe que de réappliquer un ancien fichier.

**Évitement** : Conservez des manifests versionnés dans Git. Utilisez GitOps pour permettre un retour arrière facile. Documentez comment supprimer les entrées de gestionnaires indésirables si nécessaire.

## 7. Chiffres de planification de capacité utilisables

Voici quelques chiffres de départ basés sur notre cluster de référence. Ajustez-les en fonction de vos mesures.

- **Augmentation de la taille des objets** : prévoyez 1 à 3 Ko supplémentaires par objet en raison des champs gérés. Pour 100 000 objets, cela représente 100 à 300 Mo dans etcd.
- **CPU du serveur d’API** : la logique de fusion SSA ajoute environ 5 à 10 % de surcharge CPU par requête d’application par rapport à l’application côté client. Prévoyez une petite marge supplémentaire.
- **Latence des requêtes API** : les requêtes d’application SSA peuvent être 10 à 20 % plus lentes que les applications côté client sur un serveur chargé. Surveillez le p99.
- **Mémoire sur le serveur d’API** : la mise en cache des champs gérés peut augmenter légèrement l’utilisation de la mémoire ; allouez 5 % de marge supplémentaire.
- **Limites de concurrence** : avec l’APF par défaut, un seul utilisateur peut mettre en file d’attente jusqu’à 100 requêtes mutantes. Pour les applications en masse, ajustez le flowschema `exempt` ou `global-default`.

Exemple d’ajustement de flowschema APF (illustratif, pas un manifeste complet) :

```yaml
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
  name: ssa-apply-burst
spec:
  priorityLevelConfiguration:
    name: global-default
  matchingPrecedence: 200
  distinguisherMethod:
    type: ByUser
  rules:
  - subjects:
    - kind: ServiceAccount
      serviceAccount:
        namespace: argocd
        name: argocd-application-controller
    resourceRules:
    - verbs: ["apply"]
      apiGroups: ["*"]
      resources: ["*"]
```

Cela donne au contrôleur Argo CD un flux dédié avec plus de marge pour les rafales. Testez toujours dans l’environnement de staging.

## 8. Conclusion

Kubernetes Server-Side Apply est un outil puissant pour la gestion de la configuration, mais il nécessite une planification de capacité délibérée. En suivant les étapes de ce guide — inventorier votre environnement, adopter SSA de manière incrémentale, vérifier les performances et se préparer aux modes de défaillance — vous pouvez éviter les pièges courants et garder votre cluster stable.

Commencez par une application à faible risque. Appliquez-la avec `--server-side`, inspectez les champs gérés et mesurez l’impact sur le serveur d’API et etcd. Ensuite, étendez progressivement tout en surveillant les métriques clés. Attribuez des propriétaires clairs pour les contrôles de santé SSA et révisez-les régulièrement.

Rappelez-vous : la gestion des champs de SSA vous apporte clarté et sécurité, mais seulement si vous la traitez comme une préoccupation opérationnelle de premier ordre. Mesurez, vérifiez et itérez.