<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloud Sql on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/cloud-sql/</link><description>Recent content in Cloud Sql on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Fri, 19 Jul 2024 12:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/cloud-sql/index.xml" rel="self" type="application/rss+xml"/><item><title>Kubernetes 1.29 - sidecar container - à quoi ça peut bien servir ?</title><link>https://blog.zwindler.fr/2024/07/19/kubernetes-1-29-sidecar-containers/</link><pubDate>Fri, 19 Jul 2024 12:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2024/07/19/kubernetes-1-29-sidecar-containers/</guid><description>&lt;img src="https://blog.zwindler.fr/2024/07/race.webp" alt="Featured image of post Kubernetes 1.29 - sidecar container - à quoi ça peut bien servir ?" /&gt;&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai un copain qui doit lancer un traitement périodique. Ce traitement est réalisé par un bout de code qui tourne dans un container (sur un cluster GKE), et qui a besoin de requêter une base de donnée Cloud SQL.&lt;/p&gt;
&lt;p&gt;Pour ce genre de choses, Google Cloud fourni une image à mettre à côté de son application (sidecar pattern) qui sert de passe plat (proxy) pour que l&amp;rsquo;application se connecte à l&amp;rsquo;instance Cloud SQL chez Google cloud.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine?hl=fr" target="_blank" rel="noopener"
&gt;cloud.google.com/sql/docs/mysql/connect-kubernetes-engine?hl=fr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pas de bol, il se trouve que cette image met parfois un peu de temps à démarrer, et son absence fait crasher l&amp;rsquo;application de mon ami. On se retrouve avec une race condition et il m&amp;rsquo;a demandé si j&amp;rsquo;avais des idées de solutions pour régler ce problème.&lt;/p&gt;
&lt;p&gt;Parmis d&amp;rsquo;autres propositions (que je détaille dans le tout dernier paragraphe), je lui propose d&amp;rsquo;essayer une toute nouvelle fonctionnalité qui est en béta dans Kubernetes 1.29 que je n&amp;rsquo;avais pas encore testé moi même : les sidecar containers !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/" target="_blank" rel="noopener"
&gt;kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Fun&lt;/em&gt; fact: en cherchant de la documentation sur cloud sql sidecar, je suis tombé sur cet article d&amp;rsquo;une personne qui a exactement le même problème que mon ami.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hwchiu.medium.com/exploring-kubernetes-1-28-sidecar-container-support-ed1a39ac7fe0" target="_blank" rel="noopener"
&gt;hwchiu.medium.com/exploring-kubernetes-1-28-sidecar-container-support-ed1a39ac7fe0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une fois n&amp;rsquo;est pas coutume, pour que vous puissiez bien comprendre le problème et sa résolution, je vous propose de faire cette découverte de feature avec une démo.&lt;/p&gt;
&lt;p&gt;La totalité du code et les instructions pour le refaire en anglais sont disponibles sur le dépôt github &lt;a class="link" href="https://github.com/zwindler/sidecar-container-example" target="_blank" rel="noopener"
&gt;github.com/zwindler/sidecar-container-example&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;idée est la suivante : on va simuler le problème de mon poto avec deux images Docker créées pour l&amp;rsquo;occasion :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;zwindler/slow-sidecar&lt;/strong&gt; un helloworld basique en &lt;em&gt;V lang&lt;/em&gt; (&lt;a class="link" href="https://github.com/zwindler/vhelloworld" target="_blank" rel="noopener"
&gt;vhelloworld&lt;/a&gt;) qui fait un sleep de 5 secondes avant d&amp;rsquo;écouter le port 8081.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;zwindler/sidecar-user&lt;/strong&gt; un script bash qui &lt;code&gt;curl&lt;/code&gt; et &lt;code&gt;exit 1&lt;/code&gt; si le &lt;code&gt;curl&lt;/code&gt; échoue.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="prérequis"&gt;Prérequis
&lt;/h2&gt;&lt;p&gt;Comme dit précédemment, la fonctionnalité a été introduite dans Kubernetes 1.28 en tant que fonctionnalité alpha. Si vous utilisez cette version et souhaitez la tester, vous devez activer spécifiquement le flag de fonctionnalité.&lt;/p&gt;
&lt;p&gt;À partir de Kubernetes 1.29, cette fonctionnalité est passée en bêta et devrait être activée par défaut sur votre cluster.&lt;/p&gt;
&lt;h2 id="sans-conteneurs-sidecar"&gt;Sans conteneurs sidecar
&lt;/h2&gt;&lt;p&gt;D&amp;rsquo;abord, on va essayer de déployer le CronJob de manière naïve sur un cluster :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ cat 1-cronjob-without-sidecar-container.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apiVersion: batch/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kind: CronJob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name: sidecar-cronjob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; schedule: &lt;span class="s2"&gt;&amp;#34;* * * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; jobTemplate:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - containerPort: &lt;span class="m"&gt;8081&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restartPolicy: Never
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl apply -f 1-cronjob-without-sidecar-container.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cela devrait échouer car le conteneur &amp;ldquo;slow sidecar&amp;rdquo; ne sera pas prêt lorsque le conteneur &amp;ldquo;sidecar user&amp;rdquo; essaiera de faire un &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl get pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689938-5n5x9 1/2 Error &lt;span class="m"&gt;0&lt;/span&gt; 9s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl describe pods sidecar-cronjob-28689938-5n5x9
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Containers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; slow-sidecar:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; State: Running
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Started: Fri, &lt;span class="m"&gt;19&lt;/span&gt; Jul &lt;span class="m"&gt;2024&lt;/span&gt; 15:38:03 +0200
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Ready: True
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sidecar-user:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; State: Terminated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Reason: Error
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Exit Code: &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Started: Fri, &lt;span class="m"&gt;19&lt;/span&gt; Jul &lt;span class="m"&gt;2024&lt;/span&gt; 15:38:05 +0200
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Finished: Fri, &lt;span class="m"&gt;19&lt;/span&gt; Jul &lt;span class="m"&gt;2024&lt;/span&gt; 15:38:05 +0200
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Ready: False
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Restart Count: &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;slow-sidecar fonctionne bien mais notre requête sidecar-user a échoué car le sidecar était trop lent à démarrer.&lt;/p&gt;
&lt;p&gt;Petit nettoyage avant de recommencer :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl delete cronjob sidecar-cronjob
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Utiliser un conteneur init n&amp;rsquo;est pas une option non plus car le conteneur init ne se terminera jamais (ce n&amp;rsquo;est pas son but) et le conteneur &amp;ldquo;sidecar user&amp;rdquo; attendra éternellement son tour. Si vous voulez essayer, convertissez simplement slow-sidecar en initContainer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-diff" data-lang="diff"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apiVersion: batch/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kind: CronJob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name: sidecar-cronjob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; schedule: &amp;#34;* * * * *&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; jobTemplate:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ initContainers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - containerPort: 8081
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restartPolicy: Never
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et lancez-le&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl apply -f 2-cronjob-with-init-container.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl get pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689955-lzbnf 0/1 Init:0/1 &lt;span class="m"&gt;0&lt;/span&gt; 27s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et on reste boqué à cette étape jusqu&amp;rsquo;à la fin de teeeeeeemps.&lt;/p&gt;
&lt;h2 id="avec-des-conteneurs-sidecar"&gt;Avec des conteneurs sidecar
&lt;/h2&gt;&lt;p&gt;Pour éviter ce type de race condition, mettons à jour le manifest en convertissant slow-sidecar en initContainer MAIS EN AJOUTANT également &lt;code&gt;restartPolicy: Always&lt;/code&gt; dans la déclaration du container slow-sidecar.&lt;/p&gt;
&lt;p&gt;Cette bidouille est la manière de dire à Kubernetes de lancer ce conteneur en tant qu&amp;rsquo;initContainer mais de ne PAS attendre qu&amp;rsquo;il se termine (ce qu&amp;rsquo;il ne fera jamais puisqu&amp;rsquo;il s&amp;rsquo;agit d&amp;rsquo;un serveur web écoutant sur 8081 jusqu&amp;rsquo;à la fin des temps) pour démarrer l&amp;rsquo;application principale.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-diff" data-lang="diff"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apiVersion: batch/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kind: CronJob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name: sidecar-cronjob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; schedule: &amp;#34;* * * * *&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; jobTemplate:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ initContainers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ restartPolicy: Always
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - containerPort: 8081
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restartPolicy: Never
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; C&amp;rsquo;est la manière officielle de déclarer un conteneur sidecar dans Kubernetes. Je n&amp;rsquo;ai pas encore lu le KEP donc je ne peux pas dire pourquoi l&amp;rsquo;équipe de développement n&amp;rsquo;a pas introduit un nouveau mot-clé &lt;code&gt;sidecarContainers&lt;/code&gt; dans le schéma de spécification du Pod et a réutilisé les &lt;code&gt;initContainers&lt;/code&gt; déjà existants.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl apply -f 3-cronjob-with-sidecar-container.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cette fois, le conteneur init devrait se lancer et ENSUITE seulement, l&amp;rsquo;application :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl get pods -w
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689958-zrmhh 0/2 Pending &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689958-zrmhh 0/2 Pending &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689958-zrmhh 0/2 Init:0/1 &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689958-zrmhh 1/2 PodInitializing &lt;span class="m"&gt;0&lt;/span&gt; 2s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689958-zrmhh 1/2 Error &lt;span class="m"&gt;0&lt;/span&gt; 3s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On voit que c&amp;rsquo;est mieux (sidecar-user démarre dans un second temps) mais dans cet exemple particulier, ça échoue encore&amp;hellip;&lt;/p&gt;
&lt;h2 id="avec-des-conteneurs-sidecar-et-une-startupprobe"&gt;Avec des conteneurs sidecar ET une startupProbe
&lt;/h2&gt;&lt;p&gt;Par défaut, le kubelet considère que le conteneur sidecar est up dès que le processus dans le conteneur est en cours d&amp;rsquo;exécution, puis si les autres initContainers ont tous terminé (ou s&amp;rsquo;il n&amp;rsquo;y en a pas), passe à la phase principale de démarrage des containers.&lt;/p&gt;
&lt;p&gt;Malheureusement, dans notre cas, le conteneur sidecar est très lent (sleep 5), donc le fait que le processus soit en cours d&amp;rsquo;exécution n&amp;rsquo;est pas une indication de l&amp;rsquo;état du sidecar&amp;hellip;&lt;/p&gt;
&lt;p&gt;Nous devons ajouter une &lt;code&gt;startupProbe&lt;/code&gt; pour que Kubernetes sache QUAND passer la phase d&amp;rsquo;init et démarrer la phase principale.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After a sidecar-style init container is running (the kubelet has set the started status for that init container to true), the kubelet then starts the next init container from the ordered .spec.initContainers list. That status either becomes true because there is a process running in the container and no startup probe defined, or as a result of its startupProbe succeeding.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-diff" data-lang="diff"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apiVersion: batch/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kind: CronJob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name: sidecar-cronjob
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; schedule: &amp;#34;* * * * *&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; jobTemplate:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/sidecar-user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; initContainers:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - name: slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: zwindler/slow-sidecar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restartPolicy: Always
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - containerPort: 8081
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ startupProbe:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ httpGet:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ path: /
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ port: 8081
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ initialDelaySeconds: 5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ periodSeconds: 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ failureThreshold: 5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restartPolicy: Never
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une dernière fois :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl apply -f 4-cronjob-with-sidecar-container-and-startup-probe.yaml &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; kubectl get pods -w
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cronjob.batch/sidecar-cronjob created
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 0/2 Pending &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 0/2 Pending &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 0/2 Init:0/1 &lt;span class="m"&gt;0&lt;/span&gt; 0s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 0/2 Init:0/1 &lt;span class="m"&gt;0&lt;/span&gt; 1s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 0/2 PodInitializing &lt;span class="m"&gt;0&lt;/span&gt; 6s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 1/2 PodInitializing &lt;span class="m"&gt;0&lt;/span&gt; 6s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sidecar-cronjob-28689977-lt77c 1/2 Completed &lt;span class="m"&gt;0&lt;/span&gt; 7s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hooray!&lt;/p&gt;
&lt;h2 id="bonus--si-vous-navez-pas-sidecarcontainers-activé"&gt;Bonus : si vous n&amp;rsquo;avez pas sidecarContainers activé
&lt;/h2&gt;&lt;p&gt;Si vous êtes toujours en Kubernetes 1.28 (ou pire) et que vous n&amp;rsquo;avez pas la possibilité d&amp;rsquo;activer les alpha featureFlags, il va falloir trouver une autre méthode.&lt;/p&gt;
&lt;p&gt;Malheureusement, il est probable que la solution soit de modifier le code de votre application principale ou son image Docker. Vous pouvez :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ajouter une politique de retry dans l&amp;rsquo;application sidecar-user&lt;/li&gt;
&lt;li&gt;ajouter un script dans l&amp;rsquo;application sidecar-user qui attend un peu (sleep) avant d&amp;rsquo;essayer de contacter le sidecar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La première est une bonne pratique lorsqu&amp;rsquo;on traite avec des microservices et vous devriez l&amp;rsquo;envisager de toute façon pour gérer les problèmes temporaires de connexion à la base de données.&lt;/p&gt;
&lt;p&gt;La deuxième est une rustine sur une jambe de bois. Je le déconseille fortement car la vitesse de démarrage peut varier dans le sidecar et ajouter trop de délai dans l&amp;rsquo;application est également mauvais lorsqu&amp;rsquo;on doit gérer des incidents et des bugs en prod (induisant potentiellement d&amp;rsquo;autres problèmes).&lt;/p&gt;</description></item></channel></rss>