Voor een cloudomgeving wil je applicaties gemakkelijk inzetten, meerdere machines gebruiken voor load balancing en redundantie en zonder onderbreking machines bijplaatsen om te schalen. Met enkele Raspberry Pi’s en Kubernetes maak je op kleine schaal een dergelijk cluster. Kubernetes dient daarbij als cloudsoftware. In dit artikel leggen we uit hoe je dit allemaal opzet. Zo heb je de basis voor een eigen mini-datacentrum.

 

Schema

In afbeelding 1 zie je een schema van Kubernetes. De master zorgt voor het neerzetten, verplaatsen en repliceren van applicaties over de verschillende hosts. Dat zijn de worker nodes, soms minions genoemd. Voor een nog robuuster systeem laat je de master op meerdere machines draaien, maar dat laten we hier buiten beschouwing.

Afbeelding 1: Schema van Kubernetes

 

Om applicaties te beheren, gebruikt Kubernetes software containers. In de praktijk zie je meestal Docker. Hierbij draait een applicatie met al zijn afhankelijkheden in een geïsoleerde omgeving. De container heeft geen kernel, maar draait verder onafhankelijk van de host en andere containers.

Eén of meerdere containers samen vormen een pod. Een pod bevat bij elkaar behorende applicaties, zoals een webserver met caching daemon. Kubernetes werkt op het niveau van pods. Als Kubernetes bijvoorbeeld een pod repliceert, weet je zeker dat alle bijbehorende applicaties gerepliceerd worden.

De master verplaatst pods, maakt nieuwe aan of verwijdert ze al naar gelang de load of beschikbaarheid van nodes. Daarom communiceer je niet rechtstreeks met een pod, maar via een service. Een service werkt als een proxy en regelt automatisch het verkeer naar de achterliggende pods.

 

Hardware

Voor ongeveer € 160,- koop je de volgende basisonderdelen voor een minicluster van drie Raspberry Pi’s:

•Raspberry Pi;

•Voeding;

•microSD-kaart;

•stack case.

 

We hebben gekozen voor de Raspberry Pi 3 Model B. Eén RPi fungeert als master en de andere twee als worker. De stack case maakt een compacte opbouw mogelijk. De micro SD-kaartjes hebben een capaciteit van 8 GB. Het besturingssysteem neemt circa 600 MB in beslag, waardoor je voldoende opslagruimte zal overhouden.

Je ziet hier per RPi een voeding. Er bestaan voedingen met meerdere USB poorten om alle bordjes ineens van stroom te voorzien. Dat maakt je cluster nog compacter. Let wel op dat je een voeding koopt die voldoende krachtig is. We raden aan om voor de zekerheid 2,5 ampère per RPi3 aan te houden.

 

Hypriotos

Voordat je alles in elkaar zet, plaats je eerst HypriotOS op elk microSD-kaartje. Dit besturingssysteem is gebaseerd op Raspbian en heeft Docker al aan boord. Ga naar de site (zie hiervoor de link aan het eind van het artikel) en download versie 1.1.0. Pak in de download-directory het bestand uit:

 

cd <download_directory>

unzip hypriotos-rpi-v1.1.0.img.zip

 

Vervolgens plaats je als root dit image op elk micro SD-kaartje. In ons geval is dat het device sdb (gebruik hiervoor bijvoorbeeld het commando lsblk):

 

dd bs=4M if=hypriotos-rpi-v1.1.0.img of=/dev/sdb

 

Let heel goed op welke device-naam je achter of= opgeeft. Het commando dd overschrijft zonder pardon elk device, ook je harde schijf! Het kopiëren van het image duurt enige minuten. Daarna zie je pas de uitvoer en is dd klaar. Omdat de standaard hostnaam hetzelfde is op alle bordjes, moet je zelf unieke hostnamen geven. Maak een tijdelijke directory aan en mount de eerste partitie van de micro SD-kaart. In dit voorbeeld is dat sdb1:

 

mkdir hypriotos

mount /dev/sdb1 hypriotos

 

Edit in de directory hypriotos het bestand device-init.yaml en zet in de regel met hostname een unieke naam. Wij kozen master-kube, worker-kube1 en worker-kube2. Forceer voor de zekerheid het wegschrijven van eventuele data in de cache naar het kaartje:

 

sync

 

Ontkoppel tenslotte het kaartje:

 

eject /dev/sdb

 

