Configurar gitlab-runner usando executor virtualbox

2022/09/05

Objetivo

Se busca configurar la funcionalidad de CI/CD de una instancia de gitlab community edition (self-managed).

Para ello debe agregarse por lo menos un runner que es una aplicación utilizada por gitlab CI/CD para ejecutar las tareas en un pipeline.

Al registrar un runner en gitlab se debe elegir un executor el cual determina el ambiente en el que cada trabajo es ejecutado.

Actualmente estoy utilizando el shell executor el cual tiene como ventajas la facilidad de configuración, pero como contra que los trabajos tienen acceso al servidor en que está instalado el runner el cual está compartido con otros servicios.

Se descartó utilizar el docker executor ya que requiere tener instalado docker y no funciona con podman (el cual está instalado en el equipo al cual se agregará el servicio de runner).

De las alternativas restantes, se intentará utilizar el executor virtualbox por la característica de proveer un entorno limpio para cada build y no tener problemas de que las tareas que se ejecuten accedan a los datos del servidor.

Una vez elegido virtualbox, hay que elegir la imagen a utilizar y la forma de configurarla. Ya que los proyectos que desean agregarse al pipeline de CI/CD deben generar imagenes de contenedores utilizando archivos con formato Dockerfile y teniendo en cuenta que podman, mediante su subcomando machine utiliza por defecto la distribución Fedora CoreOS se intentará utilizar esta.

Respecto a Fedora CoreOS o FCOS, parte de su filosofía radica en distribuir una imagen genérica mínima la cual deberá aprovisionarse en el primer inicio (first boot) utilizando ignition. ignition utiliza un archivo en formato json para realizar el aprovisionamiento durante la etapa de initramfs. Hay que notar que la forma recomendada de generar un archivo para ignition es usando butane, el cual requiere que se escriba la configuración en formato yaml que luego es validada por butane y convertida a json. Por otro lado, ya que utilizaremos virtualbox como virtualizador se aprevechará que ignition permite utilizar las virtualbox guest properties para cargar la información de aprovisionamiento. Como ejemplo conviene seguir la guía de aprovisionamiento en virtualbox. Por defecto FCOS contiene git y podman, que son las herramientas que utilizamos para generar los build y ssh para que gitlab-runner se conecte, por lo cual la imagen cumple con los requerimientos de gitlab-runner.

Por último, se configurará gitlab-runner para usar la imágen de virtualbox basada en FCOS.

NOTA: gitlab-runner es ejecutado con root por defecto y el executor virtualbox utiliza el usuario root para ejecutar virtualbox, por lo que el usuario en el cual se instala la máquina virtual debe ser root

Setup de proyecto de prueba

Antes de instalar gitlab-runner y configurar el executor (lo que implica crear y configurar una máquina virtual) hay que crear un proyecto (repositorio git en la instancia de gitlab) al cual se le registrará el runner.

A continuación se describe el contenido de un proyecto sencillo y representativo que se puede utilizar para probar el runner. Esperamos que el proyecto:

Para probar lo anterior utilizaremos solo dos archivos:

Para registrar un runner (obtener el token para registrarlo) se debe ir a Settings (del proyecto) > CI/CD, expandir la sección Runners y extraer los datos bajo Specific runners: la url de la instancia de gitlab y el token para registrarse. Estos valores se utilizarán más adelante.

Instalar gitlab-runner

Para instalar el runner se siguen las indicaciones dadas en Install GitLab Runner using the official GitLab repositories

Preparación de imágen basada en FCOS

Creación de configuración de FCOS

Se escribe la configuración en butane con las siguientes características:

Para realizar lo anterior se utiliza el script gen-ignition.sh que además:

Nota: para un correcto funcionamiento del script hay que tener instalado el paquete pwgen (doas apt-get install -Vy pwgen) y el ejecutable de butane (wget -O butane 'https://github.com/coreos/butane/releases/download/v0.15.0/butane-x86_64-unknown-linux-gnu' && doas install butane /usr/local/bin).

La ejecución se realiza utilizando el comando:

$ doas ./gen-ignition.sh gitlab-runner
ignition config file: /root/VirtualBox Vms/gitlab-runner/gitlab-runner.ign
file with pass for user github-runner: /root/VirtualBox Vms/gitlab-runner/user_gitlabrunner.pass
file to connect with core user: /root/VirtualBox Vms/gitlab-runner/user_core.cert

Done

Creación de la VM

Se comienza descargando la imagen estable para virtualbox en el directorio /tmp:

$ wget -P /tmp https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/36.20220806.3.0/x86_64/fedora-coreos-36.20220806.3.0-virtualbox.x86_64.ova

Para crear la vm se utiliza el script prepare-vm.sh. Este script, aparte de importar la vm realiza las siguientes tareas:

$ doas ./prepare-vm.sh gitlab-runner
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting /tmp/fedora-coreos-36.20220806.3.0-virtualbox.x86_64.ova...
OK.
Disks:
  vmdisk1	10737418240	816268288	http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized	disk.vmdk	816268288	-1

