Il est vraiment facile de mettre en ligne un cluster Kubernetes car presque chaque fournisseur de cloud propose sa propre solution (Google GKE, Amazon EKS, Microsoft AKS, DigitalOcean DOKS, Civo Kubernetes,…). Comme parfois, nous voulons simplement pouvoir nous amuser localement, ce post a pour but de répertorier les principales options disponibles pour cette utilisation.

Notes rapides

Pour accéder à un cluster Kubernetes à partir de notre machine locale, nous devons d'abord installer et configurer kubectl, l'outil de ligne de commande utilisé pour envoyer une demande au serveur API du cluster. L'installation est très simple (un binaire à télécharger et à ajouter dans le PATH), nous verrons dans les exemples comment configurer kubectl pour cibler un cluster spécifique. De plus, plusieurs solutions fonctionnent au sein d'une machine virtuelle et ont donc besoin d'un hyperviseur. Dans plusieurs exemples, nous utiliserons Multipass, un excellent outil qui permet de faire tourner des machines virtuelles Ubuntu sur un poste de travail Mac, Linux ou Windows. Selon votre système d'exploitation, il utilise Hyper-V, HyperKit, KVM ou VirtualBox en mode natif pour le temps de démarrage le plus rapide.

Comme son nom l'indique...

Minikube est probablement la solution la plus connue, il démarre une machine virtuelle et exécute tous les processus Kubernetes à l'intérieur de celle-ci. Minikube fonctionnait avec VirtualBox par défaut, mais il peut désormais sélectionner le meilleur pilote disponible sur le système. Nous devons d'abord télécharger la dernière version stable, puis lancer minikube start et nous sommes prêts à partir. Ci-dessous, l'exemple de Minikube démarrant sur MacOS.

    $ minikube start
😄  minikube v1.5.2 on Darwin 10.15.2
    ▪ KUBECONFIG=/Users/admin/.config/k3d/k3s-default/kubeconfig.yaml
