Initieer een kubernetes cluster

In de vorige blog beschreef ik hoe ik de infrastructuur heb opgebouwd. Nu is het tijd voor kubernetes. Een van de mooie dingen van kubernetes is de eenvoud en de duidelijke uitleg wat je moet doen. Maar waar je begint, dat is niet altijd duidelijk. Het is precies het eerste woord wat ik intikte: initieer. Init dus, en dat doe je als root (of met sudo) op de masternode of control plane. In mijn geval de kub0 node, en we geven een pod-network-cidr mee:

kubeadm init --pod-network-cidr=10.244.0.0/16

Vervolgens begint een redelijk lang proces, afhankelijk van de snelheid van je internetverbinding en infrastructuur. Als je het voor het eerst start kan het nogal overweldigend overkomen. Wat er gebeurt in het kort is dat de juiste containers worden opgehaald, certificaten worden gegenereerd en geïnstalleerd en een paar pods worden gemaakt. Dat laatste is niet onbelangrijk:

[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"

Deze pods heb je minstens nodig om tot een werkend cluster te komen. Elke pod heeft zijn eigen functie. Uiteindelijk komt de melding:

Your Kubernetes control-plane has initialized successfully!

Vervolgens staan er een aantal stappen vermeld die je moet uitvoeren. Controleer vooraf even of je sudo werkt. Zo nee, voegt jezelf dan toe aan de groep ‘wheel’. Login als gewone gebruiker en voer uit:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Om te controleren of het gelukt is voer je een ‘find ${HOME}/.kube -ls‘ uit en controleer je of de rechten goed staan. Dat is het geval als de bestanden en directories op jouw naam staan.

In de config-file staan certificaten waarmee je jezelf kan authenticeren aan de API. Die config-file noemen we een kubeconfig bestand. Wil je er meer over lezen, ga dan naar https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/

Voordat nodes toegevoegd kunnen worden zal een podnetwerk moeten worden ingezet; gedeployed in goed nederlands. Er zijn meerdere addons voor podnetwerken beschikbaar. In de output van kubeadm staat een link waar de belangrijkste addons beschreven staan. https://kubernetes.io/docs/concepts/cluster-administration/addons/

Als je net begint en niet zo goed weet welke je moet kiezen, dan is Weave, Calico of Flannel vaak gebruikt. Maar als je specifieke eisen of wensen hebt, kan je ook een andere kiezen. Ik ga voor Weave. Om die te installeren moet een yaml-file worden toegepast (apply):

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.apps/weave-net created

Die wijsheid is te vinden op: https://www.weave.works/docs/net/latest/kubernetes/kube-addon/

Vervolgens zullen we de nodes moeten toevoegen aan het cluster. We loggen in op kub1, kub2 en kub3 (de andere doe ik later). De laatste regels van ‘kubeadm init‘ geven weer wat je moet doen. Er wordt gesproken over een token. Dat token is 24 uur geldig, dus we hebben 24 uur de tijd om met dit token nodes toe te voegen.

[root@kubx ~]# kubeadm join 192.168.2.40:6443 --token eochqn.0qvtlsm9ckwx06zj \
                                              --discovery-token-ca-cert-hash sha256:a47932f14acbc8e0e4f3ea008614348b1015fb7afbd2d52bbf368b1f908e5223
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

Hierna zijn de nodes gekoppeld. Als we nu gaan kijken wat de status is, zoals hierboven ook aangegeven is, zien we dat de status nog niet meteen “Ready” is. Geen zorgen, na enige tijd komt dat goed. Bedenk dat kubeadm als root moet worden uitgevoerd, maar kubectl als user.

[user@kub0 ~]$ kubectl get nodes
NAME                  STATUS     ROLES    AGE   VERSION
kub0.heirbaut.local   Ready      master   23h   v1.19.0
kub1.heirbaut.local   Ready      <none>   22h   v1.19.0
kub2.heirbaut.local   NotReady   <none>   8s    v1.19.0
kub3.heirbaut.local   NotReady   <none>   7s    v1.19.0
[user@kub0 ~]$ kubectl get nodes
NAME                  STATUS     ROLES    AGE   VERSION
kub0.heirbaut.local   Ready      master   23h   v1.19.0
kub1.heirbaut.local   Ready      <none>   22h   v1.19.0
kub2.heirbaut.local   NotReady   <none>   28s   v1.19.0
kub3.heirbaut.local   NotReady   <none>   27s   v1.19.0
[user@kub0 ~]$ kubectl get nodes
NAME                  STATUS   ROLES    AGE     VERSION
kub0.heirbaut.local   Ready    master   23h     v1.19.0
kub1.heirbaut.local   Ready    <none>   22h     v1.19.0
kub2.heirbaut.local   Ready    <none>   2m51s   v1.19.0
kub3.heirbaut.local   Ready    <none>   2m50s   v1.19.0

Het belangrijkste commando wat we gebruiken is kubectl. Het is een interface naar de API-server; in feite spreek je via kubectl alleen de API-server aan. Kubectl zelf doet verder niet zo veel, behalve de syntax controleren en nog een paar zaken. Maar het echte werk wordt door de API-server gedaan. Omdat kubectl veel commandline opties heeft, is het soms lastig die allemaal te onthouden. Command completion is dan erg handig en gelukkig levert kubernetes dat allemaal mee. Met het commando kubeadm completion bash wordt de output gegenereerd om te gebruiken voor command completion in bash. Het kan voor meerdere shells gegenereerd worden; zie de output van kubeadm completion --help. De snelste manier om het te gebruiken is om de command completion te laden als je inlogt. Daarvoor kan je het beste een bestand zetten in de directory /etc/bash_completion.d

kubeadm completion bash > /etc/bash_completion.d/k8s.bash

Daarna kan je het inladen door uit te loggen en weer in te loggen, of eenmalig dat script uit te voeren:

source /etc/bash_completion.d/k8s.bash

Het cluster is nu klaar. Alleen staat er nog niet veel op.