À la découverte de K3S

À la découverte de K3S

Introduction

Vous connaissez certainement l'orchestrateur de conteneur Kubernetes et sa complexité d'installation si vous avez déjà eu l'occasion d'en installer un. On peut tout de même s'abstraire de cette difficulté en utilisant des moyens d'automatisation comme avec Kubespray pour les amateurs d'Ansible. On peut rajouter à cette complexité d'installation le fait qu'il y a des conditions à respecter pour les machines en matière de CPU et RAM.

C'est pourquoi je vais vous parler de K3S de Rancher qui est un cluster Kubernetes allégé, rapide et très simple à mettre en place. Le binaire qui permet d'exécuter un master ou un worker pèse moins que 100 Mo. Il est préconisé pour tous les types d'utilisations, même si de par sa taille et les ressources minimales demandées pour l'exécuter, il est recommandé pour de l'IoT ou pour les architectures ARM.

Il possède cinq différences majeures avec un cluster Kubernetes classique :

  • Suppression des fonctionnalités tagguées "legacy", "alpha", "non-default" et des addons ;
  • Utilisation de sqlite3 comme stockage par défaut ;
  • Gestion automatique du TLS ;
  • Très peu de dépendances avec le système d’exploitation, uniquement besoin d'un noyau Linux et des cgroups ;
  • Il utilise un tunnel websocket plutôt que d'exposer un port pour l'API Kubelet des workers.

Il a aussi un autre avantage spécifique, c'est qu'il ne demande pas d'installer Docker. RunC et Containerd sont les deux outils utilisés pour la conteneurisation.

De plus, K3S propose par défaut dans le cluster des outils très légers comme Traefik (que je ne présente plus) qui est l'ingress controller principal.

J'avais réalisé un article d'une précédente version de K3S en mode multi-master sur une infrastructure AWS et avec l'Ansible, si cela vous intéresse, vous pouvez le retrouver ici.

Dans la suite de cet article, le but est de vous montrer l'installation de K3S en mode local sur plusieurs machines avec Vagrant qui permet de provisionner par le code des machines virtuelles avec VirtualBox.

Fonctionnement

Le fonctionnement de K3S est assez simple, si l'on prend le cas de deux machines, une pour le master et l'autre pour le worker. Il suffit de télécharger le binaire K3S sur la machine et d'exécuter la commande suivante :

k3s server

Cela va démarrer le master et générer un token qu'il faudra utiliser pour connecter l'agent qui se trouve dans /var/lib/rancher/k3s/server/node-token.

Une fois le token récupéré, il sera nécessaire d'accéder à la seconde machine en gardant précieusement le token du master et exécuter la ligne suivante :

k3s agent --server https://<ip du master>:6443 --token <token du master>

Et votre cluster K3S est opérationnel. Vous pouvez donc constater qu'avec deux petites lignes, on est capable de faire démarrer un cluster Kubernetes facilement.

Mise en place

Pour la démonstration, deux machines virtuelles seront nécessaires et seront installées avec Vagrant, une qui servira de master, et l'autre de worker.

Vous pouvez vous baser sur le fichier ci-dessous :

# Variables

# Image à utiliser
IMAGE_NAME = "debian/buster64"
# RAM
MEM = 1024
# Nombre de CPU
CPU = 1
# Nom du master
MASTER_NAME="master"
# Nombre de noeuds
WORKER_NB = 1
# Prefix pour la plage d'adresses IP à utiliser
NODE_NETWORK_BASE = "10.0.0"

# Machines virtuelles

Vagrant.configure("2") do |config|
  config.ssh.insert_key = true

  # Configuration de la RAM et du CPU
  config.vm.provider "virtualbox" do |v|
      v.memory = MEM
      v.cpus = CPU
  end

  # Configuration du Master
  config.vm.define MASTER_NAME do |master|
    master.vm.box = IMAGE_NAME
    master.vm.network "private_network", ip: "#{NODE_NETWORK_BASE}.10"
    master.vm.hostname = MASTER_NAME
  end

  # Configuration du/des Worker(s)
  (1..WORKER_NB).each do |i|
    config.vm.define "worker-#{i}" do |worker|
        worker.vm.box = IMAGE_NAME
        worker.vm.network "private_network", ip: "#{NODE_NETWORK_BASE}.#{i + 10}"
        worker.vm.hostname = "worker-#{i}"
    end
  end
