Patrice Ferlet
Patrice Ferlet
Créateur de ce blog.
Publié le 16 février 2021 Temps de lecture: 8 min

Me suivre sur Mastodon

Kind - Kubernetes local, sans Docker ? avec Podman !

thumbnail for this post

Kind (Kubernetes in Docker) avec Podman au lieu de Docker, avec un utilisateur “normal” - disons, en évitant au maximum de passer par “sudo”

Soyons clairs, je n’ai rien contre Docker. Mais Docker, c’est “une méthode parmis d’autres” pour créer des conteneurs. Et force est de constater que depuis quelques temps je me détourne de cette manière de faire pour diverses raisons.

L’une d’entre elles est le fait qu’il en bave avec les nouvelles gestions de hiérarchie unifiée cgroup… Depuis Fedora 33, nous sommes forcés de dégrader le fonctionnement en injectant un paramètre à la ligne de démarrage du noyau Linux. Et ça, çe me gène.

Il existe d’autres “runners”, comme “CRI-O”, “runc”… et bien que nous avons une mouture de Docker maison nommée “moby-engine” sur Fedora, je me range de plus en plus du côté de podman. J’adore le principe.

  • Pas de service qui tourne en fond
  • Gestion des images locales à l’utilisateur (dans ~/.local/share/containers)
  • Donc… pas de groupe à gérer (avec Docker il faut être dans le groupe docker)
  • podman-compose très compatible à docker-compose

C’est propre.

Et, bien entendu, c’est compatible avec Docker - les pulls d’images fonctionnent, les conteneurs ont la même tête et les commandes de démarrage sont très proches.

La seule vraie grosse différence, et elle fait un peu mal, c’est que vos conteneurs n’auront plus d’IP à proprement parler (si vous les démarrez en tant qu’uitilisateur “normal”). Aussi, ils sont injectés dans des Pods, tout comme sur Kubernetes - et donc on se familarise plus vite à cette notion. L’avantage est que les conteneurs au sein d’un même pod communiquent avec l’adresse “localhost”, mais ça surprend un peu de ne pas pouvoir utiliser un vieux dnsmasq de derrière les bottes de foins pour taper sur le conteneur. Rien de bien méchant mais ça peut être une contrainte.

OK donc, je passe à Podman, et je suis content. Mais je bosse beaucoup sur Kubernetes… et donc j’ai besoin de tester localement mes déploiements.

Kind ?

Si vous ne connaissez pas kind, je vous invite à aller voir la page de documentation. Si vous n’avez pas “Go”, pas de panique, passez par la page Github pour prendre le binaire.

Ce binaire, placez le dans un répertoire accessible dans $PATH. J’utilise personnellement ~/.local/bin, mais je sais que certaines distributions (Ubu…) ont du mal avec les standards, donc débrouillez vous car dans l’article, je vais utiliser la commande “kind” en partant du principe qu’elle est accessible sans donner le chemin.

Bref, en gros, Kind propose de démarrer un cluster Kubernetes en quelques secondes, sans VM, via… Docker…

Ouais… Docker… Kind veut Docker, ou du moins il “préfère”.

Pas de panique, Kind supporte podman de manière “expérimentale”. Alors bref, je me dis “bon, dégageons Docker et on y va”. (Oui j’ai vraiment supprimé le paquet “moby-engine” et/ou “docker” de mon poste)

Et là, le drame:

$ kind create cluster
enabling experimental podman provider
Creating cluster "kind" ...
podman provider does not work properly in rootless mode

Arrgghhhh oui, zut… Kind veut créer un CNI du coup, et il a aucun droit car je ne suis pas “root”. La raison est simple, Kind a besoin d’une IP pour le ou les conteneurs qu’il va créer pour simuler les “masters/nodes”, et donc il faut que Podman puisse créer la ressource CNI (ou utiliser celle qui existe pour les conteneurs non “rootless”).

Et bien pas de panique ! On va passer un peu outre en utilisant jute un peu “sudo” mais vraiment qu’un peu.

D’abord, on démarre le cluster

Bon, on va pas y couper, il faut passer par “sudo” pour démarrer le cluster, ça c’est pas sorcier et “tant pis”:

sudo /home/metal3d/.local/share/go/bin/kind create cluster
enabling experimental podman provider
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.20.2) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂

Alors, pour ma part, je force l’utilisation du chemin complet pour atteindre le binaire “kind”, parce que j’ai installé depuis les sources avec “go install”, mais si vous avez posé le binaire dans un PATH accessible par tout le monde, pas de souci, mettez juste sudo kind create cluster.

Bon, jusque là tout vas bien, kind a démarré et il est accessible… par root… !?

# ne marche pas
kubectl get nodes

# marche bien...
sudo kubectl get nodes

Hors de question de taper “sudo” pour toutes les commandes !

On fait quoi ? On se met un bon vieux Eric Bibb en repensant au bon vieux temps où on se disait “non mais, pas grave je vais bosser en root directement”…

NON !

On évite sudo ?

Et bien c’est simple, là, la seule chose qui fait que seul “root” ait accès au cluster ce n’est pas parce que le “pod” a été démarré par “root”, non non non, c’est que la configuration d’accès (le “kubeconfig”) a été écrite sur /root, on va juste la récupérer !

sudo cp /root/.kube/config ~/.kube/kind-config
sudo chown $(id -u):$(id -g) ~/.kube/kind-config

