<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Productivité on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/productivit%C3%A9/</link><description>Recent content in Productivité on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Mon, 06 Sep 2021 06:55:00 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/productivit%C3%A9/index.xml" rel="self" type="application/rss+xml"/><item><title>kubectl tips and tricks n°4</title><link>https://blog.zwindler.fr/2021/09/06/kubectl-tips-and-tricks-n4/</link><pubDate>Mon, 06 Sep 2021 06:55:00 +0000</pubDate><guid>https://blog.zwindler.fr/2021/09/06/kubectl-tips-and-tricks-n4/</guid><description>&lt;img src="https://blog.zwindler.fr/2019/10/kubectl2.webp" alt="Featured image of post kubectl tips and tricks n°4" /&gt;&lt;h2 id="encore-des-tips-pour-kubectl-"&gt;Encore des tips pour kubectl !!
&lt;/h2&gt;&lt;p&gt;J’en suis donc bien au numéro 4 pour ces &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=kubectl" &gt;tips and tricks sur kubectl (sans compter d’autres articles plus généralistes)&lt;/a&gt; et il y a encore beaucoup à dire !!&lt;/p&gt;
&lt;h2 id="jarrive-plus-à-me-loguer-sur-mon-cluster-kubernetes-x1f62d"&gt;J’arrive plus à me loguer sur mon cluster Kubernetes 😭
&lt;/h2&gt;&lt;p&gt;Dans plusieurs contextes, j’ai eu à aider des collègues qui n’arrivaient plus à utiliser &lt;strong&gt;kubectl&lt;/strong&gt; (après expiration d’un jeton, changements de confs dans le cluster, etc).&lt;/p&gt;
&lt;p&gt;Un moyen rapide pour « régler » une partie des problèmes dans ce genre de cas peut être simplement de supprimer le contenu des caches de kubectl :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rm -r ~/.kube/cache
rm -r ~/.kube/http-cache
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="non-mais-ya-quoi-dans-mon-cluster-"&gt;Non mais ya quoi dans mon cluster ?
&lt;/h2&gt;&lt;p&gt;Vous le savez, Kubernetes c’est plein d’API misent bout à bout (portée par l’API server et persistée par etcd) et d’autres composants qui se connectent dessus pour faire des choses utiles. Ça implique qu’il y ait un certain nombre d’objets logiques à connaître pour interagir avec l’API server et déployer vos applications. Cependant, difficile pour le néophyte de les connaître tous.&lt;/p&gt;
&lt;p&gt;Bien sûr, on peut toujours parcourir &lt;a class="link" href="https://kubernetes.io/docs/reference/using-api/api-concepts/" target="_blank" rel="noopener"
&gt;l’API à coup de cURL&lt;/a&gt; mais vous avouerez qu’il y a plus user-friendly comme méthode ;). Et même pour l’admin chevronné, l’ajout de &lt;a class="link" href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/" target="_blank" rel="noopener"
&gt;CRDs (Custom Resource Definition)&lt;/a&gt;, difficile de savoir, sur des clusters un peu touffus, quel objet est présent et à quoi il sert.&lt;/p&gt;
&lt;p&gt;Pour ça, vous disposez de deux aides avec &lt;strong&gt;kubectl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;kubectl api-resources&lt;/em&gt;&lt;/strong&gt; va vous permettre de lister la totalité des objets logiques de l’API disponibles (CRDs comprises) sur votre cluster, ainsi qu’une autre information très utile, s’ils sont « namespacés » ou non.&lt;/p&gt;
&lt;p&gt;Dernier intérêt de cette commande, elle permet également de connaitre les abréviations (shortnames) autorisés, pratique pour sous économiser quelques caractères ;-)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
namespaces ns false Namespace
nodes no false Node
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Un autre outil intéressant pour savoir à quoi sert tel ou tel objet/API est &lt;em&gt;&lt;strong&gt;kubectl explain&lt;/strong&gt;&lt;/em&gt;, qui va vous afficher la documentation en ligne :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl explain RoleBinding
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1
DESCRIPTION:
RoleBinding references a role, but does not contain it. It can reference a
Role in the same namespace or a ClusterRole in the global namespace. It
adds who information via Subjects and namespace information by which
namespace it exists in. RoleBindings in a given namespace only have effect
in that namespace.
FIELDS:
apiVersion &amp;lt;string&amp;gt;
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Malheureusement, j’ai remarqué que plusieurs éditeurs mettant à disposition des CRDs ne mettent pas de doc accessible avec « explain ». C’est vraiment super dommage :/&lt;/p&gt;
&lt;h2 id="afficher-des-labels"&gt;Afficher des labels
&lt;/h2&gt;&lt;p&gt;Tous les objets Kubernetes que vous créés peuvent être agrémentés de labels et d’annotations. Au delà de l’aspect informatif (ce &lt;strong&gt;Pod&lt;/strong&gt; appartient à tel équipe, ce &lt;strong&gt;Node&lt;/strong&gt; à telle capacité en RAM), c’est aussi très pratique pour filtrer les informations renvoyées par les commandes &lt;strong&gt;kubectl get&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Dans le tout premier &lt;a class="link" href="https://blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/" &gt;kubectl tips and tricks&lt;/a&gt;, j’avais parlé de l’option &lt;strong&gt;&amp;ndash;selector&lt;/strong&gt;, qui permet de filtrer l’action d’une commande kubectl (get, delete, &amp;hellip;) à un couple label+valeur&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2021/08/image.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/" &gt;blog.zwindler.fr/2019/10/30/kubectl-tips-tricks-1/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par défaut, les informations renvoyées par le kubectl get sont assez concises et parfois on manque un peu d’information.&lt;/p&gt;
&lt;p&gt;Dans ce genre de cas, la première chose à tester est simplement d’ajouter un « -o wide » qui permet d’ajouter quelques colonnes (qui dépendent du type d’objet requêté) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
scw-k8s-zealous-chaum-default-4b71eda80e934790 Ready &amp;lt;none&amp;gt; 24m v1.21.3 10.70.116.23 51.158.79.36 Ubuntu 20.04.1 LTS c200a86960 5.4.0-80-generic containerd://1.5.4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Cependant, dans le cas ça n’est toujours pas suffisant et qu’on ne veut pas filtrer mais bien obtenir rapidement la valeur d’un label bien particulier sur un ensemble d’objets Kubernetes, il existe une option « &amp;ndash;label-columns » qui permet d’ajouter des colonnes supplémentaires en fonction d’un ou plusieurs labels donnés.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get nodes --label-columns=kubernetes.io/os
NAME STATUS ROLES AGE VERSION OS
scw-k8s-zealous-chaum-default-4b71eda80e934790 Ready &amp;lt;none&amp;gt; 19m v1.21.3 linux
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Les labels sont donc d’autant plus utiles qu’ils sont faciles à afficher !&lt;/p&gt;
&lt;p&gt;Note : les plus chevronnés d’entre vous savent certainement peut aller encore plus loin dans les colonnes ou les informations qu’on peut afficher avec kubectl (notamment via le « -o »). Mais je garde ça pour un prochain épisode&amp;hellip; Donc en attendant, have fun ;-)&lt;/p&gt;</description></item><item><title>Supprimer un namespace bloqué à Terminating</title><link>https://blog.zwindler.fr/2020/03/23/supprimer-un-namespace-bloque-a-terminating/</link><pubDate>Mon, 23 Mar 2020 07:15:00 +0000</pubDate><guid>https://blog.zwindler.fr/2020/03/23/supprimer-un-namespace-bloque-a-terminating/</guid><description>&lt;img src="https://blog.zwindler.fr/2020/01/terminated.webp" alt="Featured image of post Supprimer un namespace bloqué à Terminating" /&gt;&lt;h2 id="forcer-la-suppression-dun-namespace-bloqué-à-terminating-dans-kubernetes"&gt;Forcer la suppression d’un namespace bloqué à &amp;ldquo;Terminating&amp;rdquo; dans Kubernetes
&lt;/h2&gt;&lt;p&gt;Il y a quelques mois, j’ai eu des soucis pour supprimer un namespace lorsque j’ai voulu démonter mon &lt;a class="link" href="https://blog.zwindler.fr/2019/09/10/du-ceph-dans-mon-kubernetes/" &gt;cluster Ceph (monté avec Rook)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On aurait pu croire que ça m’a énervé (bon ok, si un peu quand même) mais ça m’a permis de mettre la main sur plusieurs commandes sympa avec kubectl donc tout n’est pas perdu ;-).&lt;/p&gt;
&lt;p&gt;Voyez ce récit comme une checklist des choses à vérifier si jamais vous avez du mal à supprimer des objets dans Kubernetes !&lt;/p&gt;
&lt;p&gt;Note: dans la même veine, n’hésitez pas à aller voir les articles que j’ai écris sur &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=kubectl" &gt;kubectl, notamment les tips and tricks !&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="la-base"&gt;La base
&lt;/h2&gt;&lt;p&gt;Pensant avoir correctement supprimé les objets Ceph dans mon cluster, j’ai donc terminé le nettoyage par une suppression toute bête du namespace :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox delete ns rook-ceph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Sauf que, patatra, en essayant de vérifier qu’il était bien supprimé :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox get ns rook-ceph
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME STATUS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rook-ceph Terminating 88d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le namespace est toujours présent, et reste bloqué à l’état &amp;ldquo;Terminating&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Qu’à cela ne tienne, je tente de le re-supprimer. Ça ne marche pas :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox delete ns rook-ceph
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;Conflict&lt;span class="o"&gt;)&lt;/span&gt;: Operation cannot be fulfilled on namespaces &lt;span class="s2"&gt;&amp;#34;rook-ceph&amp;#34;&lt;/span&gt;: The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="forcer-la-suppression"&gt;Forcer la suppression
&lt;/h2&gt;&lt;p&gt;Une rapide recherche sur le net me conseille d’ajouter les flags &lt;code&gt;--force&lt;/code&gt;, à obligatoirement associer avec le flag &lt;code&gt;--grace-period=0&lt;/code&gt; (si vous ne le mettez pas, il vous dira de le mettre de toute façon&amp;hellip;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox delete ns rook-ceph --force --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;warning: Immediate deletion does not &lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; confirmation that the running resource has been terminated. The resource may &lt;span class="k"&gt;continue&lt;/span&gt; to run on the cluster indefinitely.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;Conflict&lt;span class="o"&gt;)&lt;/span&gt;: Operation cannot be fulfilled on namespaces &lt;span class="s2"&gt;&amp;#34;rook-ceph&amp;#34;&lt;/span&gt;: The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Flute !&lt;/p&gt;
&lt;h2 id="vérifier-quil-ne-reste-pas-des-objets-kubernetes-dans-le-namespace-ou-associés"&gt;Vérifier qu’il ne reste pas des objets Kubernetes, dans le namespace ou associés
&lt;/h2&gt;&lt;p&gt;Bon, généralement quand j’arrive pas à supprimer un namespace, c’est qu’il reste un PVC qui traine, lui même attaché à un PV. Mais là non plus, rien :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl --namespace&lt;span class="o"&gt;=&lt;/span&gt;rook-ceph get pvc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;No resources found in rook-ceph namespace.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="vérifier-les-crd-aussi-"&gt;Vérifier les CRD aussi !
&lt;/h2&gt;&lt;p&gt;Un truc à vérifier aussi dans le cas de rook, c’est qu’il ne reste pas de CRD (CustomRessourceDefinition) que vous n’avez pas l’habitude de manipuler, qui seraient encore présentes et qui bloqueraient l’opération :&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;dgermain$ kubectl delete storageclass rook-ceph-block
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;NotFound&lt;span class="o"&gt;)&lt;/span&gt;: storageclasses.storage.k8s.io &lt;span class="s2"&gt;&amp;#34;rook-ceph-block&amp;#34;&lt;/span&gt; not found
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain$ kubectl delete storageclass rook-cephfs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;NotFound&lt;span class="o"&gt;)&lt;/span&gt;: storageclasses.storage.k8s.io &lt;span class="s2"&gt;&amp;#34;rook-cephfs&amp;#34;&lt;/span&gt; not found
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain$ kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox get crd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;volumes.rook.io 2019-08-19T09:46:08Z
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain$ kubectl --context&lt;span class="o"&gt;=&lt;/span&gt;sandbox delete crd volumes.rook.io
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="utiliser-des-scripts-pour-débloquer-les-objets-en-terminating"&gt;Utiliser des scripts pour débloquer les objets en &amp;ldquo;Terminating&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Là ça commence à devenir pénible. Comme je ne suis évidemment pas le premier à avoir le problème, des gens ont écris des scripts pour faciliter la suppression d’objets bloqués au stade Terminating. Ces scripts prennent en charge la plupart des cas courants. Attention cependant à ce que vous faites avec (soyez sûrs de vous) !&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;dgermain:~/sources/knsk$ git clone https://github.com/thyarles/knsk/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain:~/sources/knsk$ kubectl config use-context sandbox
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Switched to context &lt;span class="s2"&gt;&amp;#34;sandbox&amp;#34;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain:~/sources/knsk$ chmod +x knsk.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dgermain:~/sources/knsk$ ./knsk.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Deleting rook-ceph... &lt;span class="k"&gt;done&lt;/span&gt;!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lister-tous-les-objets-du-cluster-qui-sappellent-rook-ceph"&gt;Lister tous les Objets du cluster qui s’appellent rook-ceph
&lt;/h2&gt;&lt;p&gt;Last but not least. La solution j’ai fini par la trouver en utilisant la commande suivante, qui permet de lister TOUS les types objets existants dans votre cluster :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl api-resources --verbs=list --namespaced -o name
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, j’ai rajouté un petit xargs pour rechercher, dans tout le cluster, tous les objets s’appelant rook-ceph parmis tous les types d’objets qui existent. Et là surprise :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n rook-ceph
No resources found in rook-ceph namespace.
No resources found in rook-ceph namespace.
No resources found in rook-ceph namespace.
[...]
No resources found in rook-ceph namespace.
NAME DATADIRHOSTPATH MONCOUNT AGE STATE HEALTH
rook-ceph /var/lib/rook 1 88d Created HEALTH_OK
No resources found in rook-ceph namespace.
[...]
No resources found in rook-ceph namespace.
Error from server (NotAcceptable): the server was unable to respond with a content type that the client supports (get pods.metrics.k8s.io)
No resources found in rook-ceph namespace.
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OUPS ! Il restait un CRD &amp;ldquo;cephcluster&amp;rdquo; que j’avais oublié de supprimer ! Sauf que cet objet n’apparaissait pas avec une requête d’affichage classique.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl -n rook-ceph get cephcluster
NAME DATADIRHOSTPATH MONCOUNT AGE STATE HEALTH
rook-ceph /var/lib/rook 1 88d Created HEALTH_OK
kubectl -n rook-ceph delete cephcluster rook-ceph
cephcluster.ceph.rook.io &amp;#34;rook-ceph&amp;#34; deleted
&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;Malheureusement, ce n’est pas totalement terminé ! Notre namespace n’a plus d’objets qui bloquent sa suppression. Pour autant, il est encore bloqué dans l’état Terminating.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl -n rook-ceph delete cephcluster rook-ceph
cephcluster.ceph.rook.io &amp;#34;rook-ceph&amp;#34; deleted
^C
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans ce cas de figure, on peut soit relancer le script knsk, soit, à la main, patcher l’objet pour vider la metadata &amp;ldquo;finalizers&amp;rdquo; et débloquer le processus de suppression. Ca revient au même, mais je vous le met pour que vous compreniez ce que vous faites :&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;dgermain:~/sources/knsk$ kubectl -n rook-ceph patch cephclusters.ceph.rook.io rook-ceph -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;:{&amp;#34;finalizers&amp;#34;: []}}&amp;#39;&lt;/span&gt; --type&lt;span class="o"&gt;=&lt;/span&gt;merge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cephcluster.ceph.rook.io/rook-ceph patched
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et maintenant, votre namespace est supprimé !&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://medium.com/@newtondev/how-to-fix-kubernetes-namespace-deleting-stuck-in-terminating-state-5ed75792647e" target="_blank" rel="noopener"
&gt;How to fix Kubernetes namespace deleting stuck in Terminating State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/thyarles/knsk/blob/master/knsk.sh" target="_blank" rel="noopener"
&gt;github.com/thyarles/knsk : Kubernetes namespace killer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://rook.io/docs/rook/latest/Getting-Started/ceph-teardown/" target="_blank" rel="noopener"
&gt;Documentation Ceph : Ceph Teardown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><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>