E-NO
Kubernetes 8 min de lecture

Architecture de l'application côté serveur Kubernetes expliquée avec des exemples pratiques

calendar_today Publié : 2026-08-25
update Dernière mise à jour : 2026-08-25
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Architecture de l'application côté serveur Kubernetes expliquée avec des exemples pratiques ».

Introduction

Kubernetes Server-Side Apply (SSA) est une fonctionnalité qui déplace la logique de fusion des modifications de configuration du client (kubectl) vers le serveur d'API Kubernetes. Dans l'approche traditionnelle côté client, kubectl calcule localement un correctif de fusion à trois voies et l'envoie au serveur d'API. Avec l'application côté serveur, le serveur d'API lui-même stocke la configuration appliquée dans un champ dédié (metadata.managedFields) et résout les conflits en fonction de la propriété des champs. Ce changement améliore la cohérence, permet une meilleure détection des conflits et permet à plusieurs contrôleurs de mettre à jour en toute sécurité différents champs du même objet.

Cet article explique l'architecture de Kubernetes Server-Side Apply avec des exemples pratiques. Nous nous concentrons sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier les résultats et documenter les chemins de récupération. Vous apprendrez à activer et utiliser l'application côté serveur, à inspecter la gestion des champs, à gérer les conflits et à opérationnaliser SSA dans votre cluster.

Inventaire des versions et de l'environnement

Avant d'utiliser l'application côté serveur, vérifiez que votre cluster Kubernetes et vos outils clients la prennent en charge. L'application côté serveur est devenue bêta dans Kubernetes 1.16 et est généralement disponible et activée par défaut à partir de Kubernetes 1.18. Pour une utilisation en production, exécutez Kubernetes 1.18 ou une version ultérieure. Assurez-vous que votre version de kubectl est au moins 1.18 pour utiliser le drapeau --server-side.

Vérifiez la version de votre cluster :

kubectl version --short

La sortie attendue inclut la version du serveur, par exemple Server Version: v1.25.4.

Vérifiez la porte de fonctionnalité du serveur d'API pour l'application côté serveur (elle devrait être activée par défaut) :

kubectl get --raw /metrics | grep server_side_apply

Vous devriez voir une métrique comme apiserver_request_total{...,resource="apply"...} indiquant que le point de terminaison d'application est actif.

Kubernetes Server-Side Apply utilise le verbe apply sur le serveur d'API. Le point de terminaison pour l'application avec correctif est PATCH /api/v1/namespaces/{namespace}/configmaps/{name}?fieldManager=my-manager&force=false avec le type de contenu application/apply-patch+yaml. Le serveur d'API stocke la configuration appliquée dans le champ metadata.managedFields de l'objet. Chaque entrée dans managedFields suit le nom du gestionnaire, l'opération (Apply ou Update), la version de l'API utilisée et les champs possédés par ce gestionnaire.

Pour voir comment l'application côté serveur suit la propriété, créez un déploiement en utilisant l'application côté serveur et inspectez managedFields. Tout d'abord, créez un espace de noms :

kubectl create namespace ssa-demo

Ensuite, créez un déploiement avec l'application côté serveur :

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: ssa-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.21
          ports:
            - containerPort: 80

Appliquez avec l'option côté serveur :

kubectl apply --server-side -f deployment.yaml --field-manager=deployment-manager

Sortie attendue :

deployment.apps/nginx-deployment serverside-applied

Maintenant, inspectez les managedFields. Utilisez la commande suivante pour afficher la représentation YAML avec managedFields :

kubectl get deployment nginx-deployment -n ssa-demo -o yaml

Dans la sortie, sous metadata.managedFields, vous verrez une entrée avec manager: deployment-manager, operation: Apply et la structure fieldsV1 décrivant quels champs ce gestionnaire possède. Par exemple :

managedFields:
- apiVersion: apps/v1
  fieldsType: FieldsV1
  fieldsV1:
    f:spec:
      f:replicas: {}
      f:selector: {}
      f:template:
        f:metadata:
          f:labels:
            f:app: {}
        f:spec:
          f:containers:
            k:{"name":"nginx"}:
              f:image: {}
              f:name: {}
              f:ports: {}
  manager: deployment-manager
  operation: Apply
  time: "2023-10-01T12:00:00Z"

Cela montre que deployment-manager possède les champs qu'il a définis. Si un autre gestionnaire tente de modifier un champ possédé par deployment-manager sans forcer, le serveur d'API renverra une erreur de conflit.

Pour lister tous les gestionnaires et leurs opérations pour le déploiement, utilisez :

kubectl get deployment nginx-deployment -n ssa-demo -o json | jq '.metadata.managedFields[] | {manager: .manager, operation: .operation}'

Sortie attendue :

{
  "manager": "deployment-manager",
  "operation": "Apply"
}