# Si vous savez ce que vous faites:
# ln -sf ~/.kube/kind-config ~/.kube/config
# Sinon, utilisez la variable `KUBECONFIG` pour la placer sur ce fichier:
# export KUBECONFIG=~/.kube/kind-config
# et pensez-y... tout le temps !

OK, on y est, testons:

$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:40113
KubeDNS is running at https://127.0.0.1:40113/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Et voilà… C’était simple 😇

Soyons précis, désormais on a accès au cluster local parce que le “Kubeconfig” est généré pour ce cluster. Mais si vous le supprimez et que vous le recrééz, il faudra récupérer la configuration /root/.kube/config pour la placer dans votre HOME. Car cette configuration contient le certificat nécessaire pour s’authentifier sur le cluster. Compris ?

On va un peu plus loin ?

Cette partie fonctionne avec Kind démarré avec Docker ou Podman donc pas de différence hormis le fait que la récupération de l’IP du noeud se fait “sans sudo” avec Docker.

Perso, j’aime pouvoir accéder à mes tests sans passer par un “port-forward” ou un NodePort. Donc, vous devez le savoir, la technique est d’utiliser un ingress-conroller et de créer des ingress.

Le souci, bha… on a pas de nom de domaine local. Sauf que, des gens bien intentionnés vous permettent d’utiliser un domaine particulier qui est très pratique. Je vous en cite 3 mais je suis persuadé qu’il en existe d’autres:

  • xip.io
  • nip.io
  • sslip.io

Tous ces domaines sont très pratiques, il vous permettent de placer une IP dans le nom de domaine ainsi qu’un sous-domaine. Par exemple:

domaine résolution
10.2.3.4.xip.io 10.2.3.4
app.10.2.3.4.xip.io 10.2.3.4
mon.app.10.2.3.4.xip.io 10.2.3.4

Bon vous avez compris… on met ce qu’on veut en IP dans le domaine, et ça répond avec cette IP. Pratique !

Ouais sauf que… Free et SFR ont une facheuse tendance à foutre la merde avec les DNS, et j’ai donc pas mal de collègues qui en bavent. En gros, avec Free et SFR vous avez une chance sur dix que ça passe. Et même en forçant les DNS c’est le boxon (SFR filtre le port 53 il parait). Donc, si vous êtes chez ces FAI, vous allez potentiellement en baver un peu.

Bon, on installe un “ingress-controller”, par exemple l’excellent “ingress-nginx” que je trouve au poil:

# On ajoute le dépot qui va bien
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# on installe ça dans un namespace nommé "infra" (valeur modifiable)
NS="_change_infra"
helm install ingress-controller ingress-nginx/ingress-nginx \
    --set controller.hostNetwork=true \
    --namespace=$NS --create-namespace

Et après quelques secondes l’ingress-controller est présent, reste à avoir l’IP du noeud prinicpal (ou d’un des noeuds worker si vous avez démarré plusieurs workers, donc faites un choix):

sudo podman inspect kind-control-plane -f '{{.NetworkSettings.Networks.kind.IPAddress}}'

L’ip qui apparait, vous la notez et vous la gardez dans un coin.

À partir de maintenant, quand vous paramétrez un ingress, vous donner en hostname “ce-que-vous-voulez.ip-trouvée.xip.io”, et c’est gagné.

Par exemple, pour tester, on va se déployer un petit serveur nginx:

# Récupération de l'ip si vous ne l'avez pas encore
KIND_IP=$(sudo podman inspect kind-control-plane \
    -f '{{.NetworkSettings.Networks.kind.IPAddress}}')

# ajout du dépot de bitnami (bon sang que je les aime)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# le sous-domaine voulu, préfix de xip
DOMAIN="_change_example"

# Namespace pour tester
NS="_change_testapp"

# on installe nginx en indiquant une adresse
helm install _change_mon-application bitnami/nginx \
    --namespace=$NS --create-namespace \
    --set ingress.enabled=true \
    --set ingress.hostname="$DOMAIN.$KIND_IP.xip.io"

echo "Visitez http://$DOMAIN.$KIND_IP.xip.io"

L’adresse apparait donc à la fin, et vous devriez pouvoir visiter la page web indiquée. Si tout va bien, après quelques secondes/minutes d’installation selon la vitesse de votre machine, vous devriez avoir une belle page de “Welcome” de la part de nginx. C’est tout bon !

Alors, podman ?

Honnêtement, podman est un bonheur. Aujourd’hui je construis mes images avec, j’utilise “podman-compose” et je n’ai ressenti que très peu de vraies grosses différences hormis le fait que je n’ai pas d’IP direct. Mais… Je me suis surtout rendu compte que je n’ai pas tant besoin que ça d’un IP de conteneur. Mais je ne dis pas non plus que c’est inutile, disnons que j’ai appris à m’en passer.

Kind version 0.10.x fonctionne vraiment bien avec podman. Je n’ai à ce jour aucun souci. Maintenant, clairement, au travail j’utilise toujours docker pour des raisons évidentes de possibles manques de compatibilité avec mes coéquipiers. Cela-dit, je pourrais m’en passer… J’expérimente en ce moment.

Podman ne permet pas pour le moment d’avoir des IP en mode “rootless” (c’est-à-dire si vous démarrez des conteneurs avec votre utilisateur, sans sudo), c’est donc pour cela qu’il faut passer par “sudo” pour démarrer le cluster local. Mais en déportant la configuration de kubectl sur votre répertoire personnel, vous n’aurez pas de souci.

Donc, en somme, I 💙 Podman et Kind.

comments powered by Disqus