Kubernetes cluster op Raspberry Pi

Ter lering ende vermaeck ga ik een Kubernetes Cluster maken met Raspberry PI’s, model 3B, bestaande uit één master en twee workers (minions). Als powersupply heb ik momenteel de beschikking over een 3AMP PSU en dat blijkt genoeg te zijn om de 3 RPi’s te voorzien van de nodige spanning. De bovenste 2 RPI’s krijgen hun spanning via de GPIO poort vanuit de onderste RPI. (pin 2 en 4 = +5V, pin 6 = GND) Via ethernet kabels zijn ze allen aangesloten op een netwerk-switch (Gigabit). Een SD card voorziet in het Raspbian OS.

De pre-requisites zijn:

  • Nieuwe installatie van Hypriot
  • Aangesloten op een Gigabit Network switch waarop ook mijn laptop is aangesloten (en dus SSH toegang)
  • Hostname en Static IP adres
    • master = 192.168.1.101
    • node1 = 192.168.1.102
    • node2 = 192.168.1.103

Stap 1. SD card maken

Om Hypriot op een SD card te zetten maak je gebruik van Etcher. Na het downloaden van de Hypriot image is het zeer eenvoudig om met Etcher de image op een SD card te plaatsen.

Stap 2: IP adres instellen

Standaard login op de Hypriot OS is
username: pirate
password: hypriot

Nadat de Raspberry Pi gestart is en je hebt het IP adres gevonden (bv. via je router-dashboard) kun je inloggen op de RPi en het bestand /etc/dhcpcd.conf aanpassen om een vast IP adres in te stellen. Zoek naar het gedeelte en pas dit aan. Bijvoorbeeld:

# Example static IP configuration:
interface eth0
static ip_address=192.168.1.101/24
static routers=192.168.1.254
static domain_name_servers=192.168.1.254 8.8.8.8

Hierna geven we ook elke Raspberry Pi een eigen unieke hostname:

$ sudo hostnamectl set-hostname master

Herhaal dit tevens voor de overige RPi’s, uiteraard elk met hun eigen unieke ip adres en hostname. Hierna herstarten:

$ sudo reboot

Stap 3. Kopieer jouw public-key

Om in te loggen met ssh is het raadzaam om dit met een ssh-key-pair te doen. Om jouw public key te kopieren naar de Raspberry Pi’s, gebruik het volgende commando’s:

$ ssh-copy-id pirate@192.168.1.101
$ ssh-copy-id pirate@192.168.1.102
$ ssh-copy-id pirate@192.168.1.103

Nog vestandiger is het om hierna het inloggen met username/password op de ssh-daemon uit te schakelen. Zet daarvoor op elke RPI de volgende regel in /etc/ssh/sshd_config:

PasswordAuthentication yes

Hierna de ssh daemon herstarten:

$ sudo systemctl restart sshd

Stap 4. Installatie kubeadm

De volgende stappen gelden voor zowel de master als de workers. Hiermee wordt de Kubernetes repository toegevoegd en kubeadm geïnstalleerd. Voer deze commando’s uit op elke Raspberry Pi:

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubeadm

Stap 5. Configureer en start de master

De master node heeft een aantal images nodig en wordt daarna gestart met het ‘kubeadm init‘ commando. De ‘pods’ die later aangemaakt gaan worden geven we een eigen netwerk en dat geven we aan met de ‘pod-network-cidr‘ parameter: (cidr = Classless Inter-Domain Routing)

$ sudo kubeadm config images pull -v3
$ sudo kubeadm init --token-ttl=0 --pod-network-cidr=10.244.0.0/16

De instructies voor de worker-nodes zal op het scherm verschijnen en de token hebben we nodig om de workers te laten ‘joinen‘. Kopieer dus die instructie en gebruik het op de worker nodes.

Stap 6. De workers configureren en koppelen

De gekopieerde instructie van de master wordt nu gebruikt op de worker-nodes die gekoppeld gaan worden om een cluster te vormen:

$ sudo kubeadm join 192.168.1.101:6443 --token xqpho0.zlujflhkt0 --discovery-token-ca-cert-hash sha256:5034e38d74344df0ef9f8d372c34b9e

Dit is een voorbeeld, uiteraard zal jouw token en hash-waarde anders zijn dan de hier getoonde.

Stap 7. KUBECONFIG environment

