Saltar al contenido principal

GitLab Runner

Las herramientas de CI/CD tienden a revisar si hay cambios en un repositorio para iniciar el proceso, siendo Jenkins el más conocido.

Con el tiempo varios servicios de repositorio de código se han impuesto a otros, y han incorporado varias utilidades dentro de sus propios sistemas como el CI/CD. Actualmente entre los más grandes encontramos:

RepositorioCI/CD
GitHubGitHub Actions
GitLabGitLab Runner
BitbucketBamboo

En mi caso utilizo GitLab, con lo que mi herramienta es GitLab Runner.

Las principales características de GitLab Runner son:

  • El proceso por realizar en el CI/CD se configura directamente en el proyecto, así que los desarrolladores tienen acceso total a este.
  • La gestión de variables, logs, artefactos y resultados se muestra directamente en el repositorio de GitLab.
  • Cada etapa se ejecuta dentro de un contenedor, el código es copiado en él y se ejecutan las ordenes indicadas. Esto significa que prácticamente no tiene limitaciones.
  • Un único runner se puede configurar para iniciar varias estancias de sí mismo y se puede configurar para uno o varios proyectos.

GitLab dispone de Runner públicos que pueden ser utilizados, pero por temas de seguridad es preferible tener uno propio. Además, al desplegarlo en una red privada, tendrá acceso a los servicios de la Intranet.

Configuración de proyecto

Un proyecto nuevo en GitLab no utiliza un Runner privado por defecto, requiere de ser configurado acorde a:

  • Proyecto: Disponible únicamente para el proyecto. En el proyecto: Settings - CI/CD - Runners.
  • Grupo: Disponible para los proyectos en el grupo. En el grupo, Settings - CI/CD - Runners.
  • Global: Todos los proyectos lo pueden utilizar. Únicamente disponible en versiones instaladas, no en la cloud. En Admin Area - Runner.

En cada sección se encuentra el código de registro que será necesario en la configuración.

info

Debido a que un Runner puede ejecutar múltiples instancias, es más eficiente tener pocos y configurados a muchos proyectos o a nivel global.

Además, los Runner pueden tener tags que limiten su uso a los proyectos que coincidan con esos tags.

Instalación

Debido a que GitLab Runner desplegará múltiples contenedores que podrían no ser tan seguros como se esperaría, es preferible desplegarlo en un servidor dedicado, sin clúster.

En este caso utilizo Docker como gestor de contenedores.

Desactivar SWAP

Este servidor no necesitará la swap, así que se desactiva.

sudo swapoff -a
sudo vi /etc/fstab

Borramos la línea de swap y eliminamos el fichero para ahorrar espacio.

sudo rm /swap.img

Docker

Podemos hacer la instalación para entornos de producción o la simple a partir del script preparado por el equipo de Docker. Como este entorno únicamente será para el Runner, es factible utilizar el script.

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Repositorio SSL

Si disponemos de Nexus Repository o cualquier otro repositorio de contenedores, es posible que el certificado de SSL sea auto firmado. Docker requiere que indiquemos el certificado para confirmar cualquier dominio al que se tenga que conectar.

Creamos las carpetas para el uso del repositorio privado y para el público.

sudo mkdir -p /etc/docker/certs.d/docker-private.domain.intranet
sudo mkdir /etc/docker/certs.d/registry.domain.intranet

Dentro debemos añadir el certificado ( crt ) utilizado para validar la comunicación.

GitLab Runner

Runner funcionará como otro contenedor más en Docker.

Volumen

Cada Runner requiere un volumen para almacenar su configuración y otro para la caché, pero desviaremos la caché hacia MinIO, así que ese volumen no será necesario.

sudo docker volume create runner1

Antes de iniciar el contenedor, creamos el fichero de configuración que después ajustaremos con más datos.

Registro

sudo docker run --rm -it -v runner1:/etc/gitlab-runner registry.domain.intranet/gitlab/gitlab-runner register
info

Docker por defecto recupera las imágenes de Docker Hub, si queremos que utilice nuestro repositorio lo deberemos indicar. Esto también sucede para los contenedores indicados en el fichero de CI/CD.

