Aller au contenu principal

Installer K3s

logo kubernetes

K3s est une version ultra-light de Kubernetes développée par Rancher. Il ne nécessite que 40MB d’espace disque et 512MB de RAM pour démarrer, car il se destine avant tout pour les équipements légers comme ceux de l’IoT, des serveurs de transports edge, des RaspberryPi entre autre.

Que contient cette distribution ?

  • Tous les composants Kubernetes (kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, kube-proxy
  • Docker est remplacé par containerd
  • Pour le réseau; on retrouve Flannel, CoreDNS
  • Pour la gestion d’Ingress Traefik accompagné d’un simple loadBalancer
  • Par contre les plugins des cloud providers et de stockage ont été enlevés.
  • Sqlite3 remplace Etcd.

Installer K3S sur un cluster de VM Ubuntu

Pour cet démonstration, je vais utiliser une machine hôte Ubuntu sur laquelle je vais provisionner 3 VM (1 master + 2 workers) avec vagrant et libvirt.

En premier lieu, il faut installer vagrant et ansible. Je vous renvoie à mes billets d'introduction sur vagrant et ansible pour cela.

Il faut ensuite cloner mon projet :

git clone git@github.com:stephrobert/k3sSandbox.git

Ensuite provisionnons nos 3 VM (pour le serveur plus sage de mettre 1GB de Ram) :

vagrant up

Installons k3s sur tous les nodes :

vagrant push

Au bout de quelques minutes, vous devriez avoir accès à votre cluster k3s.

Un petit contrôle de l’état des nodes du cluster :

ssh master1
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane,master 11m v1.22.5+k3s1
worker2 Ready <none> 10m v1.22.5+k3s1
worker1 Ready <none> 10m v1.22.5+k3s1

Maintenant, vous pouvez utiliser les commandes classiques de kubectl :

kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system local-path-provisioner-64ffb68fd-5r6hf 1/1 Running 0 12m
kube-system coredns-85cb69466-sgk22 1/1 Running 0 12m
kube-system metrics-server-9cf544f65-5qx25 1/1 Running 0 12m
kube-system helm-install-traefik-crd--1-4cwxn 0/1 Completed 0 12m
kube-system helm-install-traefik--1-6txdj 0/1 Completed 1 12m
kube-system svclb-traefik-skffv 2/2 Running 0 11m
kube-system svclb-traefik-tn6xk 2/2 Running 0 11m
kube-system svclb-traefik-m65p5 2/2 Running 0 11m
kube-system traefik-786ff64748-dm5qp 1/1 Running 0 11m

Destruction des VM

Il suffit de lancer la commande :

vagrant destroy -f
==> worker2: Removing domain...
==> worker2: Deleting the machine folder
==> worker1: Removing domain...
==> worker1: Deleting the machine folder
==> master1: Removing domain...
==> master1: Deleting the machine folder
danger

Après un destroy il ne faut pas oublier de nettoyer le fichier /etc/hosts des machines master1, worker1 à n

Quelques explications sur le provisioning

Voici le fichier Vagrantfile :

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

base_ip_str = "10.240.0.1"
cpu_master = 1
mem_master = 1792
number_workers = 2 # Number of workers nodes kubernetes
cpu_worker = 1
mem_worker = 1024
config.vm.box = "generic/ubuntu2004" # Image for all installations
kubectl_version = "1.23.1-00"

nodes = []
(0..number_workers).each do |i|
case i
when 0
nodes[i] = {
"name" => "master#{i + 1}",
"ip" => "#{base_ip_str}#{i}"
}
when 1..number_workers
nodes[i] = {
"name" => "worker#{i }",
"ip" => "#{base_ip_str}#{i}"
}
end
end

# Provision VM
nodes.each do |node|
config.vm.define node["name"] do |machine|
machine.vm.hostname = node["name"]
machine.vm.provider "libvirt" do |lv|
if (node["name"] =~ /master/)
lv.cpus = cpu_master
lv.memory = mem_master
else
lv.cpus = cpu_worker
lv.memory = mem_worker
end
end
machine.vm.synced_folder '.', '/vagrant', disabled: true
machine.vm.network "private_network", ip: node["ip"]
machine.vm.provision "ansible" do |ansible|
ansible.playbook = "provision.yml"
ansible.groups = {
"master" => ["master1"],
"workers" => ["worker[1:#{number_workers}]"],
"kubernetes:children" => ["masters", "workers"],
"all:vars" => {
"base_ip_str" => "#{base_ip_str}",
"kubectl_version" => "#{kubectl_version}"
}
}
end
end
end
config.push.define "local-exec" do |push|
push.inline = <<-SCRIPT
ansible-playbook -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory master.yml
ansible-playbook -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory slave.yml
SCRIPT
end
end

Après l'initialisation des variables et du tableau contenant tous les nodes, nous entrons dans une boucle each qui va permettre d'adapter la configuration des nodes en fonction des paramètres tirés du tableau node. Cela permet de configurer des nodes master et workers avec des ressources mem et cpu différentes.

Après cette boucle, nous retrouvons une commande que j'utilise pour la première fois. La commande push permet de lancer des scripts depuis le noeud local. Pourquoi avoir choisi cette option plutôt que de tout intégrer dans le playbook lancé dans la boucle. Tout simplement que dans la boucle les playbooks ne sont pas lancés une fois, mais à chaque fois qu'un node devient disponible. Du coup le playbook des workers nodes se lance avant même que le token du master soit créé. Cela a comme bénéfice de pouvoir simplifier l'écriture du playbook.

Pour lancer la configuration des nodes, il suffit de lancer la commande vagrant push.