Voor elke Kubernetes cluster geldt een configuratie waarmee de instructies gegeven kunnen worden aan het cluster. Deze wordt standaard in /etc/kubernetes/admin.conf op de master-node geplaatst en kunnen we kopieren naar het werkstation waarmee we het beheer willen doen. Je kunt deze een willekeurige naam geven of de standaard naam (config) als dit de enige cluster is waarmee gecommuniceerd wordt. Op de master, voer de volgende commando’s uit:

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

Hierna kun je op je eigen werkstation dit bestand kopieren, bv. met scp: (Windows gebruikers zouden ‘Windows Subsystem for Linux‘ moeten gaan gebruiken)

$ scp pirate@master:/$HOME/.kube/config .

Hierna zou het volgende commando de nodes laten zien van je nieuwe cluster: (als je tenminste kubectl op je werkstation hebt geïnstalleerd)

$ kubectl get nodes -o wide
NAME     STATUS   ROLES    AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION   CONTAINER-RUNTIME
master   Ready    master   19h     v1.15.0   192.168.1.101     <none>        Raspbian GNU/Linux 10 (buster)   4.19.57-v7+      docker://18.9.0
node1    Ready    <none>   18h     v1.15.0   192.168.1.102     <none>        Raspbian GNU/Linux 10 (buster)   4.19.57-v7+      docker://18.9.0
node2    Ready    <none>   3h24m   v1.15.0   192.168.1.103     <none>        Raspbian GNU/Linux 10 (buster)   4.19.57-v7+      docker://18.9.0

Stap 8. Container networking

Container networking is één van de belangrijkste onderdelen in Kubernetes en een goed werkende controller voor RPi’s is ‘flannel’. Om deze te installeren dient het volgende commando:

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml

Controle geschiedt middels een get pods op de namespace kube-system:

$ kubectl -n kube-system get pods --selector="app=flannel"
NAME                        READY   STATUS    RESTARTS   AGE
kube-flannel-ds-arm-8f78d   1/1     Running   0          5m24s
kube-flannel-ds-arm-b6257   1/1     Running   0          5m24s
kube-flannel-ds-arm-gwgnm   1/1     Running   0          5m24s

Note: Op één van de nodes gaf de flannel pod een foutmelding en bleef in status ‘CrashLoopBackOff‘ staan. Met het commando:

$ kubectl logs pod/kube-flannel-ds-arm-m2mpw -n kube-system

werd aangegeven dat de link ‘flannel.1′ incompatible addresses had. Op de bewuste node werd dit verholpen met het volgende commando:

$ sudo ip link delete flannel.1

Stap 9. Testen

Als test kunnen we nu een nginx webserver installeren en een nodeport-service maken die een random-poort doorstuurt. De commando’s:

$ kubectl create deployment nginx --image=nginx
$ kubectl create service nodeport nginx --tcp=80:80

De nginx service poort-nummer kunnen we vinden met

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1               443/TCP        24h
nginx        NodePort    10.110.34.151           80:32456/TCP   85m

en in dit geval zien we dat de poort op 32456 geconfigureerd is. Met een browser kunnen we nu naar het IP adres van één van de nodes en dat zal dan de NGINX welkom pagina laten zien.

Note: Om verkeer door te laten op de workers via de NodePort dient ‘iptables‘ een regel te krijgen met toestemming hiervoor. Normaal gesproken zou de kube-proxy dit regelen maar op mijn twee worker-nodes moest ik alsnog verkeer toelaten. Dit zou in een productie-omgeving niet raadzaam zijn maar voor mijn lokale cluster heb ik het volgende commando op de workers uitgevoerd:

$ sudo iptables -P FORWARD ACCEPT

Om dit permanent te maken, voer het volgende commando uit:

$ sudo apt-get install iptables-persistent

en bevestig met Yes om de huidige regels mee te nemen naar de nieuwe configuratie.

1 reactie op “Kubernetes cluster op Raspberry Pi

  1. Nadat ik een ‘kubeadm reset’ had gedaan op de master en daarna met ‘kubeadm init’ de cluster opnieuw gemaakt had, zag ik dat coredns pods bleven hangen op ‘Pending’ (en daardoor de nodes op ‘NotReady’) door het feit dat de nodes een ‘taint’ hadden dat niet door de pods werd ‘tolerated’. De oplossing hiervoor was het installeren van de ‘flannel’ networking zoals beschreven in stap 8.

Reacties zijn gesloten.