En la configuración de cada repositorio, grupo o instancia de GitLab se indica la URL y el token que debemos utilizar para la configuración.

Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.com/
Enter the registration token:
<token_code>
Enter a description for the runner:
[000000000]: Runner1
Enter tags for the runner (comma-separated):
runner1,docker
Enter optional maintenance note for the runner:

Registering runner... succeeded runner=XXXXXXXXXXXXX

Enter an executor: kubernetes, docker, parallels, shell, ssh, virtualbox, docker-ssh+machine, custom, docker-ssh, docker+machine:
docker
Enter the default Docker image (for example, ruby:2.7):
registry.domain.intranet/docker:stable
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"

Caché con SSL

Cuando un Runner conecta a la caché u otros servicios, lo hace a partir de un helper. Si el servicio accede a servicios con certificados no válidos, este deberá tener la información para poder acceder.

Con un MinIO en la intranet, lo normal es que su certificado no sea válido, así que tenemos que construir un helper que disponga de nuestro certificado.

Definimos el contenido de la nueva imagen.

vi Dockerfile_runner_helper

Partiendo del helper original de GitLub Runner, le incluimos nuestro certificado.

Dockerfile_runner_helper
FROM registry.domain.intranet/gitlab/gitlab-runner-helper:x86_64-latest
RUN apk add --no-cache ca-certificates
COPY wildcard.domain.intranet.crt /usr/local/share/ca-certificates/ca.crt
RUN update-ca-certificates
RUN rm /usr/local/share/ca-certificates/ca.crt
tip

Este proceso copiará el fichero crt dentro del contenedor, para eso el fichero debe existir en la misma carpeta que el Dockerfile.

Creamos la imagen y la subimos a nuestro repositorio, necesitaremos un usuario y contraseña con acceso al repositorio.

sudo docker build -f Dockerfile_runner_helper -t docker-private.domain.intranet/internal/gitlab-runner-helper:x86_64-latest .
sudo docker login -u DOCKER_USER -p DOCKER_PASSWORD https://docker-private.domain.intranet
sudo docker image push docker-private.domain.intranet/internal/gitlab-runner-helper:x86_64-latest

Configuración

Seguimos con la configuración.

sudo vi /var/lib/docker/volumes/runner1/_data/config.toml

Este fichero tiene principalmente la primera sección donde podemos configurar el número de instancias del mismo Runner que se pueden ejecutar en paralelo y la configuración de cada proyecto, que está definida en [[runners]].

Lo primero es aumentar el número de instancias.

/var/lib/docker/volumes/runner1/_data/config.toml
concurrent = 6

El fichero contendrá la configuración del proyecto que hemos creado, pero hay que actualizarlo acorde a la caché de MinIO,

/var/lib/docker/volumes/runner1/_data/config.toml
[[runners]]
[runners.cache]
Type = "s3"
Shared = true
[runners.cache.s3]
ServerAddress = "minio.domain.intranet:443"
AccessKey = "<accessKey>"
SecretKey = "<secretKey>"
BucketName = "<buckerName>"
Insecure = false
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
helper_image = "registry.domain.intranet/internal/gitlab-runner-helper:x86_64-latest"
tip

El helper_image únicamente es necesario si conectamos a la caché de MinIO con certificado no válido.

El resto de los datos se dejan tal como están.

Desplegar

Tras configurar cada repositorio que necesitamos, iniciamos el contenedor.

sudo docker run -d --name runner1 --restart always \
-v runner1:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
registry.domain.intranet/gitlab/gitlab-runner:latest

Configuración de repositorio

Si el contenedor se ha iniciado correctamente, en la pantalla de Runners de cada proyecto donde ha sido configurado se mostrará el nombre de nuestro Runner.

Aunque el Runner esté asignado a un grupo o proyecto, únicamente se activa si el CI/CD utiliza uno de los tags definidos en el Runner. En caso de querer que se active siempre, hay que acceder a su configuración desde GitLab y seleccionar el siguiente campo:

Run untagged jobs: Indicates whether this runner can pick jobs without tags