Question rapide 1 sur 2

Quel est un avantage clair de l'utilisation de Server-Side Apply au lieu de Client-Side Apply ?

Le passage indique que Server-Side Apply présente un avantage clair : un seul aller-retour, il nécessite rarement d'effectuer d'abord une requête GET, et vous pouvez toujours détecter les conflits en cas de modifications inattendues.

Chemin de configuration sécurisé

L'application côté serveur introduit un mécanisme de résolution de conflits basé sur la propriété des champs. Lorsqu'un gestionnaire applique une modification à un champ déjà possédé par un autre gestionnaire, le serveur d'API rejette la modification avec une erreur de conflit à moins que le drapeau force ne soit défini. L'utilisation de force transfère la propriété du champ au nouveau gestionnaire, ce qui peut écraser des valeurs involontairement. Par conséquent, il est plus sûr d'éviter force en production et de résoudre plutôt les conflits explicitement.

Considérons un scénario où deux gestionnaires tentent de configurer le même déploiement. Le gestionnaire A (deployment-manager) possède spec.replicas. Le gestionnaire B (autoscaler) souhaite modifier spec.replicas de 2 à 3. Si le gestionnaire B applique sans forcer, le serveur d'API renvoie un conflit. Simulons cela.

Créez un deuxième fichier YAML qui tente de mettre à jour les réplicas :

# deployment-replicas-update.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: ssa-demo
spec:
  replicas: 3

Appliquez en tant que gestionnaire de champ différent :

kubectl apply --server-side -f deployment-replicas-update.yaml --field-manager=autoscaler

La sortie attendue inclut une erreur de conflit similaire à :

error: Apply failed with 1 conflict: conflict with "deployment-manager": .spec.replicas

