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 :
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 :
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 :
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 :
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 :
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é :
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 :
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é :
kubectl apply --server-side --field-manager=platform-team -f deployment.yaml
Vérifiez ensuite :
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 :
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 :
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 :
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_totalapiserver_current_inflight_requests
Obtenez un aperçu rapide :
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 :
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) :
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-conflictspour 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 yamlpour 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 patchavec un patch de fusion stratégique surmetadata.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 :
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 :
# 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
exemptouglobal-default.
Exemple d’ajustement de flowschema APF (illustratif, pas un manifeste complet) :
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.