<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Astuces on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/astuces/</link><description>Recent content in Astuces on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Mon, 20 Jan 2020 07:30:00 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/astuces/index.xml" rel="self" type="application/rss+xml"/><item><title>kubectl tips and tricks n°2</title><link>https://blog.zwindler.fr/2020/01/20/kubectl-tips-and-tricks-n2/</link><pubDate>Mon, 20 Jan 2020 07:30:00 +0000</pubDate><guid>https://blog.zwindler.fr/2020/01/20/kubectl-tips-and-tricks-n2/</guid><description>&lt;img src="https://blog.zwindler.fr/2019/10/kubectl2.webp" alt="Featured image of post kubectl tips and tricks n°2" /&gt;&lt;h2 id="kubectl"&gt;kubectl
&lt;/h2&gt;&lt;p&gt;Comme vous pouvez le voir, il s’agit du 2ème article d’une série sur la productivité quand on est dans un environnement Kubernetes. Et qui dit productivité dit forcément ligne de commande, donc kubectl :trollface:!&lt;/p&gt;
&lt;p&gt;Le premier article, si vous l’avez loupé, est toujours disponible ici : &lt;a class="link" href="https://blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/" &gt;kubectl tips and tricks n°1&lt;/a&gt;. J’avais parlé du flag &amp;ldquo;wait&amp;rdquo;, de comment relancer un Job ou un CronJob et de comment utiliser les &lt;em&gt;selectors&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Et j’ai aussi &lt;a class="link" href="https://blog.zwindler.fr/2018/08/28/utiliser-kubectx-kubens-pour-changer-facilement-de-context-et-de-namespace-dans-kubernetes/" &gt;écris un article sur kubectx et kubens qui pourrait vous plaire&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Normalement, les astuces que je vais vous montrer ici ne sont pas dans la plupart des tutos que j’ai pu trouver sur le net. Cet article se concentre tout particulièrement sur les Secrets de Kubernetes.&lt;/p&gt;
&lt;p&gt;C’est parti pour du fun avec kubectl !&lt;/p&gt;
&lt;h2 id="encoderdécoder-facilement-en-base64-les-secrets"&gt;Encoder/décoder facilement en base64 les Secrets
&lt;/h2&gt;&lt;p&gt;Quelque chose qu’on a TOUT le temps à faire quand on manipule les objets de type Secrets dans Kubernetes, c’est d’afficher en clair les &amp;ldquo;secrets&amp;rdquo; contenus dans notre Secret (ou de les encoder).&lt;/p&gt;
&lt;p&gt;Car, pour ceux qui ne le savent pas, les Secrets dans Kubernetes ne sont malheureusement pas très secrets, puisqu’il s’agit ni plus ni moins que des strings encodées en base64 (ce qui est donc TOUT sauf secure). A vrai dire, je me demande même pourquoi s’être embêter à les encoder tout court. La seule sécurité qu’on ajoute par rapport aux ConfigMaps, c’est simplement que la string n’est pas lisible par un humain qui passerait sa tête par dessus votre épaule.&lt;/p&gt;
&lt;p&gt;Enfin bref, vous allez surement devoir encoder ou décoder des strings en base64 et c’est parfois un peu pénible. La méthode communément admise est simplement d’utiliser les binaires linux echo et base64.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo &amp;#34;ma string&amp;#34; | base64
bWEgc3RyaW5nCg==
echo bWEgc3RyaW5nCg== | base64 -d
ma string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;C’est relou à taper, mais c’est relativement trivial.&lt;/p&gt;
&lt;h2 id="its-a-trap-"&gt;It’s a trap !
&lt;/h2&gt;&lt;p&gt;Sauf qu’il y a des pièges !&lt;/p&gt;
&lt;p&gt;Le premier vous l’aurez à l’encodage. Dans mon premier exemple, la string est très courte. Et parfois, la taille compte.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo &amp;#34;ma string très longue string pour montrer que ça va pas le faire&amp;#34; | base64
bWEgc3RyaW5nIHRyw6hzIGxvbmd1ZSBzdHJpbmcgcG91ciBtb250cmVyIHF1ZSDDp2EgdmEgcGFz
IGxlIGZhaXJlCg==
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ici, on se retrouve avec un saut de ligne dans notre string en sortie. Mais, si vous copiez collez ça dans votre YAML Kubernetes, vous allez vous prendre une bonne grosse erreur de syntaxe.&lt;/p&gt;
&lt;p&gt;Le YAML ne sera valide que si vous mettez la string complète, sur une seule ligne.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo &amp;#34;ma string très longue string pour montrer que ça va pas le faire&amp;#34; | base64 -w0
bWEgc3RyaW5nIHRyw6hzIGxvbmd1ZSBzdHJpbmcgcG91ciBtb250cmVyIHF1ZSDDp2EgdmEgcGFzIGxlIGZhaXJlCg==
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="et-cest-pas-fini-"&gt;Et c’est pas fini !
&lt;/h2&gt;&lt;p&gt;Le 2 ème piège est encore un souci de saut de ligne, mais dans la string en base64 cette fois.&lt;/p&gt;
&lt;p&gt;En fait, c’est hyper traitre car vous n’allez pas le voir à l’écran de prime abord, mais il faut savoir que echo rajoute un saut de ligne à la fin de votre string. Le retour que vous avez eu en base64 contient donc un saut de ligne, qui sera quasiment systèmatiquement non souhaité lorsqu’on gère des Secrets.&lt;/p&gt;
&lt;p&gt;La bonne commande n’est donc pas echo mais echo -n !&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#Pas bien
echo &amp;#34;ma string&amp;#34; | base64
bWEgc3RyaW5nCg==
#Bien
echo -n &amp;#34;ma string&amp;#34; | base64 -w0
bWEgc3RyaW5n
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ok-ça-commence-à-devenir-franchement-pénible"&gt;Ok ça commence à devenir franchement pénible&amp;hellip;
&lt;/h2&gt;&lt;p&gt;Pour décoder heureusement, c’est plus simple. La commande donnée au début suffit, même s’il sera plus safe de rajouter le &amp;ldquo;-n&amp;rdquo; au echo :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo -n bWEgc3RyaW5n | base64 -d
ma string
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="gagner-quelques-caractères"&gt;Gagner quelques caractères
&lt;/h2&gt;&lt;p&gt;Comme je suis fainéant, j’ai cherché une astuce pour gagner quelques caractères à taper en moins. Il existe une solution, mais qui ne marche malheureusement que pour decode, puisque dans le cas de l’encodage on risquera d’ajouter un saut de ligne non souhaité :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo bWEgc3RyaW5n | base64 -d
base64 -d &amp;lt;&amp;lt;&amp;lt; bWEgc3RyaW5n
ma string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On vient de s’économiser 3 caractères (waaaah) mais surtout un &amp;ldquo;|&amp;rdquo;, bien plus pénible à faire sur un clavier azerty standard que 3 &amp;ldquo;&amp;lt;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Je vous l’accorde, c’est pas foufou.&lt;/p&gt;
&lt;h2 id="un-peu-plus-simple"&gt;Un peu plus simple
&lt;/h2&gt;&lt;p&gt;Heureusement, mon collègue Julien (aka JUL, car il est fan de JUL, bien entendu) nous a écris un petit script pour nous faciliter la vie, donc je vous le partage :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;dgermain:~$ cat &amp;gt; b64 &amp;lt;&amp;lt;EOF
&amp;gt; #!/bin/bash
&amp;gt; echo -e &amp;#34;Base64 encoding.. \n&amp;#34;
&amp;gt; for arg in &amp;#34;\$@&amp;#34;; do
&amp;gt; echo &amp;#34;\$arg :&amp;#34;
&amp;gt; echo -n &amp;#34;\$arg&amp;#34; | base64
&amp;gt; echo
&amp;gt; done
&amp;gt; EOF
dgermain:~$ cat &amp;gt; b64d &amp;lt;&amp;lt;EOF
&amp;gt; #!/bin/bash
&amp;gt; echo -e &amp;#34;Base64 decoding.. \n&amp;#34;
&amp;gt; for arg in &amp;#34;\$@&amp;#34;; do
&amp;gt; echo &amp;#34;\$arg :&amp;#34;
&amp;gt; echo -n &amp;#34;\$arg&amp;#34; | base64 -d
&amp;gt; echo
&amp;gt; done
&amp;gt; EOF
dgermain:~$ sudo cp b64* /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Vous pouvez maintenant invoquer directement b64 suivi d’un certain nombre de strings pour avoir leur valeur encodée, ou b64d suivi d’un certain nombre de string pour les décoder.&lt;/p&gt;
&lt;h2 id="dernière-astuce-et-après-jarrête"&gt;Dernière astuce et après j’arrête
&lt;/h2&gt;&lt;p&gt;Si jamais vous voulez à l’écran toutes les strings encodées en base64 dans un Secret Kubernetes en une seule étape, j’ai également trouvé ce &lt;a class="link" href="https://stackoverflow.com/questions/56909180/decoding-kubernetes-secret" target="_blank" rel="noopener"
&gt;&lt;em&gt;oneliner&lt;/em&gt; pas piqué des hannetons sur Stackoverflow&lt;/a&gt; qui tire parti de la possibilité de faire des gotemplates directement dans kubectl :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get secret name-of-secret -o go-template=&amp;#39;
{{range $k,$v := .data}}{{printf &amp;#34;%s: &amp;#34; $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{&amp;#34;\n&amp;#34;}}{{end}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Il faudra probablement que je fasse un article entier sur le go-templating avec kubectl car c’est juste ouf ce qu’on peut faire avec ;-)&lt;/p&gt;</description></item><item><title>kubectl tips and tricks n°1</title><link>https://blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/</link><pubDate>Wed, 30 Oct 2019 07:00:44 +0000</pubDate><guid>https://blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/</guid><description>&lt;img src="https://blog.zwindler.fr/2019/10/kubectl2.webp" alt="Featured image of post kubectl tips and tricks n°1" /&gt;&lt;h2 id="kubectl"&gt;kubectl
&lt;/h2&gt;&lt;p&gt;Ça fait un moment que je garde sous le coudes quelques petites tips pour améliorer votre productivité via la CLI de Kubernetes kubectl.&lt;/p&gt;
&lt;p&gt;Rassurez vous, je ne vais pas faire un énième article sur l’autocomplétion ou autre info triviale comme &amp;ldquo;vous savez que vous pouvez stocker plusieurs contexts dans votre kubectl ?&amp;rdquo; #shocking. (Si ce dernier point vous intéresse, &lt;a class="link" href="https://blog.zwindler.fr/2018/08/28/utiliser-kubectx-kubens-pour-changer-facilement-de-context-et-de-namespace-dans-kubernetes/" &gt;j’avais fais un article sur kubectx et kubens qui va surement vous plaire&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Normalement, les astuces que je vais vous montrer ici ne sont pas dans la plupart des tutos que j’ai pu trouver sur le net.&lt;/p&gt;
&lt;p&gt;C’est parti pour du fun avec kubectl !&lt;/p&gt;
&lt;h2 id="pour-les-accrocs-à-la-flèche-du-haut"&gt;Pour les accrocs à la flèche du haut
&lt;/h2&gt;&lt;p&gt;Si, comme moi, vous faites partie de ces gens impatients qui ne peuvent pas prendre un café le temps qu’une opération se termine toute seule et que vous appuyez frénétiquement une la combinaison &amp;ldquo;flèche du haut + entrée&amp;rdquo; pour rappeler la dernière commande &amp;ldquo;kubectl get monobjetquejattendavecimpatience&amp;rdquo;, ce paragraphe est pour vous.&lt;/p&gt;
&lt;p&gt;Lors d’une commande de type &amp;ldquo;get&amp;rdquo; avec &lt;em&gt;kubectl&lt;/em&gt;, il existe un flag &amp;ldquo;-w&amp;rdquo; qui fait&amp;hellip; oui vous l’avez deviné&amp;hellip; un genre de watch sur le (ou les) objet(s) que vous attendez.&lt;/p&gt;
&lt;p&gt;Par exemple, dans le cas où vous souhaiteriez créer un objet &lt;em&gt;Service&lt;/em&gt; de type &lt;em&gt;LoadBalancer&lt;/em&gt; et que vous avez hâte que votre cloud provider vous assigne une IP publique, utilisez la commande suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=cephk8s get svc traefik-ingress-controller --namespace kube-system -w
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik-ingress-controller LoadBalancer 10.0.21.75 &amp;lt;pending&amp;gt; 80:32347/TCP,443:30388/TCP 45s
traefik-ingress-controller LoadBalancer 10.0.21.75 40.89.187.183 80:32347/TCP,443:30388/TCP 56s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans un premier temps, seul la première ligne &lt;em&gt;LoadBalancer&lt;/em&gt; s’affichera (tant que l’état restera à &amp;ldquo;Pending&amp;rdquo;), puis dès qu’il y aura une modification, la dernière ligne, avec l’IP publique, s’affichera.&lt;/p&gt;
&lt;p&gt;C’est également pratique si vous avez des &lt;em&gt;Pods&lt;/em&gt; qui mettent du temps à s’initialiser dans un &lt;em&gt;Déploiement&lt;/em&gt; complexe.&lt;/p&gt;
&lt;h2 id="relancer-un-job"&gt;Relancer un job
&lt;/h2&gt;&lt;p&gt;Kubernetes, en bon orchestrateur qu’il est, est capable de lancer des tâches planifiées. C’est super pratique lorsque vous avez des tâches bien précises à réaliser mais qu’il n’y a pas de raison de laisser un container tourner H24 pour ça.&lt;/p&gt;
&lt;p&gt;On a donc la notion d’objet Kubernetes &lt;em&gt;Job&lt;/em&gt; et de &lt;em&gt;Cronjob&lt;/em&gt;. Sans rentrer dans les détails, le &lt;em&gt;Job&lt;/em&gt;, c’est celui qui exécute la tâche (il lance un Pod qui contient un ou plusieurs containers). Le &lt;em&gt;Cronjob&lt;/em&gt;, c’est une surcouche qui lance périodiquement le &lt;em&gt;Job&lt;/em&gt;. Rien de bien sorcier.&lt;/p&gt;
&lt;p&gt;Malheureusement pour nous, il arrive que nos Jobs échouent. Il n’y avait pas assez de ressources, ou alors on est tombé sur un bug, ou alors c’est &amp;ldquo;la faute à pas de chance&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Qu’à cela ne tienne, il faut que votre Job tourne aujourd’hui, vous voulez donc le relancer. Pas de chance pour vous, &amp;ldquo;by design&amp;rdquo;, les &lt;em&gt;Jobs&lt;/em&gt; ne peuvent pas être relancés dans Kubernetes.&lt;/p&gt;
&lt;p&gt;Jusqu’à récemment, il n’y avait pas de solution propre pour relancer un Job avec kubectl. Il fallait donc passer par un exposer du JSON du Job pour en recréer un nouveau identique en tout point. &amp;ldquo;Crude but effective&amp;rdquo; comme disent nos amis anglosaxons.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=moncontext --namespace=monnamespace get job monjob -o json | jq &amp;#39;del(.spec.selector)&amp;#39; | jq &amp;#39;del(.spec.template.metadata.labels)&amp;#39; | kubectl --context=moncontext --namespace=monnamespace replace --force -f -
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si vous voulez plus de détails sur ce que oneliner fait vraiment : la première partie dump en JSON la configuration du job, la partie du milieu retire les données spécifiques au Job qui a échoué (autogénéré à la création du Job) et la dernière partie réinjecte le job dans Kubernetes, ce qui a pour effet de le relancer.&lt;/p&gt;
&lt;p&gt;Pas mal hein ?&lt;/p&gt;
&lt;p&gt;Mais&amp;hellip; si vous avez une version plus récente, vous avez de la chance, cette option est maintenant disponible par défaut dans &lt;em&gt;kubectl&lt;/em&gt;, vous permettant de créer de manière unitaire un &lt;em&gt;Job&lt;/em&gt; à partir d’un template contenu dans un &lt;em&gt;Cronjob&lt;/em&gt;, ce qui revient au même.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=moncontext --namespace=monnamespace create job --from=cronjob/lecronjobmaitre unnomuniquepourlejobrelancé
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="les-selecteurs-dans-vos-kubectl"&gt;Les selecteurs dans vos kubectl
&lt;/h2&gt;&lt;p&gt;Last but not least, il est possible de réaliser des opérations sur plusieurs objets d’un même type en même temps.&lt;/p&gt;
&lt;p&gt;La manière la plus simple de le faire est simplement d’ajouter les noms de tous les objets à la fin de votre commande. Par exemple, la commande suivante va supprimer les &lt;em&gt;Pods&lt;/em&gt; pod1, pod2 et pod1000 :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=moncontexte --namespace==monnamespace delete pods pod1 pod2 pod1000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Cependant, on va rarement supprimer des pods (ou autre objet) au hasard. Généralement, on va vouloir supprimer tous les pods d’un même déploiement, ou alors supprimer tous les objets de la même applications, ou encore scaler tous les déploiements d’un même client.&lt;/p&gt;
&lt;p&gt;Dans tous les cas, si vous avez bien fait votre travail, tous ces objets Kubernetes auront tous les labels cohérents les uns avec les autres. En partant du principe que les pods de l’exemple précédents ont tous le label app=blopiblop, je peux donc exécuter la commande suivante pour gagner du temps :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=moncontexte --namespace==monnamespace delete pods --selector=app=blopiblop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attention à ne pas vous tromper dans les labels, c’est très puissant ;-)&lt;/p&gt;</description></item></channel></rss>