✨  Automatically selected the 'hyperkit' driver (alternates: [virtualbox])
💿  Downloading VM boot image ...
    > minikube-v1.5.1.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s
    > minikube-v1.5.1.iso: 143.76 MiB / 143.76 MiB [ 100.00% 1.34 MiB p/s 1m47s
🔥  Creating hyperkit VM (CPUs=2, Memory=2000MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.16.2 on Docker '18.09.9' ...
💾  Downloading kubeadm v1.16.2
💾  Downloading kubelet v1.16.2
🚜  Pulling images ...
🚀  Launching Kubernetes ...
⌛  Waiting for: apiserver
🏄  Done! kubectl is now configured to use "minikube"
⚠️  /Users/admin/google-cloud-sdk/bin/kubectl is version 1.13.11-dispatcher, and is incompatible with Kubernetes 1.16.2. You will need to update /Users/admin/google-cloud-sdk/bin/kubectl or use 'minikube kubectl' to connect with this cluster

Lors du démarrage, le fichier kubeconfig (~ /.kube/config par défaut) est mis à jour (ou créé s'il n'était pas déjà là) et un nouveau contexte, nommé minikube, est créé. Le contexte est défini comme celui par défaut afin que kubectl puisse communiquer immédiatement avec minikube.


Sur MacOS ou Windows 10, nous pouvons utiliser Docker Desktop, un outil qui se concentre sur l'expérience des développeurs pour créer et partager des applications et des microservices conteneurisés. Docker Desktop est livré avec des outils bien connus tels que Docker Compose et Docker Machine. La distribution de Docker Desktop est disponible sur https://www.docker.com/products/docker-desktop. Une fois installé, il peut être configuré pour exécuter un Kubernetes à nœud unique.

Activation de Kubernetes sur Docker Desktop (MacOS)

Cela crée un nouveau contexte, nommé docker-desktop. Nous n'avons qu'à définir ce contexte comme le contexte actuel et nous sommes prêts à partir.

$ kubectl config use-context docker-desktop
$ kubectl get nodes
NAME             STATUS   ROLES    AGE   VERSION
docker-desktop   Ready    master   22d   v1.15.5

Kind signifie "Kubernetes dans Docker" car chaque nœud de cluster s'exécute dans un conteneur Docker. Pour l'utiliser, nous avons besoin de Docker (installé avec Docker Desktop ou avec le raccourci utile «curl https://get.docker.com|sh») et la dernière version de Kind. La capture d'écran suivante montre les commandes qui peuvent être utilisées pour gérer le cycle de vie des clusters.

MBP-de-admin:~ admin$ kind --help
kind creates and manages local Kubernetes clusters using Docker container 'nodes'

Usage:
  kind [command]

Available Commands:
  build       Build one of [base-image, node-image]
  completion  Output shell completion code for the specified shell (bash or zsh)
  create      Creates one of [cluster]
  delete      Deletes one of [cluster]
  export      exports one of [logs]
  get         Gets one of [clusters, nodes, kubeconfig-path]
  help        Help about any command
  load        Loads images into nodes
  version     prints the kind CLI version

Flags:
  -h, --help              help for kind
      --loglevel string   logrus log level [panic, fatal, error, warning, info, debug, trace] (default "warning")
      --version           version for kind

Use "kind [command] --help" for more information about a command.

La création d'un cluster à nœud unique est simple, comme l'illustre la commande suivante:

kind create cluster --name k8s
Creating cluster "k8s" ...
 ✓ Ensuring node image (kindest/node:alpha-v1.14.1) 🖼
 ✓ Preparing nodes 📦
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="k8s")"
kubectl cluster-info

Kind permet également la création de clusters multi-nœuds, il nécessite un fichier de configuration à cet effet. Par exemple, le fichier suivant définit un cluster à 6 nœuds: 3 nœuds maîtres et 3 workers.

# HA-config.yaml
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker

Dans la commande de création, nous n'avons qu'à fournir le fichier de configuration comme paramètre supplémentaire:

$ kind create cluster --name k8s-HA --config HA-config.yaml
Creating cluster "k8s-HA" ...
 ✓ Ensuring node image (kindest/node:alpha-v1.14.1) 🖼
 ✓ Preparing nodes 📦📦📦📦📦📦📦
 ✓ Configuring the external load balancer ⚖️
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining more control-plane nodes 🎮
 ✓ Joining worker nodes 🚜
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="k8s-HA")"
kubectl cluster-info

Après avoir créé 2 clusters, nous pouvons voir les conteneurs Docker correspondants s'exécuter sur notre machine locale. Il existe 7 conteneurs basés sur l'image Docker kindest/node: v1.16.3, chacun d'eux appartenant à un cluster.

$ docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                                          NAMES
bdbf9f5f86bb        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours         53088/tcp, 127.0.0.1:53088->6443/tcp           k8s-HA-control-plane3
547c28f77a5b        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours         53089/tcp, 127.0.0.1:53089->6443/tcp           k8s-HA-control-plane
d02bab9d50b0        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours                                                        k8s-HA-worker
eb9449d22e79        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours         53090/tcp, 127.0.0.1:53090->6443/tcp           k8s-HA-control-plane2
8e197d3c9f39        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours                                                        k8s-HA-worker2
d17be4d79914        nginx:1.15.12-alpine         "nginx -g 'daemon of…"   47 hours ago        Up 47 hours         80/tcp, 53091/tcp, 127.0.0.1:53091->6443/tcp   k8s-HA-external-load-balancer
fa7c93f5d417        kindest/node:alpha-v1.14.1   "/usr/local/bin/entr…"   47 hours ago        Up 47 hours                                                        k8s-HA-worker3

Chaque noeud Kind s'exécute dans un conteneur Docker.

Comme pour les exemples précédents, Kind met à jour le fichier kubeconfig (~ /.kube/config par défaut) avec le nouveau contexte. Dans la liste ci-dessous, nous pouvons voir les différents contextes créés jusqu'à présent:

$ kubectl config get-contexts
         docker-desktop docker-desktop   docker-desktop
         kind-k8s       kind-k8s         kind-k8s
*        kind-k8s-HA    kind-k8s-HA      kind-k8s-HA
         minikube       minikube         minikube

Le contexte actuel est lié à k8s-HA, le dernier cluster que nous avons créé. Si nous listons les nœuds, nous obtenons les 3 maîtres et 3 ouvriers du cluster.

$ kubectl get nodes
NAME                    STATUS   ROLES    AGE     VERSION
k8s-ha-control-plane    Ready    master   4m8s    v1.16.3
k8s-ha-control-plane2   Ready    master   3m24s   v1.16.3
k8s-ha-control-plane3   Ready    master   2m24s   v1.16.3
k8s-ha-worker           Ready    <none>   107s    v1.16.3
k8s-ha-worker2          Ready    <none>   106s    v1.16.3
k8s-ha-worker3          Ready    <none>   106s    v1.16.3

MicroK8s est un outil axé sur la simplicité et l'expérience des développeurs. C'est génial pour l'IoT, Edge et pour être exécuté sur des boîtes Linux. Il est très léger mais fournit des «add-ons» qui sont des composants pré-packagés offrant à Kubernetes des capacités supplémentaires: de la simple gestion DNS à l'apprentissage automatique avec Kubeflow.

# Create a new Ubuntu VM
$ multipass launch --name microk8s --mem 4G
# Install microk8s in the VM through snap
$ multipass exec microk8s -- sudo snap install microk8s --classic
2020-01-02T16:28:04+01:00 INFO Waiting for restart...
microk8s v1.17.0 from Canonical✓ installed

Ensuite, nous copions la configuration du cluster dans un fichier local:

$ multipass exec microk8s -- sudo microk8s.config > microk8s.yaml

Remarque: MicroK8s est livré avec plusieurs binaires, parmi eux:

  • microk8s.config: fournit la configuration kubectl à utiliser de l'extérieur
  • microk8s.kubectl: sa propre version de kubectl

Enfin, nous définissons la variable d'environnement KUBECONFIG pour définir le contexte utilisé par notre kubectl local:

$ export KUBECONFIG=$PWD/microk8s.yaml

Nous sommes prêts à utiliser votre nouveau cluster MicroK8 à nœud unique:

$  kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
microk8s   Ready    <none>   4m19s   v1.17.0

K3s est un Kubernetes léger (5 de moins que dans k8s :)). Il s'agit d'une distribution certifiée Kubernetes conçue pour l'IoT, Edge computing, CI,… Sous Windows, MacOS ou Linux, les K3 peuvent facilement être installés dans une machine virtuelle Ubuntu provisionnée avec Multipass (comme nous l'avons fait pour les MicroK8).