Virtual system 0:
 0: Suggested OS type: "Fedora_64"
    (change with "--vsys 0 --ostype <type>"; use "list ostypes" to list all possible values)
 1: VM name specified with --vmname: "gitlab-runner"
 2: Suggested VM group "/"
    (change with "--vsys 0 --group <group>")
 3: Suggested VM settings file name "/root/VirtualBox Vms/Fedora CoreOS stable/Fedora CoreOS stable.vbox"
    (change with "--vsys 0 --settingsfile <filename>")
 4: Suggested VM base folder "/root/VirtualBox Vms"
    (change with "--vsys 0 --basefolder <path>")
 5: Product (ignored): fedora-coreos Fedora CoreOS stable
 6: Vendor (ignored): fedora-coreos
 7: Version (ignored): 36.20220806.3.0
 8: Number of CPUs: 2
    (change with "--vsys 0 --cpus <n>")
 9: Guest memory: 4096 MB
    (change with "--vsys 0 --memory <MB>")
10: USB controller
    (disable with "--vsys 0 --unit 10 --ignore")
11: Network adapter: orig NAT, config 6, extra slot=0;type=NAT
12: SATA controller, type AHCI
    (disable with "--vsys 0 --unit 12 --ignore")
13: Hard disk image: source image=disk.vmdk, target path=disk.vmdk, controller=12;port=0
    (change target path with "--vsys 0 --unit 13 --disk path";
    change controller with "--vsys 0 --unit 13 --controller <index>";
    change controller port with "--vsys 0 --unit 13 --port <n>";
    disable with "--vsys 0 --unit 13 --ignore")
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Successfully imported the appliance.

Paso seguido se inicia la vm para que aplique la configuración:

$ doas vboxmanage startvm gitlab-runner --type headless
Waiting for VM "gitlab-runner" to power on...
VM "gitlab-runner" has been successfully started.

Podemos verificar el estado de la configuración y si esta terminó inspeccionando la salida de la consola que se configuró previamente:

$ doas tail -f "/root/VirtualBox Vms/gitlab-runner/gitlab-runner.log"

Para loguearnos con el usuario core utilizamos el certificado:

$ doas ssh -i "/root/VirtualBox Vms/gitlab-runner/user_core.cert" -p 2222 core@localhost
The authenticity of host '[localhost]:2222 ([127.0.0.1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:Qunkm7ADQbMOixsKPLwbZeATETdfr9+jSgz4Fk8OUhg.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2222' (ED25519) to the list of known hosts.
Fedora CoreOS 36.20220806.3.0
Tracker: https://github.com/coreos/fedora-coreos-tracker
Discuss: https://discussion.fedoraproject.org/tag/coreos

[core@gitlab-runner-vm ~]$

Y paso seguido apagamos la vm:

[core@gitlab-runner-vm ~]$ sudo shutdown -h now
Connection to localhost closed by remote host.
Connection to localhost closed.

Para verificar que apagó correctamente utilizamos:

$ doas vboxmanage showvminfo gitlab-runner | grep -i state
State:                       powered off (since 2022-09-27T17:01:30.000000000)

Configuración y pruebas de gitlab-runner

Para registrar el runner se siguen las indicaciones de Non-interactive registration.

$ export CI_SERVER_URL='https://url/to/my/instance'
$ export REGISTRATION_TOKEN='my-registration-token'
$ export SSH_PASSWORD='ohphei3op+oh5NuDophei&W4zooDahquaiNgohr9gah=b3eini#k,ai6wei/weij'
$ doas gitlab-runner register --non-interactive --url "$CI_SERVER_URL" --registration-token "$REGISTRATION_TOKEN" --executor virtualbox --virtualbox-base-name gitlab-runner --ssh-user gitlab-runner --ssh-password "$SSH_PASSWORD"
Runtime platform                                    arch=amd64 os=linux pid=1154947 revision=bbcb5aba version=15.3.0
Running in system-mode.

Registering runner... succeeded                     runner=XXXXXXXX
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"

Nota: Sobre las variables de entorno: aquí se utilizan para que no quede en la linea de comandos información sensible y son las variables utilizadas por gitlab-runner en la opción de linea de comando correspondiente. Como se está utilizando doas y este “limpia” las variables de entorno (alcanza para probar hacer doas printenv) es que se reintroducen utilizando parámetros.

Conclusiones

Apendice - Cambiar directorio ~/VirtualBox VMs

Sin tener máquinas virtuales creadas o con todas las máquinas virtuales apagadas

$ vboxmanage setproperty machinefolder $HOME/virtualbox-vms

Para verificar el cambio utilizar

$ vboxmanage list systemproperties | grep folder

Fuente: https://askubuntu.com/questions/800824/how-to-change-virtualbox-default-vm-location-in-command-line