<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RKE on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/rke/</link><description>Recent content in RKE on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Thu, 26 Sep 2024 20:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/rke/index.xml" rel="self" type="application/rss+xml"/><item><title>RKE, Talos Linux, ... : MountVolume.NewMounter initialization failed for volume : path does not exist</title><link>https://blog.zwindler.fr/2024/09/26/rke-talos-etc-path-does-not-exist/</link><pubDate>Thu, 26 Sep 2024 20:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2024/09/26/rke-talos-etc-path-does-not-exist/</guid><description>&lt;img src="https://blog.zwindler.fr/2024/09/bizu.webp" alt="Featured image of post RKE, Talos Linux, ... : MountVolume.NewMounter initialization failed for volume : path does not exist" /&gt;&lt;h2 id="tout-a-commencé"&gt;Tout a commencé&amp;hellip;
&lt;/h2&gt;&lt;p&gt;Sans trop dévoiler de mon nouveau travail, je bosse sur une plateforme Kubernetes que nous gérons nous-même avec du &lt;a class="link" href="https://www.talos.dev/" target="_blank" rel="noopener"
&gt;Talos Linux&lt;/a&gt; (un OS Kubernetes immutable pas piqué des hannetons !).&lt;/p&gt;
&lt;p&gt;La plateforme est encore assez jeune, et sur mon environnement de développement, j&amp;rsquo;ai de quoi faire des buckets S3 mais pas de PVC avec du stockage de type &amp;ldquo;block&amp;rdquo;. J&amp;rsquo;aurais pu monter un rook à &lt;a class="link" href="https://www.la-rache.com/" target="_blank" rel="noopener"
&gt;la méthode RACHE&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2024/09/Certif_a_LARACHE_DenisGERMAIN.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Mais que voulez-vous&amp;hellip; Par acquit de conscience pro (aka la grosse flemme de l&amp;rsquo;espace), et pour m&amp;rsquo;économiser 4 secondes et demi de requête à Google/ChatGPT, je demande à un collègue s&amp;rsquo;il a pas un petit bout de YAML pour monter un petit PVC à l&amp;rsquo;aide d&amp;rsquo;un hostPath vitef.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2024/09/pvc-local.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;cf &lt;a class="link" href="https://kubernetes.io/docs/concepts/storage/storage-classes/#local" target="_blank" rel="noopener"
&gt;kubernetes.io/docs/concepts/storage/storage-classes/#local&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="ca-commence-mal"&gt;Ca commence mal
&lt;/h2&gt;&lt;p&gt;Bon déjà, si vous essayer de jouer ce manifest, ça ne va pas fonctionner. En effet, ce que la doc officielle ne dit pas (pas dans la page sur les storage classes en tout cas), c&amp;rsquo;est que le provisioner Local &lt;code&gt;kubernetes.io/no-provisioner&lt;/code&gt; ne peut pas créer de PV si vous ne spécifiez pas d&amp;rsquo;affinité (nodeAffinity).&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 toto.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;storageclass.storage.k8s.io/pour-la-science-sc created
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;The PersistentVolume &lt;span class="s2"&gt;&amp;#34;pour-la-science-pv&amp;#34;&lt;/span&gt; is invalid: spec.nodeAffinity: Required value: Local volume requires node affinity
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ça se corrige facilement :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;StorageClass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-sc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;provisioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/no-provisioner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;reclaimPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Delete&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;volumeBindingMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WaitForFirstConsumer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-pv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/opt/tempDir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-sc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;À partir de là, ça fonctionne (sur le papier). Une fois les manifests créés, vous devriez avoir une storage class et un PV, prêt à être utilisé. On peut même aller un cran plus loin et créer le PVC et le bind au PV.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-sc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fin de l&amp;rsquo;article ?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;kubectl apply -f toto.yaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;storageclass.storage.k8s.io/pour-la-science-sc unchanged&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;persistentvolume/pour-la-science-pv created&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;persistentvolumeclaim/pour-la-science-pvc created&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Non, bien sûr&amp;hellip;&lt;/p&gt;
&lt;h2 id="cours-pod--couuuuuurs-"&gt;Cours, pod ! Couuuuuurs !
&lt;/h2&gt;&lt;p&gt;Lançons donc un petit Pod de debug pour voir si on arrive à monter notre PVC dans un container :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu-pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sleep 3600&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/toto&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pour-la-science-pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restartPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ici, pas besoin de spécifier l&amp;rsquo;&lt;strong&gt;affinity&lt;/strong&gt; qu&amp;rsquo;il faut que le Pod se schedule sur le worker-1 (là où se trouve le PV). Le scheduler de Kubernetes est assez intelligent pour le retrouver tout seul.&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 toto2.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pod/ubuntu-pvc created
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et là, c&amp;rsquo;est le drame. Le Pod reste bloqué en ContainerCreating !!&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;ubuntu 0/1 ContainerCreating &lt;span class="m"&gt;0&lt;/span&gt; 52s
&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 events
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LAST SEEN TYPE REASON OBJECT MESSAGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4m6s Warning ProvisioningFailed persistentvolumeclaim/pour-la-science-pvc storageclass.storage.k8s.io &lt;span class="s2"&gt;&amp;#34;pour-la-science-pv&amp;#34;&lt;/span&gt; not found
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;100s Normal WaitForFirstConsumer persistentvolumeclaim/pour-la-science-pvc waiting &lt;span class="k"&gt;for&lt;/span&gt; first consumer to be created before binding
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;88s Normal Scheduled pod/ubuntu-pvc Successfully assigned default/ubuntu to worker-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;25s Warning FailedMount pod/ubuntu-pvc MountVolume.NewMounter initialization failed &lt;span class="k"&gt;for&lt;/span&gt; volume &lt;span class="s2"&gt;&amp;#34;pour-la-science-pv&amp;#34;&lt;/span&gt; : path &lt;span class="s2"&gt;&amp;#34;/opt/tempDir&amp;#34;&lt;/span&gt; does not exist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hum&amp;hellip; ok, &lt;code&gt; path &amp;quot;/opt/tempDir&amp;quot; does not exist&lt;/code&gt;, c&amp;rsquo;est relativement explicite comme erreur. J&amp;rsquo;ai oublié de créer le dossier sur le host en question.&lt;/p&gt;
&lt;p&gt;Je vais créer un nouveau Pod qui lui va monter le /opt de l&amp;rsquo;hôte dans /mnt/opt, et créer le dossier à la main (souvenez-vous, méthode RACHE) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu-hostpath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;somespecialnamespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sleep 3600&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/host/opt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;host&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privileged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mnt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/host&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restartPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note : les PodSecurity de Talos m&amp;rsquo;empêchent de créer le Pod (hostPath &amp;amp; priviledge) si je ne le créé pas dans un namespace disposant d&amp;rsquo;exceptions.&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 &lt;span class="nb"&gt;exec&lt;/span&gt; -it -n somespecialnamespace pods/ubuntu-hostpath -- /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;root@ubuntu-hostpath:/# mkdir /host/opt/tempDir/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;control&lt;span class="o"&gt;]&lt;/span&gt; + d
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;command&lt;/span&gt; terminated with &lt;span class="nb"&gt;exit&lt;/span&gt; code &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cest-bon-maintenant-"&gt;C&amp;rsquo;est bon maintenant ?
&lt;/h2&gt;&lt;p&gt;Répertoire : créé. Mission accomplie, right ? Right ?&lt;/p&gt;
&lt;p&gt;Et ben non !! Le Pod est toujours bloqué.&lt;/p&gt;
&lt;p&gt;Pourquoi diantre je peux voir ce dossier dans mon Pod ubuntu-hostpath, mais pas dans ubuntu-pvc, qui monte le même dossier, mais via un PVC ???&lt;/p&gt;
&lt;p&gt;La raison, c&amp;rsquo;est&amp;hellip; Parce que c&amp;rsquo;est un PVC.&lt;/p&gt;
&lt;p&gt;Bon ok, d&amp;rsquo;accord. Ce n&amp;rsquo;est pas JUSTE parce que d&amp;rsquo;un côté, je passe par un hostpath et de l&amp;rsquo;autre par un PVC.&lt;/p&gt;
&lt;p&gt;Les plus astucieux/astucieuses d&amp;rsquo;entre vous se seront surement douté qu&amp;rsquo;il y a un rapport avec le titre de mon article. Le problème est le même sur RKE, Talos Linux et surement d&amp;rsquo;autres OS similaires.&lt;/p&gt;
&lt;p&gt;Ces OS ont la particularité d&amp;rsquo;être des &amp;ldquo;Container OS&amp;rdquo;. Les composants de kubernetes ne sont pas &amp;ldquo;installés&amp;rdquo; à proprement parlé dans l&amp;rsquo;OS, mais lancé dans des containers. L&amp;rsquo;OS n&amp;rsquo;est en fait qu&amp;rsquo;une grosse coquille vide avec juste de quoi lancer des containers. Ça limite la surface d&amp;rsquo;attaque et ça les rend plutôt légers.&lt;/p&gt;
&lt;p&gt;Et il y a une différence fondamentale entre la façon dont est géré &amp;ldquo;un Pod avec hostPath&amp;rdquo; et &amp;ldquo;un pod qui monte un PVC&amp;rdquo;. Dans le cas du PVC provisionné avec &lt;code&gt;kubernetes.io/no-provisioner&lt;/code&gt;, le kubelet a besoin de pouvoir monter le dossier &lt;strong&gt;avant&lt;/strong&gt; le Pod.&lt;/p&gt;
&lt;p&gt;Vous voyez où je veux en venir ? Dans un container OS, le kubelet est un container. Il ne voit rien d&amp;rsquo;autre que sa propre arborescence de container (pas le / de l&amp;rsquo;hôte comme un binaire classique, juste le contenu du gros ZIP qu&amp;rsquo;on a téléchargé depuis dockerhub avec &lt;code&gt;docker pull&lt;/code&gt;), et éventuellement les dossiers de l&amp;rsquo;hôte qu&amp;rsquo;on lui a explicitement monté.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2024/09/kubelet-talos.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Dans mon cas, pour le container du kubelet, ce dossier &lt;code&gt;/opt/tempDir&lt;/code&gt; n&amp;rsquo;existe pas, simplement parce que dans son arborescence de container, il n&amp;rsquo;a pas été monté (ni créé).&lt;/p&gt;
&lt;h2 id="la-solution"&gt;La solution
&lt;/h2&gt;&lt;p&gt;En fait, il suffisait, comme souvent, de lire la documentation. Talos Linux donne 2 méthodes pour résoudre ce problème :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;explicitement monter les dossiers dont on a besoin dans le container du kubelet&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;passer par un provider tiers qui va créer des PVCs à partir de dossier sur l&amp;rsquo;hôte, sans passer par le kubelet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://www.talos.dev/v1.8/kubernetes-guides/configuration/local-storage/" target="_blank" rel="noopener"
&gt;www.talos.dev/v1.8/kubernetes-guides/configuration/local-storage/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;ai testé les deux, elles fonctionnent parfaitement. Mais au-delà de la solution, c&amp;rsquo;est plus le chemin que j&amp;rsquo;ai trouvé intéressant à vous partager :)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2024/09/bizu.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="quelques-liens-sur-le-sujet"&gt;Quelques liens sur le sujet
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner/blob/master/docs/faqs.md#volume-does-not-exist-with-containerized-kubelet" target="_blank" rel="noopener"
&gt;FAQ su SIG storage de Kubernetes - &lt;strong&gt;Volume does not exist with containerized kubelet&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/" target="_blank" rel="noopener"
&gt;Kubernetes 1.14: Local Persistent Volumes GA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://stackoverflow.com/questions/68503386/kubernetes-mountvolume-newmounter-initialization-failed-for-volume-volume-na" target="_blank" rel="noopener"
&gt;stackoverflow - Kubernetes - MountVolume.NewMounter initialization failed for volume &amp;ldquo;&lt;volume-name&gt;&amp;rdquo; : path does not exist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>k3os, le reboot de RancherOS à la sauce k3s</title><link>https://blog.zwindler.fr/2020/12/08/k3os-le-reboot-de-rancheros-a-la-sauce-k3s/</link><pubDate>Tue, 08 Dec 2020 07:45:00 +0000</pubDate><guid>https://blog.zwindler.fr/2020/12/08/k3os-le-reboot-de-rancheros-a-la-sauce-k3s/</guid><description>&lt;img src="https://blog.zwindler.fr/2020/12/k3s.webp" alt="Featured image of post k3os, le reboot de RancherOS à la sauce k3s" /&gt;&lt;h2 id="k3os-encore-un-produit-rancher-"&gt;k3os, encore un produit Rancher ?
&lt;/h2&gt;&lt;p&gt;Oui, k3os. Je vais donc ENCORE parler d’un produit de Rancher aujourd’hui, et la raison principale est que cet article est plus ou moins la suite logique des deux précédents sur RancherOS et RKE&lt;/p&gt;
&lt;p&gt;Dans &lt;a class="link" href="https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/" &gt;Kubernetes avec RancherOS et RKE partie 1&lt;/a&gt;, je vous expliquais que j’avais ENCORE changé d’infra et que pour le fun, j’avais souhaité essayer d’installer &lt;a class="link" href="https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/" &gt;RancherOS&lt;/a&gt; puis &lt;a class="link" href="https://blog.zwindler.fr/2020/11/30/kubernetes-avec-rancheros-et-rke-partie-2/" &gt;RKE&lt;/a&gt;, respectivement comme distrib pour mes nodes Kubernetes et comme méthode d’installation de Kubernetes lui même.&lt;/p&gt;
&lt;p&gt;Bon, alors d’abord j’ai pas été super convaincu par RancherOS (pas seulement pour mon usage perso, mais aussi plus globalement) et en plus, j’ai découvert grâce aux commentaires que RancherOS était en fait abandonné.&lt;/p&gt;
&lt;p&gt;Bummer&amp;hellip;&lt;/p&gt;
&lt;h2 id="k3s-pour-mon-usecase-cest-quand-même-mieux"&gt;k3s pour mon usecase c’est quand même mieux
&lt;/h2&gt;&lt;p&gt;Bon en vrai ce n’était pas bien grave, car le but était de tester ces produits dont j’entendais parler depuis un moment. Mais du coup, je n’ai toujours pas de Kubernetes viable pour mes geekeries&amp;hellip;&lt;/p&gt;
&lt;p&gt;Un des outils qui correspond le mieux à mon usecase, là encore chez Rancher, c’est &lt;strong&gt;&lt;a class="link" href="https://k3s.io/" target="_blank" rel="noopener"
&gt;k3s&lt;/a&gt;&lt;/strong&gt;. Un Kubernetes minimaliste qui prend très peu de ressources et qui est simple à installer.&lt;/p&gt;
&lt;p&gt;J’avais d’ailleurs fait quelques articles dessus, notamment pour parler d’un playbook Ansible qui permettait de déployer k3s sur des instances ARM dans le cloud de Scaleway (la bonne époque où ils en proposaient, en tout cas&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Le code est toujours dispo et &lt;strong&gt;n’était pas spécifique à ARM ni à Scaleway&lt;/strong&gt;, si ça vous intéresse.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/ansible-scaleway-k3s" target="_blank" rel="noopener"
&gt;Le code sur Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/03/21/deployer-en-5-minutes-un-cluster-kubernetes-sur-arm-avec-k3s-et-ansible/" &gt;L’article pour en parler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="et-k3os-dans-tout-ça-"&gt;Et k3os dans tout ça ?
&lt;/h2&gt;&lt;p&gt;La méthode d’installation de Kubernetes est donc choisie. Mais ça ne répond pas à la seconde question, à savoir, sur quelle distribution je l’installe.&lt;/p&gt;
&lt;p&gt;Je peux l’installer sur n’importe quel OS Linux généraliste (Debian, Ubuntu, CentOS, &amp;hellip; you name it), mais le but, c’est quand même d’installer un Kubernetes le plus léger possible (car je suis radin sur les serveurs que je loue et ils sont peu puissants).&lt;/p&gt;
&lt;p&gt;Qu’à cela ne tienne, me dis-je ! Pourquoi ne pas retenter l’expérience CoreOS et RancherOS avec k3os ?&lt;/p&gt;
&lt;p&gt;Et c’est vraiment une bonne question&amp;hellip;&lt;/p&gt;
&lt;h2 id="k3os-donc"&gt;k3OS donc
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;k3OS is a Linux distribution designed to remove as much OS maintenance as possible in a Kubernetes cluster. It is specifically designed to only have what is needed to run &lt;a class="link" href="https://github.com/rancher/k3s" target="_blank" rel="noopener"
&gt;k3s&lt;/a&gt;. Additionally the OS is designed to be managed by kubectl once a cluster is bootstrapped. Nodes only need to join a cluster and then all aspects of the OS can be managed from Kubernetes. Both k3OS and k3s upgrades are handled by the k3OS operator.
&lt;a class="link" href="https://github.com/rancher/k3os" target="_blank" rel="noopener"
&gt;github.com/rancher/k3os&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;k3os est donc une distribution optimisée par Rancher pour fonctionner avec k3s et consommer le moins de ressources possibles.&lt;/p&gt;
&lt;p&gt;Les avantages mis en avant sont que dès que l’OS est installé, on a un Kubernetes fonctionnel puisque k3s est préinstallé et configuré à l’install de l’OS.&lt;/p&gt;
&lt;p&gt;L’autre avantage mis en avant est que tout la gestion du cycle de vie de l’OS est piloté à l’aide d’un operateur dans Kubernetes (k3OS operator) qui va nous permettre de gérer l’OS depuis Kubernetes directement.&lt;/p&gt;
&lt;p&gt;Mkay, pourquoi pas.&lt;/p&gt;
&lt;h2 id="et-cest-reparti-pour-un-tour"&gt;Et c’est reparti pour un tour
&lt;/h2&gt;&lt;p&gt;Même procédure que pour l’article sur RancherOS, les principes sont très similaires. On va télécharger une image iso, créer une VM et se connecter dessus en liveCD pour installer l’OS sur le disque.&lt;/p&gt;
&lt;p&gt;La page des releases est ici : &lt;a class="link" href="https://github.com/rancher/k3os/releases" target="_blank" rel="noopener"
&gt;github.com/rancher/k3os/releases&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /var/lib/vz/template/iso
wget https://github.com/rancher/k3os/releases/download/v0.11.1/k3os-amd64.iso
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;To copy k3OS to local disk, after logging in as rancher run sudo k3os install. Then remove the ISO from the virtual machine and reboot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/12/k3os-0.11.1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STOOOOOP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Exactement comme dans l’install de RancherOS, si vous partez bille en tête vous risquez de tomber sur un OS (ahah).&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/" &gt;Dans l’article précédent&lt;/a&gt;, j’avais fait l’andouille et lancé la commande, pour me rendre compte qu’une fois installé, je n’avais ni réseau, ni clé SSH pour me connecter sur l’utilisateur rancher post install.&lt;/p&gt;
&lt;p&gt;En vrai, tout doit se faire via cloud-config&amp;hellip;&lt;/p&gt;
&lt;p&gt;Bon, pour être honnête, cette fois-ci, ils ont quand même un peu plus prévu le coup. Si vous ne fournissez pas de cloud-config, cette fois-ci k3os vous propose de rentrer un mot de passe pour votre rancher.&lt;/p&gt;
&lt;p&gt;Mais vous n’aurez pas plus de réseau si comme moi vous n’avez pas mis de DHCP sur votre LAN (cf aparté pour les bolosses qui n’ont pas de DHCP plus tard dans l’article).&lt;/p&gt;
&lt;h2 id="cloud-config"&gt;cloud-config
&lt;/h2&gt;&lt;p&gt;Partons donc pour l’instant du principe que vous avez un DHCP et que vous aurez donc, une fois k3OS installé, accès réseau à votre machine.&lt;/p&gt;
&lt;p&gt;Proxmox a la bonne idée de permettre la création de volume cloud-init directement depuis l’UI.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/12/k3os_cloud-init.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/12/k3os_cloudinit_2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Cependant, j’ai bien l’impression que le format du cloud-init de Proxmox ne correspond pas au format attendu par k3OS&amp;hellip;&lt;/p&gt;
&lt;p&gt;OK, je suis pas fâché.&lt;/p&gt;
&lt;p&gt;On va donc devoir le faire à la mimine et ça tombe bien, car on a ENCORE le souci du clavier Qwerty/Azerty&amp;hellip; (&lt;a class="link" href="https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/" &gt;cf Bonus Qwerty&lt;/a&gt;), ce qui est parfait pour copier à la main une clé SSH, c’est bien connu.&lt;/p&gt;
&lt;p&gt;Vous l’aurez compris, on va s’en sortir une fois de plus avec un port série et la console de type xterm.js&amp;hellip;&lt;/p&gt;
&lt;p&gt;Grosso modo, mon cloud config s’est limité à ça.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat &amp;gt; config.yml &amp;lt;&amp;lt; EOF
k3os:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQAaaaaaaaaaaaaaaaaaaaaaaaaaaaOF0lZiHOjIZ/27aaHmNTq27Vws2dhzJ9 rancher
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tout ça pour ça me direz-vous ? Oui&amp;hellip;&lt;/p&gt;
&lt;p&gt;Mais bon, une fois qu’on a ça, on peut passer à l’install elle-même, qui est en fait un mini installeur qui vous pose quelques questions un peu triviales comme « rôle du node », « token », « chemin de la clé SSH ».&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;k3os-15121 [~]$ sudo k3os install
Running k3OS configuration
Choose operation
1. Install to disk
2. Configure server or agent
Select Number [1]:
Config system with cloud-init file? [y/N]: y
cloud-init file location (file path or http URL): config.yml
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ces valeurs peuvent d’ailleurs être ajoutées au cloud-config pour vous permettre d’automatiser la totalité de l’opération.&lt;/p&gt;
&lt;p&gt;A l’issue de l’opération&amp;hellip; magie ! vous aurez un Kubernetes tout neuf et tout léger :)&lt;/p&gt;
&lt;h2 id="aparté-pour-les-bolosses-qui-nont-pas-de-dhcp-aka-moi"&gt;Aparté pour les bolosses qui n’ont pas de DHCP (aka. moi)
&lt;/h2&gt;&lt;p&gt;Ça aurait été plus simple de monter un petit serveur DHCP vite fait mais je suis têtu comme pas deux.&lt;/p&gt;
&lt;p&gt;La blague avec k3OS est que, contrairement à RancherOS, il n’est tout simplement pas possible d’installer l’OS en lui spécifiant l’adresse réseau physique qu’il devra avoir post install.&lt;/p&gt;
&lt;p&gt;En fait au début, j’avais copié ce que j’avais fait pour RancherOS. L’installeur de k3OS ne râle pas, mais il ignore simplement le code en trop.&lt;/p&gt;
&lt;p&gt;Et vous ne pourrez plus vous connecter&amp;hellip;&lt;/p&gt;
&lt;p&gt;Mais comme je suis têtu (je me répète), j’ai cherché à tout prix la solution.&lt;/p&gt;
&lt;p&gt;L’idée ici est de feinter l’installeur en ne lui donnant PAS de cloud config. On garde ainsi la possibilité de se loguer à l’utilisateur rancher avec un mot de passe (pas bien ça&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Une fois k3OS installé, on se connecte une nouvelle fois en console (oui, on risque pas de le faire en SSH&amp;hellip;) et on configure la carte réseau.&lt;/p&gt;
&lt;p&gt;k3OS est un dérivé d’Alpine (pour les binaires userspace) avec le kernel d’Ubuntu 20.04 (oh&amp;hellip;kay ?).&lt;/p&gt;
&lt;p&gt;Pour setter le réseau, vous pouvez donc faire :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo connmanctl services
*AR Wired ethernet_c6eb50d8c655_cable
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Cette commande vous renvoie le nom de la carte réseau virtuelle. Vous pouvez maintenant regarder la configuration par défaut&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo connmanctl services ethernet_c6eb50d8c655_cable
/net/connman/service/ethernet_c6eb50d8c655_cable
Type = ethernet
Security = [ ]
State = ready
Favorite = True
Immutable = False
AutoConnect = True
Name = Wired
Ethernet = [ Method=auto, Interface=eth0, Address=C6:EB:50:D8:C6:55, MTU=1500 ]
IPv4 = [ Method=auto, Address=169.254.126.16, Netmask=255.255.0.0 ]
IPv4.Configuration = [ Method=auto ]
IPv6 = [ ]
IPv6.Configuration = [ Method=auto, Privacy=disabled ]
Nameservers = [ 8.8.8.8 ]
Nameservers.Configuration = [ ]
Timeservers = [ ]
Timeservers.Configuration = [ ]
Domains = [ ]
Domains.Configuration = [ ]
Proxy = [ Method=direct ]
Proxy.Configuration = [ ]
mDNS = False
mDNS.Configuration = False
Provider = [ ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Grande classe. 8.8.8.8 en DNS&amp;hellip; No comment.&lt;/p&gt;
&lt;p&gt;Et setter votre carte réseau post installation avec cette dernière commande (à remplacer par vos valeurs à vous, hein) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo connmanctl config ethernet_d2416991aa5b_cable --ipv4 manual 192.168.1.15 255.255.255.0 192.168.1.1 --nameservers 192.168.1.1
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Bon je crois qu’il est temps d’arrêter de se faire du mal&amp;hellip;&lt;/p&gt;
&lt;p&gt;Oui clairement, je me suis mis dans un exemple un peu foireux. Tout le monde de normalement constitué dispose d’un DHCP de nos jours. Surtout que k3OS cible les usages de k3s, à savoir le edge et l’IoT.&lt;/p&gt;
&lt;p&gt;Mais du coup, j’ai l’impression qu’on est vraiment dans le marché de niche de la niche : un OS optimisé pour l’IoT ou l’edge uniquement. Je ne suis clairement pas ciblé par k3OS.&lt;/p&gt;
&lt;p&gt;Ça ne m’a pas vraiment donné envie de regarder plus en détails la partie k3OS operator, qui permet de gérer les mises à jours de l’OS depuis Kube.&lt;/p&gt;
&lt;p&gt;La documentation sur le sujet est disponible ici et ça a l’air d’avoir beaucoup bougé entre la v0.9, la v0.10 et la v0.11, puisqu’il y a des exceptions dans tous les sens&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rancher/k3os#upgrade-and-maintenance" target="_blank" rel="noopener"
&gt;github.com/rancher/k3os#upgrade-and-maintenance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bref&amp;hellip; il est temps que je m’installe un bête OS généraliste&amp;hellip;&lt;/p&gt;</description></item><item><title>Kubernetes avec RancherOS et RKE – partie 1</title><link>https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/</link><pubDate>Mon, 26 Oct 2020 07:45:00 +0000</pubDate><guid>https://blog.zwindler.fr/2020/10/26/kubernetes-avec-rancheros-et-rke-partie-1/</guid><description>&lt;img src="https://blog.zwindler.fr/2020/10/rancheros_explained.webp" alt="Featured image of post Kubernetes avec RancherOS et RKE – partie 1" /&gt;&lt;h2 id="rancheros-pour-commencer"&gt;RancherOS pour commencer
&lt;/h2&gt;&lt;p&gt;Pendant l’été, j’ai &lt;em&gt;encore&lt;/em&gt; changé d’infra, avec un passage à un cluster Proxmox VE à 3 nœuds. Je reviendrais la dessus, mais la finalité c’est que j’ai eu (encore) l’envie de m’installer un petit cluster Kubernetes dans mes hyperviseurs.&lt;/p&gt;
&lt;p&gt;Ceux qui me suivent depuis un moment savent que j’en ai déjà déployé des tonnes depuis le temps (&lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=kubernetes" &gt;k3s qui vient également de chez Rancher, mais aussi kubespray, kubeadm, aks, OVH, the hard way de kelsey hightower, &amp;hellip;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Du coup, plutôt que de gagner du temps et refaire quelque chose que je maîtrise déjà, je suis parti dans l’idée de tester quelque chose d’encore nouveau, deux produits de Rancher dont j’ai entendu parler : RancherOS + RKE !&lt;/p&gt;
&lt;p&gt;L’idée dans cette première partie est de découvrir RancherOS, une des nombreuses solutions pour vos workload containerisés proposées par Rancher.&lt;/p&gt;
&lt;h2 id="mais-cest-quoi-rancheros-"&gt;Mais c’est quoi RancherOS ?
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;RancherOS A lightweight, secure Linux distribution, built from containers to run containers well.
RancherOS est donc un OS minimaliste contenant juste ce qu’il faut pour faire du Docker, configuré à l’aide de cloud-init et dans lequel la plupart des opérations de maintenances sont simplifiées.
Quand je lis ça, je ne peux pas m&amp;rsquo;empêcher de repenser à CoreOS, qui faisait (fait) les mêmes promesses.
N’ayant qu’installé et utilisé pendant peu de temps CoreOS, je ne serai pas capable de faire une comparaison des deux produits entre eux, mais la finalité est vraiment la même.
Un point intéressant (je trouve) dans RancherOS est le fait que tous les services &amp;ldquo;techniques&amp;rdquo; nécessaires pour faire fonctionner correctement vos applications containerisés sont également des containers.
RancherOS is the smallest, easiest way to run Docker in production. Every process in RancherOS is a container managed by Docker. This includes system services such as udev and syslog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/10/rancheros_explained.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;L’idée ici, c’est que tous ces services systèmes tournent dans un démon Docker séparé (pour plus de sécurité et éviter la suppression accidentelle).&lt;/p&gt;
&lt;h2 id="comment-le-déployer-"&gt;Comment le déployer ?
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Ça dépend. Et évidemment, ça dépend, ça dépasse.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rancher a fait le choix (malin) de mettre le paquet pour faciliter le déploiement de leur RancherOS sur le plus de plateformes possibles.&lt;/p&gt;
&lt;p&gt;Ainsi, vous retrouverez des processus de déploiement facilités pour la plupart des clouds providers public, mais aussi des images pour VMware, une image pour Rasberry Pi, Virtual Box ou Docker Machine. Il y a même de quoi booter en PXE pour ceux qui ont encore l’envie de faire ce genre de choses.&lt;/p&gt;
&lt;p&gt;Dans mon cas, la seule solution à ma disposition pour KVM c’est d’&lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/installation/workstation/boot-from-iso/" target="_blank" rel="noopener"
&gt;utiliser l’ISO&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="première-bonne-nouvelle-et-première-déconvenue"&gt;Première bonne nouvelle et première déconvenue
&lt;/h2&gt;&lt;p&gt;LA première bonne nouvelle, c’est qu’il existe un ISO tuné pour Proxmox VE, et ça c’est très cool.&lt;/p&gt;
&lt;p&gt;Donc je DL l’ISO, créé une bête machine virtuelle sur mon cluster, dans lequel l’ISO est monté et roule ma poule ?&lt;/p&gt;
&lt;p&gt;Ouais&amp;hellip; presque !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You must boot with enough memory which you can refer to &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/overview/#hardware-requirements" target="_blank" rel="noopener"
&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un point agaçant avec RancherOS est le &lt;em&gt;minimum requirement&lt;/em&gt; en termes de mémoire. 1.25 Go pour un OS Linux soi-disant minimaliste (passé à 1 Go depuis la 1.5), la pilule a du mal à passer. Ok, je pinaille peut-être un peu, mais 1 Go c’est énorme quand on a prévu de lancer juste quelques petits containers comme des petits nginx ou des petits bouts de code python.&lt;/p&gt;
&lt;p&gt;Il faut dire que Rancher nous a mal habitué avec k3s, leur Kubernetes modifié qui tourne avec quasiment pas de RAM au point de permettre de Kubernetes sur des RPi 1 ou en &lt;em&gt;edge computing&lt;/em&gt;. Et là, avec 2 fois plus de RAM en &lt;em&gt;requirement&lt;/em&gt;, j’ai que le démon Docker, même pas le kube qui va avec&amp;hellip;&lt;/p&gt;
&lt;p&gt;Du coup, le &amp;ldquo;RancherOS is the smallest, easiest way to run Docker in production&amp;rdquo;, bof&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/03/21/deployer-en-5-minutes-un-cluster-kubernetes-sur-arm-avec-k3s-et-ansible/" &gt;Déployer en 5 minutes un cluster Kubernetes sur ARM avec k3s et Ansible&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rancher essaye de se raccrocher aux branches en vous linkant une &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/installation/custom-builds/custom-rancheros-iso/#reduce-memory-requirements" target="_blank" rel="noopener"
&gt;doc permettant de construire soi-même une image custom nécessitant moins de RAM&lt;/a&gt;, mais bon&amp;hellip; Le mal est fait, ils m’ont pas motivé à tester&amp;hellip;&lt;/p&gt;
&lt;h2 id="déployer-rancheros-sur-proxmox-ve"&gt;Déployer RancherOS sur Proxmox VE
&lt;/h2&gt;&lt;p&gt;Ok, assez discuté, maintenant on peut rentrer dans le vif du sujet. Sur notre hyperviseur préféré, on récupère l’ISO.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /var/lib/vz/template/iso
wget https://releases.rancher.com/os/latest/proxmoxve/rancheros.iso
--2020-08-10 15:00:26-- https://releases.rancher.com/os/latest/proxmoxve/rancheros.iso
Resolving releases.rancher.com (releases.rancher.com)... 104.26.12.240, 172.67.69.133, 104.26.13.240, ...
Connecting to releases.rancher.com (releases.rancher.com)|104.26.12.240|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 160432128 (153M) [application/x-iso9660-image]
Saving to: ‘rancheros.iso’
rancheros.iso 100%[===================&amp;gt;] 153.00M 42.3MB/s in 3.7s
2020-08-10 15:00:36 (40.9 MB/s) - ‘rancheros.iso’ saved [160432128/160432128]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La procédure d’installation officielle est &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/installation/server/install-to-disk/" target="_blank" rel="noopener"
&gt;disponible ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Grosso modo, on boot la VM, qui va configurer le serveur au minimum et permettre de se connecter avec l’utilisateur rancher&lt;code&gt; sans mot de passe. L’idée est d’utiliser cet utilisateur pour finaliser l’installation avec ros install&lt;/code&gt; une fois la VM configurée.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ros install` command orchestrates the installation from the rancher/os container. You will need to have already created a cloud-config file and found the target disk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;STOOOOOP&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si vous partez bille en tête comme moi et faites un ros install` sans lire la phrase en entier, vous vous retrouverez avec une VM sur laquelle vous ne pourrez pas vous loguer (voire sans réseau si vous n’avez pas de DHCP). C’est con.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The easiest way to log in is to pass a cloud-config.yml file containing your public SSH keys.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="cloud-config"&gt;Cloud config
&lt;/h2&gt;&lt;p&gt;Ok, on va éviter de tous faire la même erreur. Voici maintenant le fameux prérequis, la documentation officielle qui parle de &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/configuration/#cloud-config" target="_blank" rel="noopener"
&gt;configuration/#cloud-config&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si vous avez un doute sur certains paramètres, vous pouvez toujours utiliser la commande ros config` qui permet de récupérer les valeurs par défaut puis les setter.&lt;/p&gt;
&lt;p&gt;On finalisera le tout en fusionnant la config actuelle avec un fichier YAML, ou alors on exportera la conf actuelle dans un autre fichier YAML.&lt;/p&gt;
&lt;p&gt;Dans le cas d’un PoC, la plupart des valeurs qui vont nous intéresser sont simplement ce qui permet de setter l’IP et de configurer notre clé SSH pour pouvoir se connecter.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros config get rancher.network
dhcp_timeout: 0
dns:
nameservers: []
search: []
http_proxy: &amp;#34;&amp;#34;
https_proxy: &amp;#34;&amp;#34;
interfaces: {}
modem_networks: {}
no_proxy: &amp;#34;&amp;#34;
post_cmds: []
pre_cmds: []
wifi_networks: {}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Donc là, de base, bah ya rien.&lt;/p&gt;
&lt;p&gt;Pourtant, si vous allez voir le fichier /var/lib/rancher/conf/cloud-config.yml, vous remarquerez qu’il y a pleeeeein de choses, plus ou moins utiles.&lt;/p&gt;
&lt;p&gt;La page de doc qui nous intéressera donc dans ce cas est &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/networking/" target="_blank" rel="noopener"
&gt;networking&lt;/a&gt;. Voici un exemple de commandes pour configurer une IP fixe (à remplacer par des valeurs qui ont du sens dans votre réseau, of course).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros config set rancher.network.interfaces.eth0.address 192.168.1.10/24
sudo ros config set rancher.network.interfaces.eth0.gateway 192.168.1.1
sudo ros config set rancher.network.interfaces.eth0.mtu 1500
sudo ros config set rancher.network.interfaces.eth0.dhcp false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de ce moment là, vous avez accès au réseau depuis votre machine RancherOS, mais les modifications ne seront pas permanentes. On va donc exporter tout ça.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros config export
rancher:
environment:
EXTRA_CMDLINE: /init
network:
interfaces:
eth0:
address: 192.168.1.10/24
dhcp: false
gateway: 192.168.1.10
mtu: 1500
ssh_authorized_keys: []
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Bon, et là vous voyez qu’il nous manque toujours la clé SSH.&lt;/p&gt;
&lt;h2 id="bonus-clavier-qwerty"&gt;Bonus clavier qwerty
&lt;/h2&gt;&lt;p&gt;Vous connaissez la différence entre un admin systèmes français débutant et un admin système français senior ?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you call yourself a sysadmin and don’t know by heart the qwerty layout on an azerty keyboard, I just assume you are a junior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Pour ceux qui n’ont pas la blague, allez voir ce tweet de _oshell qui a bien backfired (lien mort) dans sa face)&lt;/p&gt;
&lt;p&gt;Le senior, a force de bouffer des consoles à la con qui gèrent mal les différents layouts de claviers (parce que &amp;ldquo;hé, on s’en fout des gens qui ont pas de qwerty, on vient de la Silicon valley&amp;rdquo;), il connaît le qwerty par cœur.&lt;/p&gt;
&lt;p&gt;Et ben là encore, ça n’a pas loupé. La console NoVNC de mon PVE, qui en plus n’avait le partage de presse-papier qui ne marchait pas.&lt;/p&gt;
&lt;p&gt;Je veux bien être à l’aise en &amp;ldquo;blind qwerty sur azerty&amp;rdquo;, mais faut pas déconner, je suis pas senior au point d’être capable de copier une clé publique dans un YAML #trollface.&lt;/p&gt;
&lt;p&gt;Donc pour ceux qui ne connaissent pas l’astuce, il est possible d’affecter temporairement un terminal série à votre VM de la façon suivante (voir &lt;a class="link" href="https://pve.proxmox.com/wiki/Serial_Terminal" target="_blank" rel="noopener"
&gt;doc Proxmox VE&lt;/a&gt;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# qm set 100 -serial0 socket
update VM 100: -serial0 socket
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, vous devriez pouvoir accéder à un nouveau type de console dans Proxmox, qui devrait à la fois résoudre le problème de clavier qwerty ET le problème de presse-papier.&lt;/p&gt;
&lt;h2 id="cloud-config-suite"&gt;Cloud-config, suite
&lt;/h2&gt;&lt;p&gt;On récupère ce qu’on vient d’exporter et on ajoute notre clé comme nous le demande Rancher dans sa doc. Et avant de lancer l’install, on vérifie que notre cloud-config est valide&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros config validate -i cloud-config.yml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si la commande ne renvoie rien, c’est que c’est OK (pas super explicite mais bon why not). On passe donc à l’install :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros install -c cloud-config.yml -d /dev/sda
INFO[0000] No install type specified...defaulting to generic
Installing from rancher/os:v0.5.0
Continue [y/N]:
[...]
Continue with reboot [y/N]: y
INFO[0013] Rebooting
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, on peut (et on doit) se connecter en SSH sur la machine RancherOS (l’accès console n’est plus possible)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh -J proxmoxve rancher@192.168.1.10
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Et si tout s’est bien passé, vous devriez pouvoir vous connecter !&lt;/p&gt;
&lt;h2 id="et-maintenant-que-vais-je-fai-reuh-"&gt;Et maintenant, que vais-je fai-reuh ?
&lt;/h2&gt;&lt;p&gt;Ben déjà on peut regarder ce que RancherOS a activé comme &amp;ldquo;services&amp;rdquo; sur notre install Proxmox VE.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo ros service list
disabled amazon-ecs-agent
disabled container-cron
disabled open-iscsi
disabled zfs
disabled kernel-extras
disabled kernel-headers
disabled kernel-headers-system-docker
disabled open-vm-tools
disabled hyperv-vm-tools
enabled qemu-guest-agent
disabled rancher-server
disabled rancher-server-stable
disabled amazon-metadata
disabled volume-cifs
disabled volume-efs
disabled volume-nfs
disabled modem-manager
disabled waagent
disabled virtualbox-tools
disabled pingan-amc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Globalement, pas grand chose. La seule chose activée est le qemu-guest-agent, ce qui est utile puisque nous avons une effectivement une VM QEMU dans ce cas précis.
Quant à vos containers Docker, vous pouvez vérifier qu’ils sont bien séparés des containers docker servant au fonctionnement de RancherOS avec les commandes suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les containers &amp;ldquo;systèmes&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[rancher@rancher ~]$ sudo system-docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e059e78c17e rancher/os-docker:19.03.11 &amp;#34;ros user-docker&amp;#34; 12 minutes ago Up 12 minutes docker
ba43a0648227 rancher/os-qemuguestagent:v2.8.1-2 &amp;#34;/usr/bin/ros entr...&amp;#34; 12 minutes ago Restarting (1) 34 seconds ago qemu-guest-agent
d9ad607221fa rancher/os-console:v1.5.6 &amp;#34;/usr/bin/ros entr...&amp;#34; 12 minutes ago Up 12 minutes console
ad0197c79ff2 rancher/os-base:v1.5.6 &amp;#34;/usr/bin/ros entr...&amp;#34; 12 minutes ago Up 12 minutes ntp
538ccf5eb624 rancher/os-base:v1.5.6 &amp;#34;/usr/bin/ros entr...&amp;#34; 12 minutes ago Up 12 minutes network
f389c6b0b40e rancher/os-base:v1.5.6 &amp;#34;/usr/bin/ros entr...&amp;#34; 12 minutes ago Up 12 minutes udev
b51deb379bf2 rancher/container-crontab:v0.4.0 &amp;#34;container-crontab&amp;#34; 12 minutes ago Up 12 minutes system-cron
59441adcc016 rancher/os-syslog:v1.5.6 &amp;#34;/usr/bin/entrypoi...&amp;#34; 13 minutes ago Up 12 minutes syslog
120df7cc2492 rancher/os-acpid:v1.5.6 &amp;#34;/usr/bin/ros entr...&amp;#34; 13 minutes ago Up 12 minutes acpid
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Vos containers :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[rancher@rancher ~]$ docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Les containers &amp;ldquo;systèmes&amp;rdquo; sont bien distincts des containers docker &amp;ldquo;utilisateurs&amp;rdquo;. La promesse d’isolation Docker infra vs Docker appli est bien tenue.&lt;/p&gt;
&lt;h2 id="mon-avis"&gt;Mon avis
&lt;/h2&gt;&lt;p&gt;A voir à l’usage, mais je ne suis pas hyper convaincu.&lt;/p&gt;
&lt;p&gt;D’abord, en termes d’OS minimalistes, on a quand même vu mieux. Et d’ailleurs, &lt;a class="link" href="https://rancher.com/docs/os/v1.x/en/installation/custom-builds/custom-rancheros-iso/#reduce-memory-requirements" target="_blank" rel="noopener"
&gt;les gens chez Rancher le savent puisqu’ils se sentent obligés de s’en justifier&lt;/a&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Plus grave, l’UX est quand même super bof. J’ai l’habitude d’installer des softs mais je me suis quand même pris la tête avec le cloud-config assez moyennement documenté, et en plus, à faire DANS une console (et la galère QWERTY/AZERTY associée).&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Et c’est pas fini&amp;rdquo;, comme dis la pub.&lt;/p&gt;
&lt;p&gt;Je vous l’ai dis, mon objectif est d’avoir un cluster Kubernetes installé par RKE. Or, il n’est pas trivial d’utiliser RancherOS comme OS pour hoster un Kubernetes déployé avec RKE. Vous verrez dans la partie 2 que ça n’a pas été une partie de plaisir&amp;hellip;&lt;/p&gt;
&lt;p&gt;Un comble pour 2 produits de la même boite censé vous simplifier l’administration de Docker/Kube&amp;hellip;&lt;/p&gt;
&lt;p&gt;Et plus grave encore, c’est que j’ai du mal à voir pour qui ce genre de distribs apporte de la valeur. C’est d’ailleurs pour cette même raison pour laquelle je n’avais pas poussé l’expérimentation très loin avec CoreOS. En tant qu’admin, je suis forcément frustré par un OS où je n’ai pas/peu la main.&lt;/p&gt;
&lt;p&gt;J’aime bien ce qu’ils font chez Rancher. Mais je ne sais pas répondre à la question Pourquoi RancherOS ?
On pourrait se dire que pour une équipe de développeurs en mode startup qui doit sortir son MVP en peu de temps, ça peut être cool.&lt;/p&gt;
&lt;p&gt;Mais même là, j’ai des doutes.&lt;/p&gt;
&lt;p&gt;Si ces gens là veulent VRAIMENT s’abstraire d’Ops (voir mon avis sur la question dans &lt;a class="link" href="https://blog.zwindler.fr/2020/07/29/au-secours-le-metier-dops-va-disparaitre/" &gt;Au secours, le métier d’Ops va disparaître !&lt;/a&gt;), ils partiront sur d’autres types de technos (Kubernetes managé, Serverless, No code ?).&lt;/p&gt;
&lt;p&gt;Si vous voyez une raison que j’aurais loupé, n’hésitez pas à venir en parler en commentaire ou via les RS, car là je vois pas&amp;hellip;&lt;/p&gt;
&lt;p&gt;En attendant la partie sur RKE, have fun :)&lt;/p&gt;</description></item></channel></rss>