Cette erreur indique que autoscaler ne peut pas modifier spec.replicas car il est possédé par deployment-manager. Pour résoudre le conflit, vous avez quelques options :

  1. Utiliser force pour prendre possession (non recommandé en production à moins d'être certain) :
   kubectl apply --server-side -f deployment-replicas-update.yaml --field-manager=autoscaler --force

Sortie attendue : deployment.apps/nginx-deployment serverside-applied. Après cela, autoscaler possède spec.replicas et la valeur est définie sur 3.

  1. Coordonner la propriété des champs : Assurez-vous qu'un seul gestionnaire est responsable d'un champ donné. Par exemple, l'autoscaler ne devrait pas essayer de définir directement les réplicas ; il devrait plutôt utiliser un contrôleur personnalisé ou une annotation.
  1. Utiliser l'application côté client pour cette mise à jour, ce qui n'applique pas la propriété des champs et utilise l'annotation last-applied-configuration pour la fusion. Cependant, cela peut entraîner des écrasements silencieux.

Pour vérifier la propriété actuelle après le conflit, utilisez :

kubectl get deployment nginx-deployment -n ssa-demo -o json | jq '.metadata.managedFields[] | select(.manager=="autoscaler") | .fieldsV1'

Si le conflit n'a pas été forcé, la sortie sera vide. S'il a été forcé, vous verrez f:spec avec f:replicas: {}.

Meilleures pratiques pour une configuration sécurisée avec SSA :

  • Spécifiez toujours --field-manager pour identifier le gestionnaire de manière unique.
  • Utilisez des gestionnaires de champ distincts pour différents composants afin d'éviter les conflits involontaires.
  • Surveillez les conflits en vérifiant les journaux d'audit du serveur d'API ou les métriques.
  • Testez les modifications dans un cluster non productif d'abord.
  • Utilisez --dry-run=server pour prévisualiser les modifications sans les appliquer :
  kubectl apply --server-side -f deployment-replicas-update.yaml --field-manager=autoscaler --dry-run=server

Sortie attendue : deployment.apps/nginx-deployment serverside-applied (dry run) et le conflit sera signalé le cas échéant.

Vérification et diagnostics

Après avoir appliqué des modifications avec l'application côté serveur, vérifiez que la ressource reflète l'état prévu et que managedFields sont mis à jour correctement. Utilisez des commandes en lecture seule pour observer l'état actuel avant et après les modifications.

Vérifiez l'état du déploiement :

kubectl rollout status deployment/nginx-deployment -n ssa-demo

Sortie attendue :

deployment "nginx-deployment" successfully rolled out

Inspectez les managedFields pour vous assurer que le bon gestionnaire possède les champs pertinents :

kubectl get deployment nginx-deployment -n ssa-demo -o json | jq '.metadata.managedFields'

Exemple de sortie montrant deux gestionnaires :

[
  {
    "apiVersion": "apps/v1",
    "fieldsType": "FieldsV1",
    "fieldsV1": {
      "f:spec": {
        "f:replicas": {},
        "f:selector": {},
        "f:template": {}
      }
    },
    "manager": "deployment-manager",
    "operation": "Apply",
    "time": "2023-10-01T12:00:00Z"
  },
  {
    "apiVersion": "apps/v1",
    "fieldsType": "FieldsV1",
    "fieldsV1": {
      "f:spec": {
        "f:replicas": {}
      }
    },
    "manager": "autoscaler",
    "operation": "Apply",
    "time": "2023-10-01T12:05:00Z"
  }
]

Notez qu'après l'application forcée, deployment-manager possède toujours spec.selector et spec.template, tandis que autoscaler possède spec.replicas. Si le deployment-manager applique ultérieurement une modification aux réplicas, il obtiendra un conflit à moins d'utiliser force ou de renoncer à la propriété.

Pour afficher la configuration appliquée par un gestionnaire spécifique, utilisez la commande kubectl apply view-last-applied (uniquement pour l'application côté serveur) :

kubectl apply view-last-applied deployment nginx-deployment -n ssa-demo

La sortie attendue montre le YAML qui a été appliqué en dernier par le gestionnaire de champ kubectl (ou vous pouvez spécifier --field-manager). Par exemple :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: ssa-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.21
          ports:
            - containerPort: 80

Diagnostiquez les problèmes en vérifiant les événements :

kubectl describe deployment nginx-deployment -n ssa-demo

Recherchez les événements liés aux opérations d'application en cas de conflit. Le serveur d'API émet également des métriques pour les demandes d'application. Vérifiez la métrique apiserver_request_total filtrée par verb="PATCH" et code pour voir les demandes d'application et les compteurs de succès/échec :

kubectl get --raw /metrics | grep 'apiserver_request_total{.*verb="PATCH".*code="409"'

Un compteur non nul pour 409 (Conflit) indique que des conflits d'application se sont produits. Cela peut aider à la surveillance.

Question rapide 2 sur 2

Par rapport à Client-Side Apply, que suit Server-Side Apply ?

Le passage indique que Server-Side Apply utilise une approche plus déclarative, qui suit la gestion des champs d'un objet, plutôt que le dernier état appliqué par l'utilisateur.

Modes de défaillance et récupération

Comprendre les modes de défaillance courants avec l'application côté serveur aide à une récupération rapide. Voici des scénarios et comment récupérer.

Défaillance : Erreur de conflit lors de l'application

Symptôme : kubectl apply --server-side renvoie une erreur de conflit similaire à :

error: Apply failed with 1 conflict: conflict with "deployment-manager": .spec.replicas

Cause : Un autre gestionnaire possède le champ que vous essayez de modifier.

Récupération :

  • Identifiez le propriétaire actuel en utilisant kubectl get <ressource> -o yaml et en inspectant managedFields.
  • Si la modification est nécessaire, coordonnez-vous avec le propriétaire pour qu'il renonce à la propriété. Vous pouvez forcer la propriété avec --force, mais cela peut écraser la valeur du champ.
  • Alternativement, mettez à jour le champ en utilisant une mise à jour régulière (PUT) ou un correctif (strategic merge patch) car la propriété peut ne pas être appliquée pour ces opérations (bien que ce ne soit pas recommandé car cela contourne la sémantique SSA).

Défaillance : Perte de propriété de champ après force

Symptôme : Après avoir forcé une application, les mises à jour du gestionnaire précédent sur le champ sont ignorées ou provoquent des conflits.

Cause : L'opération de force a transféré la propriété au nouveau gestionnaire et le gestionnaire précédent n'a plus de droits sur ce champ.

Récupération :

  • Le gestionnaire précédent peut également utiliser force pour regagner la propriété, mais cela peut provoquer une lutte acharnée. Corrigez la cause première en attribuant une propriété de champ claire.
  • Pour renoncer explicitement à la propriété d'un champ, appliquez un correctif avec $setElementOrder ? En fait, il n'y a pas de renonciation directe ; vous pouvez appliquer une valeur vide pour le champ et laisser l'autre gestionnaire prendre le relais. Ou vous pouvez supprimer l'entrée du gestionnaire de managedFields en utilisant un appel API brut (non recommandé en production car cela peut entraîner un comportement inattendu).

Défaillance : Nom de gestionnaire de champ incorrect

Symptôme : Plusieurs utilisateurs ou contrôleurs utilisent le même nom de gestionnaire de champ (par exemple, kubectl par défaut), provoquant des conflits inattendus.

Cause : Le --field-manager par défaut est kubectl pour kubectl apply --server-side. Si plusieurs scripts d'automatisation utilisent kubectl sans spécifier de gestionnaire, ils partagent tous la propriété.

Récupération :

  • Spécifiez toujours un --field-manager unique pour chaque acteur logique. Pour CI/CD, utilisez le nom du pipeline ou le nom du compte de service.
  • Pour corriger la propriété existante, réappliquez avec le bon gestionnaire et forcez si nécessaire, mais assurez la cohérence à l'avenir.

Défaillance : Ressource non prise en charge pour l'application côté serveur

Symptôme : L'application à une ressource personnalisée ou intégrée renvoie une erreur comme :

error: Apply failed with 1 conflict: conflicts with "..." using "...": .metadata.managedFields

Cause : Certaines ressources peuvent ne pas prendre entièrement en charge SSA ou avoir des problèmes de validation.

Récupération :

  • Vérifiez la documentation de l'API de la ressource pour la prise en charge de SSA. La plupart des ressources intégrées prennent en charge SSA.
  • Si la ressource est une CustomResourceDefinition, assurez-vous que la CRD a spec.preserveUnknownFields: false (ou utilise un schéma structurel) car SSA nécessite des types structurés.

Liste de contrôle des opérations

Utilisez cette liste de contrôle pour opérationnaliser l'application côté serveur dans votre environnement.

  1. Vérifiez les versions du cluster et du client : Assurez-vous que Kubernetes >=1.18 et kubectl >=1.18. Utilisez kubectl version --short.
  2. Choisissez les noms des gestionnaires de champ : Définissez une convention de dénomination pour les gestionnaires de champ. Par exemple :
  • platform-team pour les déploiements d'infrastructure
  • autoscaler pour le contrôleur HorizontalPodAutoscaler
  • ci-cd-pipeline pour les déploiements d'applications
  1. Appliquez les ressources avec l'option côté serveur pour les nouvelles ressources :
   kubectl apply --server-side -f manifest.yaml --field-manager=platform-team
  1. Inspectez managedFields après l'application : Exécutez kubectl get <ressource> -o yaml et vérifiez le gestionnaire et l'opération.
  2. Testez les scénarios de conflit dans un cluster de préproduction : Simulez deux gestionnaires modifiant le même champ pour comprendre les messages de conflit et la récupération.
  3. Mettez en place une surveillance des conflits d'application : Utilisez Prometheus pour alerter sur l'augmentation de apiserver_request_total{verb="PATCH", code="409"} ou récupérez les journaux d'audit pour les événements de conflit.
  4. Documentez la propriété des ressources critiques : Maintenez un tableau comme :
RessourceChampGestionnaire propriétaire
Deployment nginx-deploymentspec.replicasautoscaler
Deployment nginx-deploymentspec.templateplatform-team
Service nginx-servicespec.selectorplatform-team
  1. Utilisez dry-run dans CI/CD : Avant d'appliquer en production, exécutez :
   kubectl apply --server-side -f manifest.yaml --field-manager=ci-cd --dry-run=server

Si le dry run réussit sans conflit, procédez à l'application réelle.

  1. Assurez-vous que les secrets ne sont pas gérés uniquement via SSA : Utilisez une gestion externe des secrets (par exemple, SealedSecrets, External Secrets) et référencez les secrets dans les pods.
  2. Examinez régulièrement managedFields : Auditez périodiquement managedFields pour détecter les entrées obsolètes. Supprimez les entrées de gestionnaire inutilisées en appliquant un correctif vide avec l'ancien gestionnaire ? En fait, vous pouvez supprimer l'entrée du gestionnaire en appliquant avec le même gestionnaire un objet vide ? Il n'y a pas de commande directe ; vous pouvez utiliser l'API pour supprimer l'entrée managedFields. Pour simplifier, utilisez kubectl apply --server-side --field-manager=<ancien-gestionnaire> -f <manifeste sans champs possédés> puis supprimez l'entrée du gestionnaire ? Pas simple. Une alternative est d'utiliser un outil comme kubectl patch avec un application/merge-patch+json brut pour supprimer l'entrée managedFields, mais c'est avancé. Il est souvent sûr de laisser les anciennes entrées car elles n'affectent pas le fonctionnement.

Conclusion

Kubernetes Server-Side Apply fournit un mécanisme robuste pour gérer la configuration en suivant la propriété au niveau des champs sur le serveur d'API. En comprenant son architecture, vous pouvez éviter les pièges courants tels que les conflits involontaires et la perte de propriété. Les meilleures pratiques opérationnelles incluent l'utilisation de gestionnaires de champ uniques, les tests en non-production, la surveillance des conflits et des procédures de récupération claires.

Commencez avec une ressource à faible risque comme une ConfigMap dans un espace de noms de test. Pratiquez l'application avec l'option côté serveur, inspectez managedFields et simulez des conflits. Ensuite, déployez progressivement l'application côté serveur vers des charges de travail plus critiques, en vous assurant que votre équipe est familière avec la résolution des conflits. Avec une gestion minutieuse, l'application côté serveur peut rendre vos flux de travail de configuration Kubernetes plus sûrs et plus prévisibles.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO