<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Control Plane on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/control-plane/</link><description>Recent content in Control Plane on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Sat, 19 Jul 2025 13:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/control-plane/index.xml" rel="self" type="application/rss+xml"/><item><title>Créer un cluster Kubernetes sur Clever Cloud avec les apps Linux</title><link>https://blog.zwindler.fr/2025/07/20/kubernetes-sur-clever-cloud-linux/</link><pubDate>Sat, 19 Jul 2025 13:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2025/07/20/kubernetes-sur-clever-cloud-linux/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/07/k8s-clever.webp" alt="Featured image of post Créer un cluster Kubernetes sur Clever Cloud avec les apps Linux" /&gt;&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Après avoir testé les &lt;a class="link" href="https://blog.zwindler.fr/2025/07/07/je-reessaye-les-sites-statiques-chez-clever/" &gt;apps statiques chez Clever Cloud&lt;/a&gt;, j&amp;rsquo;ai voulu pousser plus loin l&amp;rsquo;exploration des nouvelles fonctionnalités.&lt;/p&gt;
&lt;p&gt;Clever Cloud a en effet lancé récemment un nouveau type d&amp;rsquo;application : les &lt;strong&gt;apps Linux&lt;/strong&gt;. Ces dernières permettent de déployer des applications génériques sur une machine Linux, sans runtime prédéfini. Un peu comme avoir sa propre VM, mais managée par Clever Cloud.&lt;/p&gt;
&lt;p&gt;Du coup, pour &amp;ldquo;rigoler&amp;rdquo; (et par pure curiosité technique), j&amp;rsquo;ai décidé de créer un &lt;strong&gt;control plane Kubernetes&lt;/strong&gt; complet sur ce type d&amp;rsquo;instance. Pourquoi ?&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;abord parce que je parle tout le temps de Kubernetes. Et ensuite, pour faire un petit clin d&amp;rsquo;œil aux copains de chez Clever Cloud : ils annoncent depuis des mois leur offre Kubernetes managée qui devrait sortir (soon™).&lt;/p&gt;
&lt;p&gt;Et en poussant les runtimes Linux dans leurs retranchements, ça m&amp;rsquo;a permis de découvrir pas mal de fonctionnalités que (j&amp;rsquo;avoue) je ne connaissais pas chez Clever.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt; : ce projet est purement éducatif et expérimental. Ne l&amp;rsquo;utilisez pas, même pour un usage personnel !&lt;/p&gt;
&lt;h2 id="le-projet--k8s-on-clever-linux"&gt;Le projet : k8s-on-clever-linux
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai créé un dépôt GitHub dédié à ce projet : &lt;a class="link" href="https://github.com/zwindler/k8s-on-clever-linux" target="_blank" rel="noopener"
&gt;k8s-on-clever-linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le principe est simple : déployer tous les composants du control plane Kubernetes (etcd, kube-apiserver, kube-controller-manager, kube-scheduler) comme des processus sur une app Linux Clever Cloud.&lt;/p&gt;
&lt;p&gt;Le projet s&amp;rsquo;inspire fortement de mon tutoriel &lt;a class="link" href="https://github.com/zwindler/demystifions-kubernetes" target="_blank" rel="noopener"
&gt;demystifions-kubernetes&lt;/a&gt;. Et d&amp;rsquo;ailleurs, pour tester le &lt;em&gt;proof of concept&lt;/em&gt;, c&amp;rsquo;est ce que j&amp;rsquo;ai bêtement déroulé, pour valider la faisabilité.&lt;/p&gt;
&lt;p&gt;Cependant, dans le cas de Clever, plutôt que de lancer tous les composants un par un en déroulant un script bash (ce qui est fait dans github.com/zwindler/demystifions-kubernetes), j&amp;rsquo;ai fait un poil plus rusé&amp;hellip;&lt;/p&gt;
&lt;h2 id="découverte-de-mise"&gt;Découverte de Mise.
&lt;/h2&gt;&lt;p&gt;Mais d&amp;rsquo;abord un peu de contexte :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Clever Cloud platform provides a multi-runtime environment, including many tools to deploy and run your applications. The Linux runtime is a versatile solution to build and deploy any kind of application. The Mise package manager helps you to install and manage any supported dependencies Clever Cloud doesn’t provide by default such as Dart, Gleam, Zig for example.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.clever-cloud.com/developers/doc/applications/linux/" target="_blank" rel="noopener"
&gt;Documentation officielle des Linux runtimes chez Clever Cloud&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Déjà, ça parle d&amp;rsquo;un truc qui s&amp;rsquo;appelle &lt;strong&gt;Mise package manager&lt;/strong&gt;. C&amp;rsquo;est quoi ça ?&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agit d&amp;rsquo;un projet de &lt;em&gt;Jeff Dickey&lt;/em&gt; (&lt;a class="link" href="https://jdx.dev/" target="_blank" rel="noopener"
&gt;jdx.dev&lt;/a&gt;). Sur nos apps Linux, ça va nous permettre d&amp;rsquo;installer une partie des dépendances d&amp;rsquo;une part, et d&amp;rsquo;ordonnancer le lancement de commandes pour &lt;em&gt;build&lt;/em&gt;, puis pour &lt;em&gt;run&lt;/em&gt; notre projet dans l&amp;rsquo;instance Linux&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mise.jdx.dev/dev-tools/" target="_blank" rel="noopener"
&gt;mise.jdx.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="découpage-de-lapplication"&gt;Découpage de l&amp;rsquo;application
&lt;/h2&gt;&lt;p&gt;Maintenant qu&amp;rsquo;on en sait plus, voilà comment j&amp;rsquo;ai découpé l&amp;rsquo;application avec Mise :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Initialisation (&lt;code&gt;mise.toml&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Même si tous les prérequis ne sont pas tous disponibles dans Mise, je peux quand même déléguer le téléchargement d&amp;rsquo;une partie d&amp;rsquo;entre eux, ce qui va alléger le script de téléchargement des dépendances par rapport à &lt;strong&gt;démystifions kubernetes&lt;/strong&gt;. C&amp;rsquo;est toujours bon à prendre :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;cfssl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;etcd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;helm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Phase de build (&lt;code&gt;.mise-tasks/build&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Télécharge tous les binaires Kubernetes&lt;/li&gt;
&lt;li&gt;Génère les certificats pour l&amp;rsquo;authentification des composants&lt;/li&gt;
&lt;li&gt;Configure les paramètres statiques&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mise en cache&lt;/strong&gt; : cette phase n&amp;rsquo;est exécutée que lors des changements de code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De cette manière, en cas de reboot de l&amp;rsquo;application, on ne perd pas les certificats et on gagne un peu de temps pour le redéploiement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase de run (&lt;code&gt;.mise-tasks/run&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lancer tous les composants de notre control plane Kubernetes&lt;/li&gt;
&lt;li&gt;Génère un bootstrap token pour ajouter des Nodes&lt;/li&gt;
&lt;li&gt;Lance un serveur HTTP qui écoute sur le port 8080 et ne sert&amp;hellip; rien.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pourquoi un serveur HTTP ? Eh bien tout simplement parce que&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Linux runtime only requires a CC_RUN_COMMAND to execute, with a working web application listening on 0.0.0.0:8080.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si je ne mets rien en écoute sur le port 8080, Clever va logguer que mon app est en panne (alors que non).&lt;/p&gt;
&lt;h2 id="focus-sur-mise-pour-installer-les-dépendances"&gt;Focus sur Mise pour installer les dépendances
&lt;/h2&gt;&lt;p&gt;Concrêtement, comment ça se présente quand on lance une app dans Clever Cloud avec un mise.toml ?&lt;/p&gt;
&lt;p&gt;Ben tout simplement comme ça :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;2025-07-20T15:54:04.304Z mise etcd@3.6.2 install
2025-07-20T15:54:05.302Z mise etcd@3.6.2 download etcd-v3.6.2-linux-amd64.tar.gz
2025-07-20T15:54:06.403Z mise etcd@3.6.2 checksum etcd-v3.6.2-linux-amd64.tar.gz
2025-07-20T15:54:06.422Z mise etcd@3.6.2 extract etcd-v3.6.2-linux-amd64.tar.gz
2025-07-20T15:54:06.705Z mise etcd@3.6.2 ✓ installed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La liste des tools disponibles avec mise est ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://mise.jdx.dev/registry.html" target="_blank" rel="noopener"
&gt;mise.jdx.dev/registry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et on peut remarquer que les tools viennent de différentes sources telles qu&amp;rsquo;aqua, pipx, ubi, asdf&amp;hellip; Ça me donne envie de tester ça pour les dépendances qui me manquent donc attendez-vous à un prochain article sur le sujet :).&lt;/p&gt;
&lt;h2 id="mais-ils-sont-où-les-binaires-du-control-plane-de-kubernetes-"&gt;Mais&amp;hellip; ils sont où les binaires du control plane de Kubernetes ?
&lt;/h2&gt;&lt;p&gt;Initialement, j&amp;rsquo;avais mis tout ça dans la phase de &lt;code&gt;run&lt;/code&gt;. Sauf que David m&amp;rsquo;a proposé de découvrir une autre fonctionnalité de Clever Cloud que je n&amp;rsquo;avais jamais utilisée : les Workers.&lt;/p&gt;
&lt;p&gt;Les &lt;strong&gt;Workers&lt;/strong&gt; sont des processus en arrière-plan qui tournent en parallèle de votre application principale.&lt;/p&gt;
&lt;p&gt;Pour notre cluster Kubernetes, c&amp;rsquo;est &lt;strong&gt;parfait&lt;/strong&gt; ! Plutôt que de lancer tous les composants dans un script bash, chaque composant du control plane devient un worker dédié :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Worker 0&lt;/strong&gt;: &lt;code&gt;./run-scripts/start-etcd.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker 1&lt;/strong&gt;: &lt;code&gt;./run-scripts/start-kube-apiserver.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker 2&lt;/strong&gt;: &lt;code&gt;./run-scripts/start-kube-controller-manager.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker 3&lt;/strong&gt;: &lt;code&gt;./run-scripts/start-kube-scheduler.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker 4&lt;/strong&gt;: &lt;code&gt;./run-scripts/post-boot.sh&lt;/code&gt; - bootstrap tokens, RBAC, worker scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avec en bonus la possibilité de configurer le comportement de redémarrage :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CC_WORKER_RESTART=on-failure&lt;/code&gt; (par défaut) : redémarre seulement en cas d&amp;rsquo;erreur&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CC_WORKER_RESTART=always&lt;/code&gt; : redémarre toujours&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CC_WORKER_RESTART_DELAY=1&lt;/code&gt; : délai en secondes avant redémarrage&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installation-et-configuration"&gt;Installation et configuration
&lt;/h2&gt;&lt;p&gt;Bon, clairement, cette partie n&amp;rsquo;est pas la plus user-friendly du tutoriel. Si vous voulez plus de détails sur ce qui est fait et pourquoi, vous pouvez aller jeter un œil directement sur le dépôt &lt;a class="link" href="https://github.com/zwindler/k8s-on-clever-linux" target="_blank" rel="noopener"
&gt;github.com/zwindler/k8s-on-clever-linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les grandes étapes sont :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Créer l&amp;rsquo;app Linux &lt;code&gt;clever create --type linux --github zwindler/k8s-on-clever-linux&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configuration de la redirection TCP&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Linux runtime only requires a CC_RUN_COMMAND to execute, with a working web application listening on 0.0.0.0:8080.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pour rappel, Clever Cloud s&amp;rsquo;attend à ce qu&amp;rsquo;on expose une app en HTTP non sécurisé sur le port 8080. Sauf que moi, je veux exposer l&amp;rsquo;API server Kubernetes en HTTPS. On va donc activer la &amp;ldquo;redirection TCP&amp;rdquo; : Clever Cloud attribue un port aléatoire (dans les 5XXX) qui redirige vers le port 4040 de votre application (et donc je dois dire à l&amp;rsquo;API server de ne pas écouter sur le 6443, mais 4040) :&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;$ clever tcp-redirs add --namespace default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Successfully added tcp redirection on port: &lt;span class="m"&gt;5131&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Configuration du domaine&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une fois le port TCP connu, on peut configurer notre domaine.&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;clever domain add k8soncleverlinux.domain.org
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dans mon cas, l&amp;rsquo;API server sera accessible sur le domaine &lt;code&gt;k8soncleverlinux.zwindler.fr&lt;/code&gt; et sur le port &lt;code&gt;5131&lt;/code&gt;. Comme ces deux valeurs seront différentes pour vous, j&amp;rsquo;ai vite codé un script qui permet de prendre les valeurs par défaut pour moi, mais vous permettre de les écraser si vous spécifiez des valeurs sur VOTRE app Clever Cloud :&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;clever env &lt;span class="nb"&gt;set&lt;/span&gt; K8S_DOMAIN k8soncleverlinux.zwindler.fr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;clever env &lt;span class="nb"&gt;set&lt;/span&gt; K8S_TCP_PORT &lt;span class="m"&gt;5131&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Je suis vraiment sympa.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Configuration des workers : pour ça j&amp;rsquo;ai fait un script &lt;code&gt;./setup-clever-workers.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce script configure 5 workers dont j&amp;rsquo;ai parlé plus haut et qui sont gérés par systemd.&lt;/p&gt;
&lt;h2 id="déploiement-et-test"&gt;Déploiement et test
&lt;/h2&gt;&lt;p&gt;Si tout s&amp;rsquo;est bien passé, l&amp;rsquo;app devrait correctement se lancer, Mise devrait lancer la phase de &lt;code&gt;build&lt;/code&gt; (surtout télécharger les dépendances qui manquent), puis la phase de &lt;code&gt;run&lt;/code&gt; (les dépendances connues de Mise, et les workers une fois que &lt;code&gt;run&lt;/code&gt; se termine) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;2025-07-19T13:10:45.130Z Successfully deployed in 0 minutes and 18 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Les workers en tâche de fond devraient démarrer tous les composants de notre control plane Kubernetes. Au bout de quelques secondes (1 minute max), on devrait avoir un control plane fonctionnel, et tout un tas de certificats et autres secrets.&lt;/p&gt;
&lt;p&gt;Mais comment le tester ? Via SSH sur l&amp;rsquo;instance Clever Cloud ! Car oui, on peut SSH sur cette instance :)&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;$ clever ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Last login: Fri Jul &lt;span class="m"&gt;18&lt;/span&gt; 20:17:00 UTC &lt;span class="m"&gt;2025&lt;/span&gt; on pts/0
&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 version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client Version: v1.33.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Kustomize Version: v5.6.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Server Version: v1.33.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;🎉 &lt;strong&gt;Ça marche !&lt;/strong&gt; On a bien un control plane Kubernetes qui tourne sur Clever Cloud !&lt;/p&gt;
&lt;p&gt;Et si vous avez bien travaillé (c&amp;rsquo;est à dire correctement configuré votre domaine et le port), on peut même l&amp;rsquo;utiliser depuis l&amp;rsquo;extérieur en copiant le fichier &lt;code&gt;admin.conf&lt;/code&gt; localement et en modifiant l&amp;rsquo;&lt;code&gt;endpoint&lt;/code&gt; dans le YAML :&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 cluster-info
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Kubernetes control plane is running at https://k8soncleverlinux.zwindler.fr:5131
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ajout-dun-worker-node"&gt;Ajout d&amp;rsquo;un worker node
&lt;/h2&gt;&lt;p&gt;Deuxième hic dans mon histoire. Un control plane sans worker, c&amp;rsquo;est pas terrible.&lt;/p&gt;
&lt;p&gt;Et je ne peux pas utiliser l&amp;rsquo;app de type Linux de chez Clever car je n&amp;rsquo;ai pas assez de privilèges pour changer les options kernel (routage) et installer &lt;strong&gt;containerd&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Mais je n&amp;rsquo;allais pas en rester là. Dans mon projet &amp;ldquo;Démystifions Kubernetes&amp;rdquo;, j&amp;rsquo;installe un worker directement sur la machine du control plane et j&amp;rsquo;utilise le &lt;code&gt;admin.conf&lt;/code&gt; (cluster-admin) pour enrôler l&amp;rsquo;hôte courant en tant que Node.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est cracra, mais quand je suis en conf et que j&amp;rsquo;ai 20 minutes pour speedrun, c&amp;rsquo;est acceptable.&lt;/p&gt;
&lt;p&gt;Ici, j&amp;rsquo;ai fait l&amp;rsquo;effort d&amp;rsquo;aller regarder comment faire pour enrôler des Nodes avec un bootstrap token et c&amp;rsquo;est assez intéressant.&lt;/p&gt;
&lt;p&gt;La doc officielle de kube est plutôt bien faite et je ferai peut-être un article à part sur le sujet, c&amp;rsquo;est assez facile en fait, avec un flag à ajouter dans l&amp;rsquo;API server, quelques RBAC et un secret bien spécifique à générer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/" target="_blank" rel="noopener"
&gt;https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je vous épargne les détails, le projet va générer automatiquement un script pour ajouter des nodes externes :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;2025-07-19T13:51:47.848Z ✓ Worker setup script generated: setup-worker-node.sh
2025-07-19T13:51:47.849Z 📋 Next steps:
2025-07-19T13:51:47.849Z 1. Copy setup-worker-node.sh to your external worker node
2025-07-19T13:51:47.849Z 2. (Optional) Edit NODE_NAME_OVERRIDE and NODE_IP_OVERRIDE if auto-detection is incorrect
2025-07-19T13:51:47.849Z 3. Ensure your worker node has sudo privileges and internet access
2025-07-19T13:51:47.849Z 4. Run the script on your worker node: sudo ./setup-worker-node.sh
2025-07-19T13:51:47.849Z 5. Check the node joined with: kubectl get nodes
&lt;/code&gt;&lt;/pre&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;&lt;span class="c1"&gt;# Script généré automatiquement&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/bin/bash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# External Worker Node Setup Script for Kubernetes&lt;/span&gt;
&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;&lt;span class="nv"&gt;API_SERVER_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://k8soncleverlinux.zwindler.fr:5131&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;BOOTSTRAP_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;xxxxxx.xxxxxxxxxxxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... (configuration complète et certificats/secrets inclus)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il suffit de copier ce script sur une VM Linux quelconque et de l&amp;rsquo;exécuter. Le script :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installe containerd, kubelet, kube-proxy&lt;/li&gt;
&lt;li&gt;Configure automatiquement l&amp;rsquo;authentification via bootstrap token&lt;/li&gt;
&lt;li&gt;Démarre les services&lt;/li&gt;
&lt;/ul&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;✓ Worker node setup completed!
&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 nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;coucou1 NotReady &amp;lt;none&amp;gt; 13m v1.33.3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le node apparaît en &amp;ldquo;NotReady&amp;rdquo; car il manque le plugin CNI. Flannel fonctionne parfaitement :&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 https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
&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 nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;coucou1 Ready &amp;lt;none&amp;gt; 30m v1.33.3
&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 -A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAMESPACE NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kube-flannel kube-flannel-ds-b65jg 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 14m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le &lt;strong&gt;cluster est fonctionnel 😎😎😎 !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On a maintenant un cluster Kubernetes complet avec control plane sur Clever Cloud et worker externe&amp;hellip; Avant la sortie du kube managé de Clever.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/07/Trollface.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="limitations-et-évolutions-possibles"&gt;Limitations et évolutions possibles
&lt;/h2&gt;&lt;p&gt;Le worker externe n&amp;rsquo;étant pas dans le réseau Clever Cloud, l&amp;rsquo;API server ne peut pas communiquer avec le kubelet (dans le sens api-server -&amp;gt; kubelet uniquement). Cela limite les fonctionnalités comme &lt;code&gt;kubectl logs&lt;/code&gt;, &lt;code&gt;kubectl exec&lt;/code&gt;, etc. Une solution possible serait d&amp;rsquo;utiliser les &lt;a class="link" href="https://www.clever-cloud.com/developers/doc/develop/network-groups/" target="_blank" rel="noopener"
&gt;Network Groups&lt;/a&gt; de Clever Cloud pour créer un réseau privé sécurisé.&lt;/p&gt;
&lt;p&gt;Si ce projet continue de m&amp;rsquo;amuser, plusieurs améliorations sont envisageables :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;exploration des Network Groups (dont je viens de parler)&lt;/li&gt;
&lt;li&gt;intégration de &lt;a class="link" href="https://github.com/k3s-io/kine" target="_blank" rel="noopener"
&gt;Kine&lt;/a&gt;. Cela permettrait d&amp;rsquo;utiliser les bases de données existantes de Clever Cloud (PostgreSQL, MySQL) comme DB pour Kubernetes, ce qui permettrait éventuellement de rendre cette install &amp;ldquo;HA&amp;rdquo; ce qui serait aussi débile que rigolo&lt;/li&gt;
&lt;li&gt;création des packages aqua/ubi manquants (les binaires de kubernetes et &lt;code&gt;cfssljson&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai commencé ce projet comme une blague et j&amp;rsquo;ai finalement mis le doigt dans plein de petites fonctionnalités cools de chez Clever Cloud et dont j&amp;rsquo;ignorais l&amp;rsquo;existence (ou alors, que j&amp;rsquo;avais vu passer mais pas creusé).&lt;/p&gt;
&lt;p&gt;Même si ça m&amp;rsquo;a pris quelques soirées, c&amp;rsquo;était super intéressant. La première itération a été très vite fonctionnelle et je me suis pris au jeu des améliorations successives.&lt;/p&gt;
&lt;p&gt;Le code complet est disponible sur &lt;a class="link" href="https://github.com/zwindler/k8s-on-clever-linux" target="_blank" rel="noopener"
&gt;GitHub&lt;/a&gt; si vous voulez reproduire l&amp;rsquo;expérience ou contribuer !&lt;/p&gt;
&lt;p&gt;Et vous, quels projets fous avez-vous envie de tester avec les apps &lt;strong&gt;Linux&lt;/strong&gt; ? 😄 Moi, j&amp;rsquo;attends mon accès au k8s managé de Clever Cloud maintenant 😝 (comment ça, je suis un gros &lt;em&gt;forceur&lt;/em&gt; ???)&lt;/p&gt;</description></item></channel></rss>