❓ Un runner ?
L'intégration continue de GitLab, plus connue sous le nom de GitLab CI fonctionne avec des runners qui exécutent les pipelines que vous décrivez dans vos projets. Sur gitlab.com, GitLab met à disposition des runners avec cependant une limitation en termes d'utilisation voir ici.
Les runners, développés en Go, peuvent être installés sur n'importe quelle structure que ce soit sur le cloud ou chez vous de façon à avoir totalement la main sur leurs configurations.
🤷♂️ Pourquoi un Raspberry PI ?
Depuis quelques années, j'ai un projet perso sur GitLab qui me sert de "cobaye", dans le sens où il subit mes différentes tentatives de manipulation de langages, framework ou divers outils sur des cas d'utilisation sortant du contexte d'un simple "hello world". Et le raspberry est une solution simple et pas chère pour pouvoir tester cela.
Après avoir acheté un raspberry pour y installer de la domotique, me voilà parti dans l'achat d'un autre raspberry où j'ai pu déployer k3s, une distribution Kubernetes très légère et adaptée aux machines ayant peu de mémoire. Pour une infrastructure ARM telle un raspberry, c’est l’idéal. Lorsque j'ai voulu générer mon application pour cette structure ARM, j'ai sollicité fortement les runners jusqu'à arriver à recevoir des alertes sur la consommation élevée de runners GitLab.
Alors pourquoi pas essayer tout simplement d'installer mon propre runner sur un raspberry ?
🏠 Mon raspberry PI
Je suis parti sur l'achat de la dernière version de raspberry, un Raspberry Pi 4 Modèle B 8 Go Kit avec une carte SD de 64 Go disponible à 135,99 euros sur Amazon.
Après avoir installé la dernière version de Debian (la carte SD était déjà configurée, dans le cas contraire vous pouvez aller sur ce site pour avoir la procédure à suivre), l'installation du runner GitLab peut être effectuée.
🚀 Installation du runner
L'installation se fait rapidement après avoir téléchargé le bon package armhf
curl -L0 debian gitlab-runner-armhf https://s3.amazonaws.com/gitlab-runner-downloads/master/deb/gitlab-runner_armhf.deb
puis exécuter le fichier d'installation (après avoir donné les droits suffisant) :
sudo apt install -y gitlab-runner-armhf
A partir de là, la commande gitlab-runner
est disponible :
🐳 Installation de docker
Comme je me base sur un exécuteur docker, j'ai également dû installer docker sur mon raspberry, ce qui se fait rapidement avec ces commandes :
sudo apt-get update && sudo apt-get upgrade
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker pi
Pour que la modification soit prise en compte, vous devez recharger le shell ou vous déconnecter/reconnecter à votre raspberry. La bonne installation de docker peut se vérifier en récupérant la version via la commande docker version
et en exécutant une image , par exemple hello-world via cette commande docker pull hello-world
qui doit renvoyer cela :
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(arm32v7)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Cette image est souvent citée pour vérifier son environnement, qu'il soit sous Windows, Linux, Mac ou ARM. Cette image est multi-plateformes et cela peut se vérifier sur le Docker Hub ou avec la commande
docker inspect hello-world
.
pi@raspberrypi:~ $ docker inspect hello-world | grep 'Architecture'
"Architecture": "arm",
💾 L'enregistrement du runner
Une fois le gitlab-runner créé, un lien entre votre runner et un projet GitLab existant est nécessaire. Pour cela,
il suffit de lancer la commande
sudo gitlab-runner register
L'exécutable vous proposera de saisir :
- l'url de votre instance GitLab
- le token de votre projet, disponible dans Settings > CI/CD > Runners où vous pouvez trouver le token d'enregistrement
- un tag associé à votre runner
- un exécuteur où il est courant d'utiliser docker. Dans ce cas l'image par défaut pour exécuter votre CI vous sera demandée.
📝 Plus de docs sur le site de GitLab : Doc GitLab
⚙️ La configuration de votre runner
Pour que votre CI utilise votre runner, vos scripts de CI doivent être modifiés pour indiquer le nom du tag de votre runner :
stages:
- build
my-job:
stage: build
tags: ["runner-pi"] # le tag associé à votre runner défini lors de l'enregistrement de votre runner
image:
name: golang:alpine
script:
- go mod download
- go get -d -v
- GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
Pour vérifier que votre pipeline a bien utilisé votre runner, il est possible de voir sur un job le runner utilisé :
🪛 Customisation du runner
Le fichier config.toml
La configuration du gitlab-runner est stockée dans le fichier /etc/gitlab-runner/config.toml
. Par défaut le nombre de job exécuté en parallèle est de 1. Vous pouvez modifier cette valeur dans la première ligne du fichier et passer la variable concurrent
à 4 par exemple.
Le swap
Une autre découverte (merci Guillaume), c'est autour du swap du raspberry. Cet espace de mémoire est de base initié à 100MB et il est préconisé par GitLab de monter à 4GB de swap. A prendre avec précaution car une forte charge du swap peut tout simplement ruiner votre carte SD.
En tout cas, pour faire l'upgrade de votre swap, il suffit de :
- arrêter votre swap :
sudo dphys-swapfile swapoff
- ouvrir le fichier de configuration du swap :
sudo vi /etc/dphys-swapfil
- modifier la valeur du paramètre swap :
CONF_SWAPFILE
avec la valeur que vous désirez en MB (je suis resté à 2048 MB). - démarrer le swap :
sudo dphys-swapfile swapon
Kaniko
Dans mes pipelines GitLabCI, j'utilise habituellement l'outil Kaniko pour builder et pusher mes images dans un registry.
Sur Raspberry, l'exécution d'image Kaniko n'est pas possible malgré la prise en compte d'image taggée arm. A l'heure où j'écris cet article, trois issues évoquent ce problème :
- https://github.com/GoogleContainerTools/kaniko/issues/1591
- https://github.com/GoogleContainerTools/kaniko/issues/1587
- https://github.com/GoogleContainerTools/kaniko/issues/1488
Pour pallier à cela, je me suis basé sur les commandes Docker :
- docker login -u gitlab-ci-token -p $CI_SECRET registry.gitlab.com
- docker build -t registry.gitlab.com/<le nom de votre image>:$CI_COMMIT_BRANCH -f $CI_PROJECT_DIR/Dockerfile .
- docker push registry.gitlab.com/<le nom de votre image>:$CI_COMMIT_BRANCH
où :
- $CI_SECRET est une variable définie dans les paramètres de votre projet (Settings > CI/CD > Variables).
📝 Edit : suite à des échanges avec Philippe Charrière, Kaniko fonctionne correctement avec un raspberry PI basé sur une image Ubuntu.
Et voilà, votre runner GitLab est disponible sur votre raspberry et votre projet GitLab y est relié, il ne reste plus qu'à vous amuser avec 🚀 💪.