# Create a new Ubuntu VM
$ multipass launch --name k3s
# Get the VM's IP address (we will need it later on)
$ IP=$(multipass info k3s | grep IP | awk '{print $2}')
# Run a shell in the VM
$ multipass exec k3s -- \
bash -c "curl -sfL https://get.k3s.io | sh -"

Une fois installé, nous copions sur notre machine locale le fichier kubeconfig généré dans /etc/rancher/k3s/k3s.yaml dans la VM.

$ multipass exec k3s sudo cat /etc/rancher/k3s/k3s.yaml > k3s.yaml

Dans ce fichier, nous devons changer la clé du serveur afin qu'elle fasse référence à l'IP externe de la machine virtuelle au lieu du loopback (127.0.0.1).

$ sed -i '' "s/127.0.0.1/$IP/" k3s.yaml

Ensuite, nous définissons la variable d'environnement KUBECONFIG pour définir le contexte utilisé par kubectl:

$ export KUBECONFIG=$PWD/k3s.yaml

Nous pouvons alors commencer à jouer avec K3s!

$ kubectl get nodes
NAME   STATUS   ROLES    AGE     VERSION
k3s    Ready    master   5m57s   v1.16.3-k3s.2

Remarque: Si vous êtes sous Linux, vous pouvez installer k3s directement en utilisant la commande

