<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Conteneur on slash-root.fr</title><link>https://beta.slash-root.fr/tags/conteneur/</link><description>Recent content in Conteneur on slash-root.fr</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><lastBuildDate>Sun, 15 Jun 2025 16:17:21 +0200</lastBuildDate><atom:link href="https://beta.slash-root.fr/tags/conteneur/index.xml" rel="self" type="application/rss+xml"/><item><title>Docker : Configuration des réseaux par défaut</title><link>https://beta.slash-root.fr/docker-configuration-des-reseaux-par-defaut/</link><pubDate>Sun, 15 Jun 2025 16:17:21 +0200</pubDate><guid>https://beta.slash-root.fr/docker-configuration-des-reseaux-par-defaut/</guid><description>&lt;img src="https://beta.slash-root.fr/docker-configuration-des-reseaux-par-defaut/cover.png" alt="Featured image of post Docker : Configuration des réseaux par défaut" /&gt;&lt;p&gt;Salut les admins sys et autres dompteurs de conteneurs ! Aujourd'hui, plongeons dans le fascinant (et parfois frustrant) monde des réseaux Docker. Comme on dit dans notre jargon : &amp;quot;Un conteneur sans réseau, c'est comme un pingouin sans banquise - techniquement possible, mais pas vraiment utile.&amp;quot;&lt;/p&gt;
&lt;h2 id="les-réseaux-docker-par-défaut"&gt;&lt;a href="#les-r%c3%a9seaux-docker-par-d%c3%a9faut" class="header-anchor"&gt;&lt;/a&gt;Les réseaux Docker par défaut
&lt;/h2&gt;&lt;p&gt;Docker, cet invité un peu sans-gêne, s'installe et crée directement trois réseaux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bridge&lt;/code&gt; : Le réseau par défaut où tous vos conteneurs font la fête (172.17.0.0/16)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;host&lt;/code&gt; : Pour quand vos conteneurs veulent se sentir comme à la maison&lt;/li&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt; : Pour les conteneurs asociaux qui préfèrent rester dans leur coin&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le réseau &lt;code&gt;bridge&lt;/code&gt; s'approprie allègrement la plage 172.17.0.0/16. Mais que se passe-t-il quand cette plage est déjà occupée par votre infrastructure existante ? Eh bien, c'est un peu comme deux familles qui réservent le même bungalow pour les vacances - ça crée des tensions.&lt;/p&gt;
&lt;h3 id="résolution-des-conflits-avec-le-réseau-par-défaut"&gt;&lt;a href="#r%c3%a9solution-des-conflits-avec-le-r%c3%a9seau-par-d%c3%a9faut" class="header-anchor"&gt;&lt;/a&gt;Résolution des conflits avec le réseau par défaut
&lt;/h3&gt;&lt;p&gt;Pour modifier la plage d'adresses que Docker utilise par défaut, éditez le fichier &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; (si le fichier n'existe pas, créez-le avec la même joie que lorsque vous créez un nouveau répertoire &lt;code&gt;batman&lt;/code&gt;) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;default-address-pools&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;192.168.66.0/24&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;size&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Après cette modification, un petit redémarrage s'impose :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="incrémentation-automatique-des-réseaux-docker"&gt;&lt;a href="#incr%c3%a9mentation-automatique-des-r%c3%a9seaux-docker" class="header-anchor"&gt;&lt;/a&gt;Incrémentation automatique des réseaux Docker
&lt;/h2&gt;&lt;p&gt;Quand vous créez de nouveaux réseaux Docker avec &lt;code&gt;docker network create&lt;/code&gt;, Docker fait preuve d'une logique implacable pour l'allocation des sous-réseaux. En fonction de votre configuration &lt;code&gt;default-address-pools&lt;/code&gt;, Docker va attribuer automatiquement des plages d'adresses IP qui s'incrémentent à chaque nouveau réseau :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create mon-super-reseau
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour cette commande, Docker utilisera automatiquement la première plage disponible: 192.168.66.0/24&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create mon-autre-reseau
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour ce deuxième réseau, Docker passera à la plage suivante: 192.168.67.0/24&lt;/p&gt;
&lt;p&gt;C'est comme distribuer des tranches de gâteau - mais en version IP.&lt;/p&gt;
&lt;p&gt;Si vous préférez choisir votre part vous-même :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create --subnet&lt;span style="color:#f92672"&gt;=&lt;/span&gt;192.168.42.0/24 mon-reseau-avec-le-nombre-de-la-vie
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="les-différents-types-de-réseaux-docker"&gt;&lt;a href="#les-diff%c3%a9rents-types-de-r%c3%a9seaux-docker" class="header-anchor"&gt;&lt;/a&gt;Les différents types de réseaux Docker
&lt;/h2&gt;&lt;h3 id="dans-un-docker-engine-standalone"&gt;&lt;a href="#dans-un-docker-engine-standalone" class="header-anchor"&gt;&lt;/a&gt;Dans un Docker Engine standalone
&lt;/h3&gt;&lt;p&gt;Un Docker Engine standard (non-Swarm) propose plusieurs types de réseaux pour répondre à des besoins distincts :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bridge&lt;/code&gt; : Le réseau par défaut utilisé par les conteneurs. C'est un réseau virtuel interne qui permet aux conteneurs de communiquer entre eux et avec l'hôte.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;host&lt;/code&gt; : Supprime l'isolation réseau entre le conteneur et l'hôte. Le conteneur utilise directement la pile réseau de l'hôte. Utile pour les performances mais réduit l'isolation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;none&lt;/code&gt; : Désactive complètement le réseau. Le conteneur n'a aucun accès réseau externe. Utile pour les traitements isolés ne nécessitant pas de communication.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;macvlan&lt;/code&gt; : Attribue une adresse MAC physique aux conteneurs, les faisant apparaître comme des périphériques physiques sur le réseau. Idéal pour migrer des applications legacy qui dépendent d'IPs spécifiques.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Créer un réseau bridge personnalisé (recommandé au lieu du bridge par défaut)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create --driver bridge mon-reseau-bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="dans-un-cluster-docker-swarm"&gt;&lt;a href="#dans-un-cluster-docker-swarm" class="header-anchor"&gt;&lt;/a&gt;Dans un cluster Docker Swarm
&lt;/h3&gt;&lt;p&gt;Docker Swarm, c'est comme une colocation de conteneurs répartis sur plusieurs serveurs. La communication entre nœuds nécessite des réseaux spéciaux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;overlay&lt;/code&gt; : Permet aux conteneurs de différents nœuds de communiquer comme s'ils étaient sur le même hôte. Crée un réseau virtual &amp;quot;au-dessus&amp;quot; de l'infrastructure physique.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ingress&lt;/code&gt; : Un réseau overlay spécial qui facilite le routage du trafic entrant vers les services appropriés, indépendamment du nœud qui héberge le conteneur. Gère également l'équilibrage de charge interne.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Créer un réseau overlay pour les services Swarm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create --driver overlay --attachable mon-reseau-multi-hote
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tous ces réseaux peuvent coexister sur le même hote ou cluster, permettant ainsi une architecture réseau flexible et adaptée à chaque cas d'usage.&lt;/p&gt;
&lt;h3 id="le-réseau-ingress-et-la-plage-100008"&gt;&lt;a href="#le-r%c3%a9seau-ingress-et-la-plage-100008" class="header-anchor"&gt;&lt;/a&gt;Le réseau Ingress et la plage 10.0.0.0/8
&lt;/h3&gt;&lt;p&gt;Par défaut, ce cher réseau &lt;code&gt;ingress&lt;/code&gt; s'installe confortablement dans la plage 10.0.0.0/8. Si vous utilisez déjà cette plage, les symptômes sont clairs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker vous lance des erreurs cryptiques avec &amp;quot;network overlap&amp;quot;&lt;/li&gt;
&lt;li&gt;Vos conteneurs deviennent subitement muets&lt;/li&gt;
&lt;li&gt;Vous commencez à douter de vos choix de carrière&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reconfiguration-du-réseau-ingress"&gt;&lt;a href="#reconfiguration-du-r%c3%a9seau-ingress" class="header-anchor"&gt;&lt;/a&gt;Reconfiguration du réseau Ingress
&lt;/h3&gt;&lt;p&gt;Contrairement à ce qu'on pourrait croire, &lt;strong&gt;pas besoin de quitter le swarm&lt;/strong&gt; pour résoudre ce problème ! Une approche beaucoup plus civilisée consiste à :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Supprimer poliment le réseau ingress existant :&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network rm ingress
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;Créer un nouveau réseau ingress avec votre propre plage :&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker network create &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --driver overlay &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --ingress &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --subnet&lt;span style="color:#f92672"&gt;=&lt;/span&gt;172.30.0.0/16 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --gateway&lt;span style="color:#f92672"&gt;=&lt;/span&gt;172.30.0.1 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ingress
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Voilà qui est beaucoup moins traumatisant pour votre swarm que de tout démolir et reconstruire !&lt;/p&gt;
&lt;h2 id="bonnes-pratiques-pour-la-gestion-des-réseaux-docker"&gt;&lt;a href="#bonnes-pratiques-pour-la-gestion-des-r%c3%a9seaux-docker" class="header-anchor"&gt;&lt;/a&gt;Bonnes pratiques pour la gestion des réseaux Docker
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Planifiez votre allocation d'adresses IP&lt;/strong&gt; : Un schéma bien pensé vaut mieux qu'une nuit blanche de débogage&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choisissez le bon type de réseau&lt;/strong&gt; : Ne vous limitez pas au &lt;code&gt;bridge&lt;/code&gt; par défaut.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bridge personnalisé&lt;/strong&gt; (&lt;code&gt;docker network create my_bridge&lt;/code&gt;) : Résolution DNS entre conteneurs, isolation, idéal pour les applications sur un seul hôte&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overlay&lt;/strong&gt; (&lt;code&gt;docker network create -d overlay my_overlay&lt;/code&gt;) : Communication entre hôtes dans Swarm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Macvlan&lt;/strong&gt; (&lt;code&gt;docker network create -d macvlan --subnet=192.168.40.0/24 --gateway=192.168.40.1 -o parent=eth0 my_macvlan&lt;/code&gt;) : Intégration au réseau physique&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sécurisez votre infrastructure&lt;/strong&gt; : &lt;strong&gt;Évitez d'exposer les ports de base de données&lt;/strong&gt; (comme MySQL, PostgreSQL, MongoDB) sur votre réseau hôte. C'est une faille de sécurité courante et totalement évitable. Dans les réseaux Docker Compose ou Swarm, la communication inter-services se fait nativement via le nom du service. En pratique, votre service d'application peut simplement utiliser &lt;code&gt;db:3306&lt;/code&gt; comme adresse de connexion, sans jamais avoir à publier le port 3306 sur l'interface de l'hôte. Dans Swarm, cette communication fonctionne même entre des conteneurs déployés sur différents nœuds physiques via les réseaux overlay&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Adoptez une nomenclature claire&lt;/strong&gt; : Préférez &lt;code&gt;project_frontend_net&lt;/code&gt; ou &lt;code&gt;prod_db_network&lt;/code&gt; à des noms génériques comme &lt;code&gt;net1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Documentez votre architecture réseau&lt;/strong&gt; : Votre futur vous (ou votre remplaçant après votre burnout) vous remerciera&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;&lt;a href="#conclusion" class="header-anchor"&gt;&lt;/a&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;La gestion des réseaux Docker ressemble parfois à un jeu de Tetris avec des blocs CIDR - challenging mais satisfaisant une fois maîtrisé. En comprenant comment Docker assigne et gère les adresses IP, vous pourrez éviter ces moments où, tard dans la nuit, vous fixez votre écran en murmurant &amp;quot;mais pourquoi ça ne communique pas ?&amp;quot;.&lt;/p&gt;
&lt;p&gt;Une bonne configuration réseau vous permettra de dormir tranquille, sachant que vos conteneurs peuvent socialiser entre eux sans créer d'incident diplomatique sur votre infrastructure.&lt;/p&gt;
&lt;p&gt;Et souvenez-vous : dans un monde de conteneurs éphémères, seule une bonne configuration réseau est éternelle (ou du moins, jusqu'au prochain &lt;code&gt;docker-compose down&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>Déployer une application sur Kubernetes</title><link>https://beta.slash-root.fr/deployer-une-application-sur-kubernetes/</link><pubDate>Thu, 06 Feb 2025 08:30:54 +0100</pubDate><guid>https://beta.slash-root.fr/deployer-une-application-sur-kubernetes/</guid><description>&lt;img src="https://beta.slash-root.fr/deployer-une-application-sur-kubernetes/cover.png" alt="Featured image of post Déployer une application sur Kubernetes" /&gt;&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Aujourd'hui, je vous embarque à bord de mon voyage, ce voyage consiste à progressivement remplacer mes conteneurs Docker par des services Kubernetes dans mon homelab.&lt;/p&gt;
&lt;p&gt;Pourquoi ce changement ?&lt;br /&gt;
Car étant encore étudiant et en plein dans le sujet, quoi de mieux que de mettre les mains dans le camboui ?&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Préparation&lt;/h1&gt;
&lt;h2 id="la-cible"&gt;&lt;a href="#la-cible" class="header-anchor"&gt;&lt;/a&gt;La cible
&lt;/h2&gt;&lt;p&gt;Parmi la liste des applications que je dois migrer, j'ai dû en choisir une, et Mealie a été l'heureuse gagnante.&lt;br /&gt;
&lt;a href="https://mealie.io/"&gt;C'est quoi Mealie ?&lt;/a&gt; Mealie est un gestionnaire de recettes de cuisine accessible via navigateur, entièrement self hosté.&lt;/p&gt;
&lt;h2 id="lexistant"&gt;&lt;a href="#lexistant" class="header-anchor"&gt;&lt;/a&gt;L&amp;rsquo;existant
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;: 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mealie&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ghcr.io/mealie-recipes/mealie:latest &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;mealie-front-01&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;restart&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;reverse-proxy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;traefik.enable=true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;traefik.http.routers.mealie-https.entrypoints=https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;traefik.http.routers.mealie-https.rule=Host(`mealie.homelab.domain.fr`)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-vol:/app/data/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;env_file&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/opt/docker/apps/mealie/stack.env&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;reverse-proxy&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;external&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mealie-network&lt;/span&gt;: {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mealie-vol&lt;/span&gt;: {}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ci-haut, vous pouvez voir le yaml docker-compose ayant servi à créer mon conteneur Mealie.&lt;/p&gt;
&lt;p&gt;Nous pouvons y observer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une image en tag latest (on ne juge pas !).&lt;/li&gt;
&lt;li&gt;2 Réseaux alloués
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mealie-network&lt;/code&gt; étant le réseau propre de cette stack.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reverse-proxy&lt;/code&gt; permettant de relier le conteneur au conteneur Reverse Proxy traefik, permettant d'exposer Mealie et de lui attribuer un Certificat Let's Encrypt.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Des labels:
&lt;ul&gt;
&lt;li&gt;Des middlewares classiques pour sécuriser l'accès au service Mealie.&lt;/li&gt;
&lt;li&gt;Deux routeurs, un &lt;code&gt;https&lt;/code&gt; pour forcer le port d'entrée sur le 443 et un routeur pour attribuer un hostname au conteneur.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Un volume Docker monté sur le chemin &lt;code&gt;/app/data&lt;/code&gt; du conteneur&lt;/li&gt;
&lt;li&gt;Un fichier d'environnement contenant toutes les clés-valeurs requises pour que Mealie fonctionne.&lt;/li&gt;
&lt;li&gt;Le port d'exposition du Conteneur dans le pod (ici, 9000)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="la-migration"&gt;&lt;a href="#la-migration" class="header-anchor"&gt;&lt;/a&gt;La migration
&lt;/h2&gt;&lt;p&gt;Maintenant que nous avons décortiqué les éléments présents, il va falloir les traduire en manifests Kubernetes.&lt;br /&gt;
Les manifests Kubernetes sont des fichiers yaml déclaratif qui vont dire à Kubernetes &lt;strong&gt;comment&lt;/strong&gt; on veut que notre application soit déployée.&lt;/p&gt;
&lt;p&gt;Il est important de noter que mes volumes sont provisonnés sur mon TrueNAS Scale grâce à une StorageClass via le protocole NFS, contrairement à Docker, où les volumes étaient stockés en local.&lt;br /&gt;
Mealie étant une application tournant sur du LiteSQL, le site de l'application ne recommande pas de faire du LiteSQL avec du NFS, j'ai donc dû opter pour une PostgreSQL dédiée.&lt;/p&gt;
&lt;p&gt;(Petite information, il existe un binaire nommé &lt;code&gt;kompose&lt;/code&gt; qui permet de faire une traduction d'un fichier docker-compose en manifests yaml, mais ça s'appelle enlever le fun de la découverte.)&lt;/p&gt;
&lt;p&gt;Reprenons notre liste à puce de la partie précédente.&lt;br /&gt;
Il nous faut:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Il nous faut un objet de type &lt;a href="https://kubernetes.io/fr/docs/concepts/workloads/controllers/deployment/"&gt;Deployment&lt;/a&gt;, il va servir à déployer les &lt;a href="https://kubernetes.io/fr/docs/concepts/workloads/pods/pod-overview/"&gt;Pods&lt;/a&gt; avec des configuration que j'aurais définie.&lt;br /&gt;
Ce manifest yaml contiendra:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L'image Docker de Mealie (On enlève le tag latest, c'est risqué de pointer sur un tag d'image en mouvement perpétuel).&lt;/li&gt;
&lt;li&gt;Le nombre de Replicas du pod (Un replica est une copie d'un pod, si l'un tombe l'autre prend la relève, sert aussi de loadbalancing en cas de workload important).&lt;/li&gt;
&lt;li&gt;Un appel à des clés-valeurs d'une Configmap, qui est un objet contenant ici mes variables d'environnement.&lt;/li&gt;
&lt;li&gt;Un appel a des clés-valeurs d'un Secret, qui est un objet qui contient ici les mots de passe de la base de donnée PostgreSQL.&lt;/li&gt;
&lt;li&gt;Un appel à un PersistentVolumeClaim, qui lui même est lié à un PersistentVolume qui sera monté sur &lt;code&gt;app/data&lt;/code&gt; nous reviendrons plus tard dessus, mais retenez que c'est le volume.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Un objet de type &lt;a href="https://kubernetes.io/fr/docs/concepts/workloads/controllers/statefulset/"&gt;StatefulSet&lt;/a&gt; pour déployer la base de donnée.&lt;br /&gt;
Le StatefulSet fonctionne presque exactement comme un Deployment, mais il est fait pour les services type stateful, les pods sont identifiés et non-interchangeable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensuite, on va avoir besoin de créer les objets &lt;a href="https://kubernetes.io/docs/concepts/configuration/configmap/"&gt;Configmap&lt;/a&gt; et &lt;a href="https://kubernetes.io/fr/docs/concepts/configuration/secret/"&gt;Secret&lt;/a&gt;.&lt;br /&gt;
Ces objets permettent de stocker sous forme de clé-valeur des informations, que ce soit des variables d'environnement, des arguments de commande, etc.., ils peuvent ensuite être consommés par des pods.&lt;br /&gt;
La différence entre un Secret et une Configmap réside dans le fait que les Secrets sont encodés en base64, et sont fait pour contenir des données sensibles.&lt;br /&gt;
Exemple d'une configmap:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;apiVersion&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ConfigMap&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;mealie-configmap&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;namespace&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;mealie&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ALLOW_SIGNUP&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;TZ&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Europe/Paris&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;DB_ENGINE&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;postgres&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;POSTGRES_USER&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;admin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pour que les pods puissent communiquer entre eux ET que le pod du front web soit disponible dehors, il nous faut des objets de type &lt;a href="https://kubernetes.io/fr/docs/concepts/services-networking/service/"&gt;Services&lt;/a&gt;.&lt;br /&gt;
Les Services permettent d'exposer un ou plusieurs pods, car les pods de nature sont amenés à être détruits et recréés, et leur IP changent également.&lt;br /&gt;
La logique d'un service fonctionne donc comme ça:&lt;br /&gt;
Les Pods ont des labels sous forme de clé valeur --&amp;gt; Les Services qui ont une IP statique visent ces labels, et sont donc attribués à ces pods, le service peut même faire du LoadBalancing entre les pods qu'il expose.&lt;br /&gt;
Un service au minimum demande:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le protocole du port qu'on va exposer (TCP ou UDP).&lt;/li&gt;
&lt;li&gt;Le port que le Service expose (donc son propre port).&lt;/li&gt;
&lt;li&gt;Le port du conteneur que le Service va viser.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour nos besoins, il faudra créer un service pour exposer la base de donnée et un service pour exposer le front.&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Pour les volumes, il faut faire une introduction aux &lt;a href="https://kubernetes.io/fr/docs/concepts/storage/persistent-volumes/"&gt;PersistentVolumes&lt;/a&gt; (PV) et aux PersistentVolumeClaims (PVC).&lt;br /&gt;
Un PV est un volume de stockage défini provisionné manuellement ou dynamiquement (via une &lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/"&gt;StorageClass&lt;/a&gt;).&lt;br /&gt;
Le PVC quant à lui est une requête pour consommer un PV.&lt;br /&gt;
Dans mon cas à moi, j'utilise une StorageClass qui est issue du CSI (Container Storage Interface) &lt;a href="https://github.com/democratic-csi/democratic-csi"&gt;DemocraticCSI&lt;/a&gt;, ça me permet de créer un CSIDriver spécifiquement fait pour interagir avec l'API de TrueNAS, afin de provisionner des PV stockés sur un Dataset ZFS via le protocole NFS.&lt;br /&gt;
Il nous faut donc 2 volumes:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Le premier sera monté sur le &lt;code&gt;app/data&lt;/code&gt; du front de Mealie, il stockera les Metadata du front, et fera 1Gi.&lt;/li&gt;
&lt;li&gt;Le deuxième sera le volume de la base de donnée PostgreSQL, ce dernier ne sera pas défini dans son propre manifest yaml mais directement dans le manifest du StatefulSet.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Nous en avons terminé avec les objets qui constituent l'application en elle-même, pour finir il nous faut un objet de type &lt;a href="https://kubernetes.io/fr/docs/concepts/services-networking/ingress/"&gt;Ingress&lt;/a&gt;.&lt;br /&gt;
Un Ingress c'est un objet créé par un &lt;a href="https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/"&gt;IngressController&lt;/a&gt;, vous connaissez surement quelques noms connus d'IngressController: Nginx, Traefik, HAProxy, par exemple, pour ma part, j'utilise Traefik car je m'en servais déjà sur Docker.&lt;br /&gt;
Un Ingress est un Reverse Proxy et LoadBalancer de couche 7, il agit comme un point d'entrée pour des routes HTTP et HTTPS et redirige les requêtes selon les règles qu'il contient, par exemple, il peut rediriger une requête vers un objet de type service précis, lui même redirigeant à un pod , dépendant de l'URL (machin.fr/app qui redirige au service app).&lt;br /&gt;
Il peut également gérer plusieurs noms de domaine, utiliser des headers de sécurité et implémenter un certificat SSL/TLS.&lt;br /&gt;
Normalement, il faudrait créer un objet de type certificat contenu dans un Secret Kubernetes et appeler ce secret dans le manifest de l'Ingress, mais comme j'utilise Cert-Manager qui est relié à mon domaine dans Cloudflare, je n'ai qu'à rajouter une annotation dans l'objet pour faire une requête de Certificat Let's Encrypt.&lt;br /&gt;
Je ne rentrerais pas en détail dans le sujet de Cert-Manager, cependant, &lt;a href="https://cert-manager.io/"&gt;voici la documentation officielle du projet&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;Construction&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;└── base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── kustomization.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-configmap.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-db-service.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-deployment.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-pvc.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-secret.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-statefulset.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;├── mealie-ingressroute.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;└── mealie-web-service.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bon, appliquer tous ces fichiers yaml à la main, ça serait VRAIMENT pénible.&lt;br /&gt;
Comment faire pour tout faire d'un coup ?&lt;br /&gt;
Avec la commande CLI builtin et les manifests Kustomize.&lt;/p&gt;
&lt;p&gt;Voici un exemple d'un manifest kustomize:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;apiVersion&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;kustomize.config.k8s.io/v1beta1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Kustomization&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;resources&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-deployment.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-statefulset.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-secret.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-web-service.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-db-service.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-ingressroute.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-configmap.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;mealie-pvc.yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour appliquer ce fichier il faut lancer la commande &lt;code&gt;kubectl apply -k ./base&lt;/code&gt;, le &lt;code&gt;-k&lt;/code&gt; spécifie qu'on vise un manifest kustomize.&lt;br /&gt;
Kustomize va donc appeler chaque manifest yaml de la liste définie dans &lt;code&gt;resources&lt;/code&gt; et les appliquer un à un dans Kubernetes.&lt;br /&gt;
On peut faire des choses très utiles avec Kustomize, mais ce n'est pas le but de l'article. Néamoins, &lt;a href="https://dev.to/mxglt/quest-ce-kustomize--dai"&gt;Voici un article en parlant.&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Et voilà ! À table !&lt;/p&gt;
&lt;p&gt;&lt;img data-recalc-dims="1" height="216" width="300" decoding="async" src="Mealie.png" alt="" /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Au final si jamais vous vous posez la question, est-ce que vous devez utiliser Kubernetes ou Docker dans votre homelab, sachez une chose.&lt;/p&gt;
&lt;p&gt;Utiliser Docker est vraiment vraiment plus simple dans un petit environnement, quel intérêt d'utiliser Kubernetes ?&lt;br /&gt;
Apprendre et évoluer ! Bien sûr c'est suffisant d'utiliser Docker, mais Kubernetes apporte son lot d'avantage, de satisfaction, (de soirée perdues).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Watch Tower : Auto update docker images</title><link>https://beta.slash-root.fr/docker-update-auto-images/</link><pubDate>Tue, 11 Apr 2023 08:04:46 +0200</pubDate><guid>https://beta.slash-root.fr/docker-update-auto-images/</guid><description>&lt;img src="https://beta.slash-root.fr/docker-update-auto-images/cover.png" alt="Featured image of post Watch Tower : Auto update docker images" /&gt;&lt;h2 id="présentation"&gt;&lt;a href="#pr%c3%a9sentation" class="header-anchor"&gt;&lt;/a&gt;Présentation
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Watch Tower&lt;/strong&gt; permet de mettre à jour les images docker utilisées de façon automatique. Il va permettre de télécharger la nouvelle image, supprimer proprement le conteneur l'utilisant et le relancer avec les mêmes options. Par défaut, cela utilise le Docker Hub, mais il est possible de paramétrer un registry privé en spécifiant des credentials.&lt;/p&gt;
&lt;p&gt;La documentation complète peut être accessible ici : &lt;a href="https://containrrr.dev/watchtower/"&gt;https://containrrr.dev/watchtower/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="installation"&gt;&lt;a href="#installation" class="header-anchor"&gt;&lt;/a&gt;Installation
&lt;/h2&gt;&lt;p&gt;L'installation est très simple car &lt;strong&gt;Watch Tower&lt;/strong&gt; va tourner lui-même en conteneur.&lt;/p&gt;
&lt;p&gt;Je vais utiliser un fichier &lt;code&gt;docker-compose.yml&lt;/code&gt; pour exécuter l'application :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;version&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;3.8&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;watchtower&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;containrrr/watchtower:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;watchtower&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;restart&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;unless-stopped&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;command&lt;/span&gt;: --&lt;span style="color:#ae81ff"&gt;schedule &amp;#34;0 0 4 * * *&amp;#34; --cleanup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;docker.sock&lt;/strong&gt; : Indispensable pour avoir accès au socket docker de l'hôte dans le conteneur afin de surveiller tous les autres conteneurs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;schedule&lt;/strong&gt; : Permet de préciser quand vérifier les mises à jour sous un format à 6 colonnes (contrairement à crontab). La 1ère colonne correspond aux secondes. Ici, 4h tous les jours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cleanup&lt;/strong&gt; : Permet de supprimer les anciennes images docker.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par défaut toutes les images de tous les conteneurs sont surveillées. Il est possible d'affiner ce comportement.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;D'autres options sont disponibles (Se référer à la documentation précisée en introduction).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="exécution"&gt;&lt;a href="#ex%c3%a9cution" class="header-anchor"&gt;&lt;/a&gt;Exécution
&lt;/h2&gt;&lt;p&gt;Lancer simplement le &lt;code&gt;docker-compose.yml&lt;/code&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker-compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Docker-Compose : Portainer Agent</title><link>https://beta.slash-root.fr/docker-compose-portainer-agent/</link><pubDate>Mon, 15 Aug 2022 16:55:25 +0200</pubDate><guid>https://beta.slash-root.fr/docker-compose-portainer-agent/</guid><description>&lt;img src="https://beta.slash-root.fr/docker-compose-portainer-agent/cover.png" alt="Featured image of post Docker-Compose : Portainer Agent" /&gt;&lt;h2 id="docker-composeyml"&gt;&lt;a href="#docker-composeyml" class="header-anchor"&gt;&lt;/a&gt;docker-compose.yml
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;version&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;agent&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;portainer/agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;portainer_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;restart&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;unless-stopped&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;security_opt&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#66d9ef"&gt;no&lt;/span&gt;-&lt;span style="color:#ae81ff"&gt;new-privileges:true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/etc/localtime:/etc/localtime:ro&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/var/run/docker.sock:/var/run/docker.sock:ro&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/var/lib/docker/volumes:/var/lib/docker/volumes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;9001&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;9001&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item></channel></rss>