Argo CD and Server-Side Apply: Who Owns Which Field
Server-side apply moves the merge into the API server and replaces the last-applied annotation with field ownership. What that actually changes in Argo CD.
Migrer une infrastructure legacy vers Kubernetes sans couper la prod, faire tourner des clusters au quotidien, comprendre ce qui se passe entre le kernel et le CNI quand ça se dégrade. Les articles de cette catégorie viennent de migrations et d'opérations réelles, pas de labs.
Ces sujets, je les traite aussi en mission : Migration Kubernetes.
Pour lire ces articles dans l'ordre plutôt que par date : Kubernetes en production · Sécurité d’infrastructure.
Le vocabulaire du domaine : Boucle de réconciliation · Classes QoS (Kubernetes) · Cluster Autoscaler · CrashLoopBackOff · Helm chart (paquet d'application Kubernetes) · Ingress (Kubernetes) · NetworkPolicy (Kubernetes) · Node drain · RBAC (contrôle d’accès basé sur les rôles) · Rolling deployment (déploiement progressif) · Vertical Pod Autoscaler (VPA) · Webhook d'admission · tout le glossaire.
Server-side apply moves the merge into the API server and replaces the last-applied annotation with field ownership. What that actually changes in Argo CD.
Le server-side apply déplace la fusion dans l'API server et remplace l'annotation last-applied par des propriétaires de champs. Ce que ça change dans Argo CD.
Les sync options d'Argo CD passées une à une : ce que chacune change à la commande appliquée, et laquelle se pose sur l'Application ou sur la ressource.
Argo CD sync options one by one: what each changes in the command actually run, and which ones belong on the Application versus on the resource.
Un Deployment ne modifie jamais un ReplicaSet existant : il en crée un nouveau et réduit l'ancien à zéro replica. C'est ce mécanisme précis qui rend le rollback possible.
A Deployment never edits an existing ReplicaSet: it creates a new one and scales the old one to zero. That exact mechanism is what makes rollback possible.
Une API Kubernetes dépréciée reste fonctionnelle pendant un temps annoncé, puis disparaît définitivement. Un manifeste jamais mis à jour casse alors sans avertissement progressif.
VPA's Auto mode always restarted a pod to change its requests. In-place resize (K8s 1.27+) eliminates that interruption, under certain conditions.
rollout restart forces a clean rolling update without editing a single line of the Deployment. The right command for a one-off ConfigMap refresh, not kubectl delete pod.
rollout restart force un rolling update propre sans modifier une seule ligne du Deployment. La bonne commande pour un refresh de ConfigMap ponctuel, pas kubectl delete pod.
A deprecated Kubernetes API keeps working for an announced period, then disappears for good. A manifest never updated then breaks with no gradual warning.
Le mode Auto du VPA redémarrait systématiquement un pod pour changer ses requests. Le redimensionnement in-place (K8s 1.27+) élimine cette interruption, sous conditions.
Modifier un objet Kubernetes sans relire sa dernière version produit un 409 Conflict, pas un écrasement silencieux. Le mécanisme qui protège contre les écritures concurrentes.
Modifying a Kubernetes object without re-reading its latest version produces a 409 Conflict, not a silent overwrite. The mechanism protecting concurrent writes.
A static pod is managed directly by the kubelet, not the API server. Deleting it via kubectl just makes it reappear, a classic kubeadm cluster confusion.
Un static pod est géré directement par le kubelet, pas par le serveur API. Le supprimer via kubectl le fait juste réapparaître, une confusion classique en cluster kubeadm.
RBAC empêche, Falco détecte en direct, l'audit logging répond après l'incident. Sans Audit Policy activée, cette question n'a tout simplement pas de réponse.
Activer EncryptionConfiguration chiffre les nouvelles écritures dans etcd. Les Secrets déjà stockés avant l'activation restent en clair, sans avertissement.
kube-proxy traduit chaque Service en règles iptables évaluées séquentiellement. Cilium, basé sur eBPF, remplace ce mécanisme par des tables de hachage dans le kernel.
kube-proxy translates every Service into iptables rules evaluated sequentially. Cilium, built on eBPF, replaces that mechanism with kernel hash tables.
LoadBalancer and NodePort never replace ClusterIP: they add a layer on top of it. Understanding that stack avoids picking the wrong type by default.
LoadBalancer et NodePort ne remplacent jamais ClusterIP : ils l'ajoutent en couche. Comprendre cet empilement évite de choisir le mauvais type de Service.
Modifier un ConfigMap ne redémarre aucun pod automatiquement. Les variables d'environnement ne se mettent même jamais à jour sans un redémarrage manuel.
Editing a ConfigMap never restarts any pod automatically. Environment variables don't even get updated at all without a manual restart.
Enabling EncryptionConfiguration encrypts new writes to etcd. Secrets already stored before activation stay in plaintext, with no warning.
RBAC, NetworkPolicy et Pod Security agissent avant qu'un pod ne tourne. Falco observe ce qui se passe réellement à l'intérieur, une fois qu'il tourne déjà.
RBAC, NetworkPolicy, and Pod Security act before a pod runs. Falco watches what actually happens inside it, once it's already running.
Un finalizer bloqué, pas Kubernetes, empêche un objet en Terminating de mourir : il attend un nettoyage qu'un contrôleur disparu ne fera jamais.
A stuck finalizer, not Kubernetes itself, keeps a Namespace in Terminating: it's waiting on a cleanup a gone controller will never actually run.
Ingress encodes anything advanced into controller-specific annotations. Gateway API splits roles into typed resources, portable across controllers.
L'Ingress encode toute logique avancée dans des annotations propres à chaque contrôleur. La Gateway API sépare les rôles en ressources typées, portables entre contrôleurs.
A worker consuming a queue can run at 5% CPU while completely overwhelmed. HPA on a custom metric solves what CPU/memory structurally can't see.
Un worker qui consomme une file d'attente peut tourner à 5% de CPU tout en étant complètement submergé. Le HPA sur métrique custom résout ce que CPU/mémoire ne peuvent pas voir.
An init container runs to completion before the main container starts. Since Kubernetes 1.29, a native sidecar changes what's still possible.
Un init container s'exécute jusqu'au bout avant que le conteneur principal démarre. Depuis Kubernetes 1.29, un sidecar natif change ce qui reste possible.
port-forward goes through the API server, not the pod's network. NetworkPolicy never sees it, a blind spot governed by its own specific RBAC verb.
port-forward passe par le serveur API, pas par le réseau du pod. NetworkPolicy ne le voit jamais, un angle mort qui a son propre verbe RBAC à restreindre spécifiquement.
RBAC prevents, Falco detects live, audit logging answers after the incident. Without an Audit Policy enabled, that question simply has no answer.
Un Event Kubernetes disparaît après 1 heure par défaut, pas après un an. La preuve d'un incident survenu la veille a souvent déjà été purgée avant qu'on la cherche.
A Kubernetes Event vanishes after 1 hour by default, not a year. The proof of yesterday's incident has usually already been purged before anyone looks.
A Helm chart deploys a fixed configuration. An Operator encodes operational knowledge that keeps acting after deployment, not just during it.
Le ndots:5 par défaut de Kubernetes essaie 5 domaines de recherche internes avant chaque nom externe. Une latence DNS invisible jusqu'à ce qu'elle s'accumule.
Kubernetes' default ndots:5 tries 5 internal search domains before every external name. A DNS latency tax that's invisible until it adds up.
A full conntrack table doesn't slow anything down: it silently rejects new connections, a symptom that looks like an application problem elsewhere.
Une table conntrack pleine ne ralentit rien : elle rejette silencieusement les nouvelles connexions, un symptôme qui ressemble à un problème applicatif ailleurs.
Un Helm chart déploie une configuration figée. Un Operator encode une connaissance opérationnelle qui continue d'agir après le déploiement, pas seulement pendant.
Kubernetes sends SIGTERM and removes a pod from Service endpoints in parallel, never in a guaranteed order. Without preStop, requests land on empty air.
Kubernetes envoie SIGTERM et retire un pod des endpoints du Service en parallèle, jamais dans un ordre garanti. Sans preStop, des requêtes arrivent dans le vide.
The strangler fig pattern puts a routing facade in front of the legacy system, then switches over feature by feature until the old one just dies off.
Le pattern strangler fig fait passer une façade de routage devant le legacy, puis bascule fonctionnalité par fonctionnalité, jusqu'à ce que l'ancien système meure de lui-même.
VolumeSnapshot capture l'état d'un PVC à un instant donné, sans jamais toucher aux ressources Kubernetes autour. Un besoin différent de la sauvegarde cluster complète.
VolumeSnapshot captures a PVC's state at a point in time, never touching the Kubernetes resources around it. A different need than full cluster backup.
Le HPA scale les pods, chaque pod ouvre son propre pool de connexions. Sous charge, la base atteint max_connections avant même que le HPA n'ait fini de scaler.
The HPA scales pods, each pod opens its own connection pool. Under load, the database hits max_connections before the HPA even finishes scaling.
Le choix entre Kubernetes auto-géré et un service managé ne se résume pas au coût du control plane. Ce que le fournisseur gère réellement, ce qui reste à charge.
Choosing self-managed Kubernetes versus a managed service isn't just about control-plane pricing. What the cloud provider actually handles, what stays on you.
Namespaces, vcluster, or separate clusters: three ways to isolate teams on Kubernetes, with the same trade-off between isolation strength and operational cost.
Namespaces, vcluster ou clusters séparés : trois façons d'isoler des équipes sur Kubernetes, avec un compromis identique entre force d'isolation et coût opérationnel.
Un Ingress ne fait rien sans contrôleur pour l'exécuter. nginx-ingress et Traefik répondent au même besoin par deux modèles de configuration opposés.
An Ingress does nothing without a controller to run it. nginx-ingress and Traefik answer the same need through two opposite configuration models.
Le blue-green bascule tout le trafic d'un coup, pas progressivement. Rollback instantané, prix réel : deux environnements complets à faire tourner en double.
Blue-green flips all traffic at once, not gradually. Instant rollback, real price: two complete environments running side by side.
Without a cloud provider, no StorageClass provisions a volume automatically. What Longhorn does instead, and what replication doesn't replace.
Sans cloud provider, aucun StorageClass ne provisionne de volume automatiquement. Ce que Longhorn fait à la place, et ce que la réplication ne remplace pas.
Gérer un Application ArgoCD par service tient à dix équipes. À cent, ApplicationSets automatise la génération, mais déplace le vrai problème d'isolation.
Managing one ArgoCD Application per service holds up for ten teams. At a hundred, ApplicationSets automate generation, but shift the real isolation problem.
Un Service de type LoadBalancer reste en Pending indéfiniment sur un cluster on-premise, faute de cloud provider pour le satisfaire. Ce que MetalLB fait à la place.
A LoadBalancer Service stays Pending forever on an on-premise cluster, for lack of a cloud provider to satisfy it. What MetalLB does instead.
Un cadre concret pour savoir si votre infrastructure a besoin de Kubernetes maintenant, dans un an, ou jamais, avant de payer pour le découvrir.
A concrete framework to work out whether your infrastructure needs Kubernetes now, in a year, or never, before paying a consultant to find out for you.
A volume snapshot backs up neither your Deployments, nor your Secrets, nor your cluster's structure. What Velero covers, and why testing restores matters.
Un snapshot de volume ne sauvegarde ni vos Deployments, ni vos Secrets, ni la structure de votre cluster. Ce que Velero couvre, et pourquoi le tester avant d'en avoir besoin.
Kubernetes assigns a QoS class from requests/limits, never an explicit choice. A critical service with no limits gets evicted first.
Without a defined priority, every pod is equal to the scheduler on a saturated node. PriorityClass and preemption decide who stays and who gets evicted when capacity runs out.
Sans priorité définie, tous les pods sont égaux devant un nœud saturé. PriorityClass et la préemption décident qui reste et qui se fait évincer quand la capacité manque.
La classe QoS d'un pod fixe son ordre d'éviction, déduite des requests/limits, jamais choisie explicitement. Un service critique sans limits part en premier.
kubectl top pod and HPA have no data to read without metrics-server installed. How it actually works, and the most common certificate error at install time.
kubectl top pod et le HPA n'ont aucune donnée à lire sans metrics-server installé. Comment il fonctionne, et l'erreur de certificat la plus fréquente à l'installation.
PodSecurityPolicy has been dead since Kubernetes 1.25. Pod Security Admission replaces it with three profiles applied through a single namespace label.
PodSecurityPolicy est mort depuis Kubernetes 1.25. Pod Security Admission le remplace par trois profils appliqués via un simple label de namespace.
La facture cloud arrive par nœud, jamais par namespace. Sans allocation par requests, chaque équipe partage un coût qu'aucune ne peut expliquer seule.
The cloud bill arrives per node, never per namespace. Without allocation by requests, every team shares a cost none of them can explain alone.
Three replicas scheduled on the same node protect against nothing. Pod anti-affinity and topology spread constraints solve the same problem through two different mechanics.
Trois replicas planifiées sur le même nœud ne protègent de rien. Pod anti-affinity et topology spread constraints résolvent le même problème par deux mécaniques différentes.
Les taints repoussent tous les pods d'un nœud sauf ceux qui les tolèrent explicitement. Les trois effets, et pourquoi ce n'est pas une affinité positive.
Taints repel every pod from a node except those that explicitly tolerate them. The three effects, and why this isn't a positive-affinity mechanism.
ArgoCD et Flux résolvent le même problème par deux modèles différents : UI centralisée contre contrôleurs composables. Le vrai critère de choix.
ArgoCD and Flux solve the same problem with two different models: a centralized UI versus a set of composable controllers. The criterion that actually decides.
Le Cluster Autoscaler reste prisonnier des groupes de nœuds préconfigurés. Karpenter provisionne l'instance exacte dont le pod a besoin, sans ce détour.
Cluster Autoscaler stays locked into preconfigured node groups. Karpenter provisions the exact instance a pod needs, no detour through a group.
This component stores a cluster's entire state and tolerates zero disk latency. Losing etcd quorum only recovers cleanly if you have a tested backup.
Ce composant stocke tout l'état du cluster et n'a droit à aucune latence disque. Une perte de quorum etcd ne se répare proprement qu'avec une sauvegarde testée.
Two Kubernetes policy engines, two models: native YAML versus a dedicated query language. What actually matters for the choice, beyond syntax familiarity.
Deux moteurs de policy Kubernetes, deux modèles : YAML natif contre langage de requête dédié. Ce qui compte pour choisir, au-delà de la syntaxe.
Des requests bien posées protègent un pod. Rien n'empêche une équipe d'en créer mille sans limite globale. ResourceQuota et LimitRange gouvernent au niveau du namespace.
Well-set requests protect a single pod. Nothing stops a team from creating a thousand of them with no global cap. ResourceQuota and LimitRange govern at the namespace level.
A distroless image has no shell and no diagnostic tools, by deliberate security choice. Ephemeral containers let you debug it anyway, without redeploying.
Une image distroless n'a ni shell ni outils de diagnostic, par choix de sécurité. Les conteneurs éphémères permettent de déboguer quand même, sans redéployer.
An admission webhook is an explicit single point of failure. failurePolicy: Fail can block an entire cluster if the webhook becomes unreachable.
Un webhook d'admission est un point de défaillance unique explicite. failurePolicy: Fail peut bloquer tout le cluster si le webhook devient injoignable.
Un Deployment traite ses pods comme interchangeables. Une base de données ne l'est pas : elle a besoin d'une identité stable et de son propre volume. C'est le rôle du StatefulSet.
A Deployment treats its pods as interchangeable. A database isn't: it needs a stable identity and its own volume. That's what StatefulSet is for.
The VPA sizes CPU/memory requests from real consumption. Its Auto mode restarts pods to apply a new sizing, a cost that's easy to overlook.
Le VPA sert à dimensionner les requests CPU/mémoire à partir de la consommation réelle. Son mode Auto redémarre les pods à chaque ajustement.
Kubernetes RBAC denies everything by default, but an overly broad role never breaks anything: it just sits there, silent, until the incident that exposes it.
RBAC Kubernetes refuse tout par défaut, mais un rôle trop large ne casse jamais rien : il existe, silencieux, jusqu'à l'incident qui l'expose.
A Deployment guarantees no per-node distribution. DaemonSet guarantees an exact one: one pod on every node, the mechanism behind most infrastructure agents.
Un Deployment ne garantit aucune répartition par nœud. DaemonSet en garantit une exacte, le mécanisme derrière la plupart des agents d'infrastructure.
CrashLoopBackOff is a symptom, never a cause. Three radically different root-cause families, one diagnostic method to tell them apart in a few commands.
CrashLoopBackOff est un symptôme, jamais une cause. Trois familles d'origine différentes, une méthode pour les distinguer en quelques commandes.
A service mesh adds a proxy per pod for free mTLS and observability. Istio and Linkerd pay for that benefit at very different prices.
Un service mesh ajoute un proxy par pod pour du mTLS et de l'observabilité gratuits. Istio et Linkerd payent ce bénéfice à un prix très différent.
A Deployment keeps its pods alive indefinitely. A migration or a nightly batch needs to finish, not stay alive. Job and CronJob answer that different need.
Un Deployment garde ses pods vivants indéfiniment. Une migration ou un batch nocturne doit se terminer, pas rester vivant. Job et CronJob répondent à ce besoin différent.
How ArgoCD continuously reconciles cluster state with Git, the difference between push and pull deployment, and what drift actually reveals.
Comment ArgoCD réconcilie en continu l'état du cluster avec Git, la différence entre push et pull deployment, et ce que la dérive (drift) révèle vraiment.
kubectl apply n'écrase pas un objet, il le fusionne. Ce mécanisme invisible explique pourquoi un kubectl edit manuel disparaît silencieusement au prochain déploiement.
kubectl apply doesn't overwrite an object, it merges it. That invisible mechanism explains why a manual kubectl edit silently vanishes on the next deploy.
Comment Consul distingue un service enregistré d'un service joignable, pourquoi un health check mal conçu masque une panne, et le rôle du consensus Raft.
How Consul tells a registered service apart from a reachable one, why a shallow health check hides an outage, and what Raft consensus is doing in there.
How a Helm chart generates YAML from templates and values, why nested conditionals become unreadable, and when Kustomize is the better fit.
Comment un chart Helm génère du YAML à partir de templates et de valeurs, pourquoi les conditions imbriquées deviennent illisibles, et quand préférer Kustomize.
Le Cluster Autoscaler ajoute des nœuds facilement. Le scale down casse en silence : PDB trop stricts, pods sans contrôleur, annotation oubliée.
The Cluster Autoscaler adds nodes easily. Scale down is where it silently breaks: overly strict PDBs, controller-less pods, and one forgotten annotation.
How an Ingress routes HTTP traffic to your services, what cert-manager actually automates for Let's Encrypt certificates, and the HTTP-01 challenge trap.
Comment un Ingress route le trafic HTTP, ce que cert-manager automatise pour les certificats Let's Encrypt, et le piège du challenge HTTP-01.
Pourquoi le Horizontal Pod Autoscaler ne fonctionne pas sans requests correctement posées, comment il décide de scaler, et le piège de l'oscillation.
Why the Horizontal Pod Autoscaler doesn't work without requests set correctly, how it decides to scale, and the flapping trap.
What a Kubernetes PodDisruptionBudget guards (voluntary evictions, not node crashes), minAvailable vs maxUnavailable, and the misconfigs that stall drains.
Ce qu'un PodDisruptionBudget garde : évictions volontaires, pas crashs de nœud, minAvailable contre maxUnavailable, et les erreurs qui bloquent les drains.
What each Kubernetes probe type actually gates, the failure modes of copy-pasted probe configs, and a decision table for setting each parameter.
Ce que chaque type de probe Kubernetes contrôle réellement, les modes de défaillance des configs copiées-collées, et une table de décision par paramètre.
What actually happens when a pod crosses its CPU or memory limit, how QoS classes are derived, the no-limits debate, and a method to set sane defaults.
Ce qui se passe vraiment quand un pod Kubernetes dépasse sa limite CPU ou mémoire, les classes QoS, le débat des limites, et une méthode de réglage.