$ curl -sfL https://get.k3s.io | sh -

Dans cet article précédent, vous trouverez des détails supplémentaires pour configurer un cluster multi-nœuds K3s.


k3d

k3d est un autre outil des laboratoires Rancher qui déploie des clusters k3s dans des conteneurs. Il ne nécessite qu'une machine exécutant Docker. L'installation de k3d est très simple, cela peut être fait avec la commande suivante:

$ curl -s https://raw.githubusercontent.com/rancher/k3d/master/install.sh | bash

La création d'un cluster nécessite la commande k3d create avec certains paramètres facultatifs, par exemple:

  • le nom du cluster
  • le port pour publier le serveur api sur la machine locale (la valeur par défaut est 6443)
  • les ports pour publier des services à l'extérieur
  • le nombre de workers pour un cluster à plusieurs nœuds

Nous créons un cluster nommé k3s avec 2 nœuds de travail (au-dessus du maître) :

$ k3d create --workers 2 --name k3s
INFO[0000] Created cluster network with ID e5f18007f00e6faf73fdb158115808540021d65f75184516a5fe1b318fd80b8b
INFO[0000] Created docker volume  k3d-k3s-images
INFO[0000] Creating cluster [k3s]
INFO[0000] Creating server using docker.io/rancher/k3s:v0.10.0...
INFO[0001] Booting 2 workers for cluster k3s
INFO[0001] Created worker with ID ab3e3ce889deb797112018b357147b8239a3a22872ce3fa8bcdc981cc0fc3b96
INFO[0002] Created worker with ID e9b053d2218c73c664f2511649c044b308f7846c63cc873498a8af836cd389b6
INFO[0002] SUCCESS: created cluster [k3s]
INFO[0002] You can now use the cluster with:

export KUBECONFIG="$(k3d get-kubeconfig --name='k3s')"
kubectl cluster-info

Nous pouvons voir les 3 conteneurs créés, un pour chaque nœud du cluster.

$ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
e9b053d2218c        rancher/k3s:v0.10.0   "/bin/k3s agent"         18 seconds ago      Up 17 seconds                                k3d-k3s-worker-1
ab3e3ce889de        rancher/k3s:v0.10.0   "/bin/k3s agent"         19 seconds ago      Up 18 seconds                                k3d-k3s-worker-0
b43b20ee9425        rancher/k3s:v0.10.0   "/bin/k3s server --h…"   20 seconds ago      Up 18 seconds       0.0.0.0:6443->6443/tcp   k3d-k3s-server

Nous pouvons ensuite définir la variable d'environnement KUBECONFIG pour utiliser le kubeconfig créé pour le cluster:

$ export KUBECONFIG="$(k3d get-kubeconfig --name='k3s')"

et commencez à utiliser notre nouveau cluster:

$ kubectl get nodes
NAME               STATUS   ROLES    AGE   VERSION
k3d-k3s-server     Ready    master   14m   v1.16.2-k3s.1
k3d-k3s-worker-0   Ready    <none>   14m   v1.16.2-k3s.1
k3d-k3s-worker-1   Ready    <none>   14m   v1.16.2-k3s.1

Remarque:

Afin d'exposer les services à l'extérieur, le cluster doit être créé avec l'indicateur --publish, plusieurs options de configuration sont illustrées dans la documentation.

Sommaire

Tous les outils que nous avons détaillés dans cet article peuvent être utilisés pour configurer un cluster Kubernetes local. Ils ont différentes fonctionnalités et options: configuration rapide, mise à niveau facile, mises à jour régulières, intégration simplifiée avec d'autres projets de l'écosystème,… Je vous recommande de vérifier certains d'entre eux (tous? :)) et de sélectionner celui qui convient le mieux à vos besoins . De plus, comme nous l'avons vu dans les exemples, Multipass est un excellent outil qui facilite le processus de création de VM