La fondation Raspberry a annoncé en mai 2020 une nouvelle version de la Raspberry Pi 4 disposant de 8 Go de RAM : de quoi faire tourner de nombreuses applications, donc Kubernetes et Cyberwatch !
Dans cet article, nous allons voir :
- comment compiler des images de conteneurs pour qu’elles fonctionnent sur une architecture ARM ;
- comment installer Kubernetes sur un Raspberry Pi 4B ;
- comment déployer des images ARM sur une instance Kubernetes déployée sur un Raspberry Pi 4B.
Prérequis
Nous utiliserons ici un Raspberry Pi 4B avec 8 Go de RAM, sur lequel est installé le système d’exploitation Raspberry Pi OS en version 64 bits. Pour vérifier que votre Raspberry Pi est bien en architecture 64 bits, vous pouvez lancer la commande :
dpkg --print-architecture
Le résultat attendu est :
arm64
Comment compiler des images Docker pour une architecture ARM ?
Pour compiler les images pour notre architecture arm64
, nous allons utiliser l’extension buildx
de la ligne de commande de docker
.
Cette extension offre une interface relativement similaire à la commande docker build
en ajoutant la possibilité de compiler pour d’autres architectures que celle de l’hôte ou sur plusieurs noeuds en parallèle.
La première étape pour utiliser buildx
est de créer un builder
configuré pour compiler les images pour l’architecture arm64
.
En anticipation, nous ajoutons la configuration d’un futur registre Docker local via le fichier config.toml
dont le contenu est (remplacer <IP
>
par l’adresse IP de votre machine vue par le Raspberry Pi) :
[registry."<IP>:5000"]
insecure = true
Créer un builder
:
docker buildx create --name armbuilder --platform linux/arm64 --config config.toml --use
Pour que les images puissent être téléchargées sur le Raspberry Pi, nous allons ensuite les pousser sur un registre local après leur compilation.
Pour cela, nous créons d’abord un certificat auto-signé avec la commande suivante (remplacer <IP
>
par l’adresse IP de votre machine vue par le Raspberry PI) :
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout registry.key -out registry.crt -subj "/CN=registry.dev" \
-addext "subjectAltName=IP:<IP>"
Puis nous créons le registre local avec la commande suivante :
docker run -d --privileged --restart=always --name registry -v $(pwd):/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key -p 5000:5000 registry:2
Enfin, nous allons compiler les différentes images pour l’architecture ARM64. Nous prendrons comme exemple une image nginx
utilisée par Cyberwatch.
Pour générer l’image nginx
pour la plateforme arm64
, nous lançons la commande :
docker buildx build --platform linux/arm64 . -t <IP_REGISTRY>:5000/nginx:latest --push
L’image est alors compilée puis poussée sur le registre local.
Nous reproduisons la même commande pour toutes les images utilisées par Cyberwatch, avec les points d’attention suivants :
1. Toutes les images utilisées dans le Dockerfile avec le mot-clé FROM doivent elles-aussi être compilées pour l’architecture ARM64.
2. Il est possible que certaines étapes de la compilation ne fonctionnent pas en raison d’incompatibilité avec l’architecture ARM64 pour certains outils ou certaines dépendances. Il faut alors trouver des alternatives.
3. Enfin, une erreur fréquente lors de la compilation des images indique que l’exécuteur ne parvient pas à se lancer, avec le message :
error: failed to solve: rpc error: code = Unknown desc = executor failed running [/dev/.buildkit_qemu_emulator /bin/sh -c apt-get update && apt-get install -y --no-install-recommends make]: exit code: 100
Dans ce cas, il suffit de remettre à zéro l’émulateur avec la ligne de commande :
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
Comment installer Kubernetes sur la Raspberry Pi ?
Nous allons installer Microk8s, un déploiement de Kubernetes complet, léger et adapté à la fois à un contexte de production et à un contexte de développement, maintenu par Canonical, l’entreprise derrière Ubuntu. Microk8s a aussi l’avantage de supporter l’architecture arm64
.
Avant d’installer Microk8s, il faut activer les c-groups dans la configuration du noyau. Après s’être connecté en SSH sur le Raspberry Pi, éditer le fichier de configuration /boot/firmware/cmdline.txt
peut aussi s’appeler /boot/cmdline.txt
).
Dans le fichier en question, ajouter les options suivantes au début de la ligne :
cgroup_enable=memory cgroup_memory=1
Sauvegarder le fichier puis redémarrer le Raspberry Pi avec sudo reboot
.
Nous pouvons maintenant installer Microk8s, avec la commande :
sudo snap install microk8s --classic
Pour en savoir plus sur l’utilisation de Microk8s, se référer à la documentation officielle.
Comment déployer des images ARM sur une instance Kubernetes déployée sur un Raspberry Pi ?
Maintenant que nous disposons d’un cluster Kubernetes fonctionnel, nous pouvons déployer nos images. Voyons comment déployer l’image nginx
compilée précédemment.
Créer un nouveau fichier nginx.yml
sur le Raspberry Pi contenant la configuration d’un pod utilisant l’image nginx
(remplacer <IP>
par l’adresse IP du registre) :
export REGISTRY_IP=<IP>
cat <<EOF >nginx.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: $REGISTRY_IP:5000/nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
Déployer ensuite la configuration sur le cluster avec la commande :
microk8s kubectl apply -f nginx.yml
Enfin, vérifier l’état du pod avec la commande :
microk8s kubectl get pods
Vous obtenez ainsi un pod opérationnel avec l’image nginx, le tout sur votre Raspberry Pi ! La même approche peut alors être généralisée pour l’ensemble des images de Cyberwatch.