Kubernetes INside Docker
Introduction
Lorsque l’on développe un chart, ou que l’on souhaite faire des tests sur Kubernetes (ex : rbac), nous n’allons pas faire ces tests sur un environnement de production. Nous n’avons non-plus pas toujours de cluster dédié aux tests. Alors avec l’aide de KIND : nous allons pouvoir créer ce cluster de test, et sans devoir installer la moindre machine virtuelle.
Comme son nom l’indique ce soft permet de créer un cluster à partir de conteneurs Docker. C’est d’ailleurs ce que j’utilise dans le CI présenté ici : Créer un dépot Helm
Information
Ma configuration :
- Docker : 20.10.22
- Kind : 0.17.0
- Linux : Ubuntu amd64 (6.0.12)
Pré-requis si vous utilisez Docker en RootLess
Avertissement
Vous pouvez passer cette partie si vous n’utilisez pas Docker en Rootless.
Vérifiez si les cgroup v2 sont activés sur votre poste :
➜ grep cgroup /proc/filesystems
nodev cgroup
nodev cgroup2
Si ce n’est pas le cas, vous devrez ajouter GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"
à votre fichier /etc/default/grub
, puis mettre à jour votre grub : sudo update-grub
.
Installer Kind
Linux
ARCH="amd64"
KIND_VERSION="v0.20.0"
wget https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-linux-${ARCH} -O ./kind
Go
go install sigs.k8s.io/[email protected]
Mac
ARCH="amd64"
KIND_VERSION="v0.20.0"
wget https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-darwin-${ARCH} -O ./kind
Nix
Avec Nix, il est possible de lancer Kind de manière éphémère via Nix-Shell:
nix-shell -p kind
Utiliser Kind
➜ kind create cluster
ERROR: failed to create cluster: running kind with rootless provider requires setting systemd property "Delegate=yes", see https://kind.sigs.k8s.io/docs/user/rootless/
Si vous tombez sur la même erreur que moi, alors suivez les prochaines étapes. (sinon on se retrouve un peu plus bas)
sudo mkdir -p /etc/systemd/system/[email protected]
sudo sh -c 'cat >/etc/systemd/system/[email protected]/delegate.conf <<EOF
[Service]
Delegate=yes
EOF'
sudo sh -c 'cat >>/etc/modules-load.d/iptables.conf <<EOF
ip6_tables
ip6table_nat
ip_tables
iptable_nat
EOF'
sudo systemctl daemon-reload
Nous retentons après coup :
➜ kind create cluster
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.25.3) 🖼
✓ 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 nice day! 👋
➜ kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:45975
CoreDNS is running at https://127.0.0.1:45975/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Pour le supprimer : kind delete cluster kind-kind
Avertissement
- Les montages OverlayFS ne peuvent être activé que si votre kernel est >= 5.11
- Impossible de mount les block storages (iSCSI, Aws, Local Volume)
- Impossible de mount un partage NFS
Astuce
Je vous conseille d’utiliser Kubectx pour changer votre context utilisé.
kubectx kind-kind
Les conteneurs ’nodes’ sont visibles directement avec la cli Docker.
➜ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
288826f42d30 kindest/node:v1.25.3 "/usr/local/bin/entr…" 14 hours ago Up 41 minutes 127.0.0.1:6443->6443/tcp test-control-plane
98738fa957e4 kindest/node:v1.25.3 "/usr/local/bin/entr…" 14 hours ago Up 41 minutes test-worker
Configuration KIND
Si l’usage de KIND est assez simple, il est toujours possible de rajouter des petits paramètres pour l’adapter à nos besoins.
Par exemple, il est possible de choisir le réseau des pods/services. Il suffit de créer un fichier yaml qui accueillera notre configuration :
# kind-config.yml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: reseau-en-192
networking:
podSubnet: "192.168.244.0/24"
serviceSubnet: "192.168.137.0/24"
Et nous créons ce cluster à partir de notre fichier kind-config.yml
.
➜ kind create cluster --config=kind-config.yml
Et nous observons les IPs choisies par notre cluster:
➜ kubectl get pods -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-565d847f94-pmgqf 1/1 Running 0 28s 192.168.244.2 reseau-en-192-control-plane <none> <none>
kube-system coredns-565d847f94-rd5jh 1/1 Running 0 28s 192.168.244.3 reseau-en-192-control-plane <none> <none>
kube-system etcd-reseau-en-192-control-plane 1/1 Running 0 42s 172.18.0.2 reseau-en-192-control-plane <none> <none>
kube-system kindnet-4bhxr 1/1 Running 0 28s 172.18.0.2 reseau-en-192-control-plane <none> <none>
kube-system kube-apiserver-reseau-en-192-control-plane 1/1 Running 0 42s 172.18.0.2 reseau-en-192-control-plane <none> <none>
kube-system kube-controller-manager-reseau-en-192-control-plane 1/1 Running 0 42s 172.18.0.2 reseau-en-192-control-plane <none> <none>
kube-system kube-proxy-g88wr 1/1 Running 0 28s 172.18.0.2 reseau-en-192-control-plane <none> <none>
kube-system kube-scheduler-reseau-en-192-control-plane 1/1 Running 0 43s 172.18.0.2 reseau-en-192-control-plane <none> <none>
local-path-storage local-path-provisioner-684f458cdd-bdnmt 1/1 Running 0 28s 192.168.244.4 reseau-en-192-control-plane <none> <none>
➜ kubectl get service -A -o wide
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default kubernetes ClusterIP 192.168.137.1 <none> 443/TCP 75s <none>
kube-system kube-dns ClusterIP 192.168.137.10 <none> 53/UDP,53/TCP,9153/TCP 74s k8s-app=kube-dns
Nous avons bien nos pods sur le réseau 192.168.244.0/24, et les services sur 192.168.137.0/24.
Information
Ce réseau est géré par Docker, Kind n’a pas la main-mise sur le choix des IPs. C’est un réseau Docker indépendant des autres conteneurs. Pour voir sa configuration :
docker network inspect kind
Si l’on souhaite avoir un second noeud, il suffit de mettre l’instruction :
[...]
nodes:
- role: control-plane
- role: worker
On peut également ajouter des labels aux nodes :
[...]
- role: worker
labels:
role: db-controler
Les possibilités sont vastes, la documentation de KIND est très claire et montre de nombreux cas d’utilisations. Voici le fichier que j’utilise au quotidien dans mes différents tests :
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-petit-cluster
networking:
apiServerAddress: "127.0.0.1"
apiServerPort: 6443
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 3000
hostPort: 3000
listenAddress: "127.0.0.1"
protocol: TCP
- role: worker
labels:
tier: backend