De bordjes krijgen via DHCP een IP-adres. Het beste is om vaste IP-adressen te gebruiken. Dit regel je bijvoorbeeld door op de DHCP-server van je router aan de hostnaam een statisch IP-adres te koppelen.

Schuif het micro SD-kaartje in de houder aan de onderkant van de RPi. Zorg dat de koperen stripjes van het kaartje naar het bordje wijzen. Monteer nu alle onderdelen, verbind de bordjes via een ethernetkabel met een switch en zet alle voedingen aan.

Tijdens de eerste boot voert HypriotOS enkele initiële acties uit. Onder andere rekt hij de root partitie op om de volledige ruimte van het micro SD-kaartje te benutten. Dat duurt zo’n twee minuten en dan is het systeem klaar voor gebruik.

 

Master

Log in op de master node via SSH. De standaard gebruikersnaam is pirate met wachtwoord hypriot:

 

ssh pirate@master-kube

 

Het project Kubernetes on ARM maakt de installatie van Kubernetes eenvoudig. Deze installeert overigens Kubernetes zelf ook in Docker containers, maar dat is geen vereiste. Wij gebruiken versie 0.8.0. Download het pakket docker-multinode.deb en installeer het (zie hiervoor listing 1). Vervolgens configureer en prepareer je het systeem voor Kubernetes:

 

sudo kube-config install

 

Dit is een interactief script. Bij de eerste vraag geef je het type bord op, in ons geval rpi-3. Bij de volgende vraag over het besturingssysteem antwoord je hypriotos. Vervolgens voert git een clone van een repository uit. Wacht totdat naar de hostnaam gevraagd wordt en tik master-kube in. Bij de tijdzone vul je Europe/Amsterdam in. Bij de volgende twee vragen druk je op enter. Bij de laatste vraag tik je n in, omdat een reboot voor HypriotOS niet nodig is.

Zet tot slot deze RPi als master op (listing 2). Er lijkt de eerste minuut niets te gebeuren, maar dan begint het downloaden en het installeren van allerlei componenten. Nu moet je geduld hebben, want het systeem is hier al gauw zo’n 10 tot 15 minuten zoet mee.

 

Workers

Haal op de master de lijst van containers op:

 

watch docker ps

 

Wacht totdat je onder COMMAND de hyperkube apiserver, scheduler, controller, proxy en kubelet ziet. Dit duurt een minuut. Voer dan pas bij de overige bordjes dezelfde acties uit als voor de master, behalve het commando van listing 2. Gebruik natuurlijk wel de juiste hostnamen. Als laatste zet je deze bordjes als worker op (listing 3). Het IP-adres <master_ip> vind je door: host master-kube. Via docker ps op een worker zie je maar twee containers: de hyperkube proxy en kubelet. Deze zijn vrijwel meteen actief.

 

Pod

Kubernetes heeft een webinterface op http://master-kube:8080/ui. In dit artikel gebruiken we echter het commando kubectl.

Ga naar de master en check of de workers gereed staan (listing 4). In de lijst zie je eerst de master met daaronder de workers. De STATUS moet Ready zijn. Gedetailleerde informatie over een node krijg je als volgt:

 

kubectl describe node 192.168.0.63

 

Installeer nu een docker image van Hypriot met een testwebserver (listing 5). Aan het eind van het artikel vind je ook nog een link naar andere images. De docker container gaat draaien in een pod met de naam mijn-httpd.

Haal een lijst met pods op (listing 6). Onder STATUS zie je dat de container nog gemaakt wordt. Na enkele tellen is dit klaar en dan toont dit commando hier Running. Door de optie –output=wide zie je onder NODE op welke worker de pod draait. Verifieer op deze worker door middel van docker ps dat daar inderdaad de webserver-container draait.

 

Service

In listing 6 zie je onder IP het IP-adres van de pod. De webserver is op dit adres binnen het cluster te benaderen, maar nog niet van buitenaf. Definieer daartoe een service (listing 7). Gebruik voor <master_ip> het IP-adres van de master. Nu gaat verkeer op poort 90 van de master naar poort 80 op de pod. De pod heet een endpoint voor deze service. In de lijst met services zie je mijn-httpd (listing 8). Informatie over de interne poort en IP-adres krijg je door:

 

kubectl describe service mijn-httpd

 

Ga nu met je browser naar http://master-kube:90 om de webpagina van de testserver op te halen.

 

Self-healing