end

On utilisera donc une distribution Debian pour nos deux noeuds, en configurant un réseau privé qui permettra à notre cluster de communiquer. Dans cet exemple, on choisit d'utiliser un seul noeud pour le worker, mais on aurait très bien pu en ajouter d'autres en modifiant la variable WORKER_NB.

Dans le répertoire du fichier Vagrant, la commande ci-dessous permet de mettre en place nos deux machines :

vagrant up

Pour l'installation de K3S, j'ai choisi d'utiliser le playbook officiel communautaire qui se nomme k3s-ansible.

Ce playbook va permettre de réaliser ce qui a été décrit en haut dans la partie Fonctionnement et va configurer la commande kubectl sur notre noeud master pour accéder à notre cluster.

Je vous invite à cloner le dépôt de code afin de configurer l'inventaire.

# On copie l'inventaire qui sert d'exemple
cp -r inventory/sample inventory/vagrant-cluster
# On vient ici modifier la configuration d'accès à nos machines
vim inventory/vagrant-cluster/hosts.ini

Vu que l'on utilise Vagrant, l'accès à nos machines se fait par localhost en modifiant le port d'accès. La première machine qui est notre master utilise le port 2222 et notre worker le port 2200. Enfin, l'utilisateur vagrant est l'utilisateur par défaut qui permet de se connecter en SSH.

[master]
master ansible_host=localhost ansible_ssh_port=2222 ansible_user=vagrant

[node]
worker-1 ansible_host=localhost ansible_ssh_port=2200 ansible_user=vagrant

[k3s_cluster:children]
master
node

Une fois l'inventaire initialisé, il faut modifier plusieurs variables du fichier all.yaml du dossier group_vars :

k3s_version: v1.20.6+k3s1 # Mettre à jour la version de K3S
ansible_user: vagrant # Modifier l'utilisateur par défaut
systemd_dir: /etc/systemd/system
master_ip: 10.0.0.10 # Modifier l'ip du master sinon "localhost" sera utilisé
extra_server_args: "--flannel-iface eth1" # Indiquer que le master doit écouter sur l'interface eth1 (réseau privé)
extra_agent_args: "--flannel-iface eth1" # Indiquer que la connexion du worker au master se fait par l'interface eth1 (réseau privé)

Enfin, il ne reste plus qu'à ajouter les clés privées de nos machines pour les joindre en SSH et exécuter le playbook Ansible :

# À faire dans le dossier où on a exécuté la commande "vagrant up"
eval $(ssh-agent)
ssh-add .vagrant/machines/master/virtualbox/private_key
ssh-add .vagrant/machines/worker-1/virtualbox/private_key

# Commande à exécuter dans le dossier k3s-ansible
ansible-playbook site.yml -i inventory/vagrant-cluster/hosts.ini

Et voilà ! Notre cluster K3S est opérationnel ! Comme vous pouvez le voir ci-dessous :

root@master:~# kubectl get nodes
NAME       STATUS   ROLES                  AGE   VERSION
worker-1   Ready    <none>                 26s   v1.20.6+k3s1
master     Ready    control-plane,master   39s   v1.20.6+k3s1

root@master:~# kubectl get pods -n kube-system
NAME                                      READY   STATUS      RESTARTS   AGE
metrics-server-86cbb8457f-5pwth           1/1     Running     0          50s
local-path-provisioner-5ff76fc89d-2dljw   1/1     Running     0          50s
coredns-854c77959c-wzt9m                  1/1     Running     0          50s
helm-install-traefik-v4zps                0/1     Completed   0          51s
svclb-traefik-g2g4q                       2/2     Running     0          35s
svclb-traefik-2dlc5                       2/2     Running     0          35s
traefik-6f9cbd9bd4-jcl2f                  1/1     Running     0          35s

Conclusion

En conclusion, K3S est une solution rapide et efficace pour mettre en place un cluster Kubernetes quel que soit le type de machine et d'architecture que l'on possède.

Je l'utilise personnellement sur mes rapsberry, ce qui permet de rester dans un contexte Kubernetes sur une architecture ARM et avec peu de ressources utilisées.