Kubernetes herstelt zichzelf automatisch. Verwijder de ethernetkabel uit de worker waarop de webserver draait. Na 15 seconden verandert de status van deze worker in NotReady (listing 9). Refresh je webbrowser om te zien dat inderdaad geen verbinding met de webserver meer mogelijk is.

Na 5 minuten plaatst de master een pod met de webserver op de andere wel bereikbare worker (listing 10). Je ziet onder IP dat deze pod een ander intern IP-adres heeft (vergelijk met listing 6). Refresh je webbrowser nog een keer en de webpagina verschijnt weer. Merk hierbij op dat door de service van listing 7 het voor de buitenwereld niet uitmaakt op welke node of pod de webserver draait. Plaats daarna de ethernetkabel weer terug.

 

High availability

Eigenlijk wil je helemaal geen tijdelijk onbereikbare webserver. Laat daarom de webserver op beide workers tegelijk draaien (listing 11). Verifieer dit door middel van het commando uit listing 6. Verwijder de ethernetkabel van een worker en refresh je browser. Nu blijft de webpagina van afbeelding 3 zonder enige hapering zichtbaar. Na vijf minuten plaatst de master een nieuwe pod met webserver op de master zelf. Hij is dus tegelijkertijd worker. Sluit de ethernetkabel weer aan.

Om de master uit te sluiten van pods gebruik je het commando van listing 12. De STATUS in listing 4 toont nu Ready,SchedulingDisabled. De master verplaatst draaiende pods echter niet. Forceer dit door de pod op de master te verwijderen:

 

kubectl delete pod <naam>

 

Gebruik het commando uit listing 6 om onder NAME de juiste naam bij de master node vinden. De master initieert meteen een nieuwe pod op de worker om het aantal replica’s op peil te houden.

 

Afsluiten

Kubernetes on ARM heeft systemd services op de roadmap staan. Momenteel moet je daarom handmatig afsluiten. Doe dit eerst op de workers:

 

sudo kube-config disable

 

Antwoord n op de vraag om de cache /var/lib/kubelet te schonen. Tot slot doe je hetzelfde op de master.

Om het cluster weer op te starten, gebruik je eerst op de master het commando van listing 2 en vervolgens op de workers dat van listing 3. Ook dan tik je n in bij de vraag over het schonen van de cache. Het opstarten verloopt nu veel sneller dan de installatie. Dit komt omdat alle software al klaar staat.

 

Tot slot

Nu draait je eigen rekencluster met cloudomgeving. Naar eigen inzicht pas je het aan, installeer je andere docker images of voeg je externe storage toe. En mocht het cluster overbelast raken, dan plaats je een extra RPi met Kubernetes worker. Zonder interruptie schalen, net als in een datacentrum!

 

Listings

 

LISTING 1

wget https://github.com/luxas/kubernetes-on-arm/releases/download/v0.8.0/docker-multinode.deb

sudo dpkg -i docker-multinode.deb

 

LISTING 2

sudo kube-config enable-master

 

LISTING 3

sudo kube-config enable-worker <master_ip>

 

LISTING 4

kubectl get nodes

NAME            STATUS    AGE

192.168.0.102   Ready     28m

192.168.0.63    Ready     7m

192.168.0.84    Ready     6m

 

LISTING 5

kubectl run mijn-httpd –image=hypriot/rpi-busybox-httpd

 

LISTING 6

kubectl get pods –output=wide

NAME                         READY STATUS            …  IP        NODE

mijn-httpd-4018314304-f4izn  1/1   ContainerCreating …  10.1.55.2 192.168.0.84

 

LISTING 7

kubectl expose deployment mijn-httpd –port=90 –target-port=80 –external-ip=<master_ip>

 

LISTING 8

kubectl get services

NAME         CLUSTER-IP   EXTERNAL-IP    PORT(S)   AGE

mijn-httpd   10.0.0.171   192.168.0.102  90/TCP    21s

 

LISTING 9

kubectl get nodes 192.168.0.84

NAME           STATUS     AGE

192.168.0.84   NotReady   1h

 

LISTING 10

kubectl get pods –output=wide

NAME                         READY STATUS  …  IP        NODE

mijn-httpd-4018314304-q03iq  1/1   Running …  10.1.59.2 192.168.0.63

 

LISTING 11

kubectl scale –replicas=2 deployment/mijn-httpd

 

LISTING 12

kubectl patch node <master_ip> -p ‘{“spec”: {“unschedulable”: true}}’

 

Links

Kubernetes 

Docker 

HypriotOS 

Kubernetes on ARM 

Docker images