Ir al contenido
  1. Posts/

Como Configurar y Utilizar GitLab Runner Self-Hosted

·1508 palabras·8 mins· loading · loading ·
GitLab DevOps gitlab runner ci devops
Autor
Enmanuel Moreira
Ingeniero DevOps de día y aprendiz de Barman en mis tiempos libres, con experiencia en Kubernetes, Cloud, y DevOps. También disfruta de hacer stream de juegos, hablar de CI/CD, desplegar en producción un viernes con Terraform y automatizar tareas aburridas con Ansible.

GitLab Runner es una instancia que nos permite ejecutar nuestros jobs utilizando múltiples máquinas (físicas o virtuales) y que enviarán los resultados a GitLab. Si no quiséramos hacer uso de los runners compartidos proporcionados por GitLab (los cuales tienen un límite de 400 minutos por mes), podemos instalar uno o varios runners en nuestra infraestructura para que se hagan cargo de todo el proceso de CI de nuestros desarrollos.

PROMO DigitalOcean
#

Antes de comenzar, quería contarles que hay una promoción en DigitalOcean donde te dan un crédito de USD 200.00 durante 60 días para que puedas probar los servicios que este Proveedor Cloud ofrece. Lo único que tienes que hacer es suscribirte a DigitalOcean con el siguiente botón:

DigitalOcean Referral Badge

O a través del siguiente enlace: https://bit.ly/digitalocean-itsm

Prerequisitos
#

Creando un Grupo en GitLab
#

Primero creamos un grupo para almacenar los repositorios o proyectos que van a hacer uso de nuestros Runners, en la pantalla principal de GitLab, vamos a la semi esquina superior derecha:

Crear Grupo

Creamos el nuevo grupo:

Crear Grupo
Crear Grupo

Lo vamos a llamar GitLab Runner Example para simplificar este ejemplo:

Nuevo Grupo
Nuevo Grupo

Deshabilitar Runners Compartidos
#

Para que los trabajos puedan ser asignados a nuestro Runner propio y no usar los compartidos de GitLab, debemos deshabilitar estos últimos.

Vamos al menú de la izquierda y buscamos en Configuración la opción CI/CD:

Menu CI/CD

Expandimos la opción Variables, y deshabilitamos la opción que dice: Enable shared runner for this group

Menu CI/CD
Menu CI/CD

Obteniendo un Token de Registro
#

El Token de registro lo vamos a necesitar para poder registrar valga la redundancia, nuestro Runner. Para esto, Vamos a ir al menú de la izquierda y buscamos en CI/CD la opción Runners:

Menu Runners
Menu Runners

Copiamos y reservamos el Token para poder registrar nuestro Runner:

Runner Token
Runner Token

Instalando Nuestro Runner
#

Ya con el Token de Registro en mano, procedemos a instalar nuestro Runner. Si tenemos Docker instalado, lo podremos configurar de manera sencilla, en caso que aún no tengas instalado Docker, ya lo hablé en el artículo Como Instalar Docker en Linux

Consideración de Seguridad: Es altamente recomendable ejecutar GitLab Runner en una máquina física o virtual aislada, ya que vamos a montar como un volumen el socket de Docker y darle permisos de root a la ejecución de nuestros jobs, por lo que no instales un runner en tu máquina propia o personal para tal fin.

Ya con Docker en funcionamiento, procedemos a ejecutar GitLab Runner:

docker run -d --name nombre-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:alpine-v15.11.0

Si utilizaramos Docker Compose:

version: '3.9'
services:
  gitlab-runner:
    container_name: nombre-runner
    image: 'gitlab/gitlab-runner:alpine-v15.11.0'
    restart: always
    volumes:
      - '/srv/gitlab-runner/config:/etc/gitlab-runner'
      - '/var/run/docker.sock:/var/run/docker.sock'

Levantamos el servicio con:

docker compose up -d

La versión actual a la fecha es la v15.11.0 por lo que puedes ir viendo las versiones existentes en el Repositorio Oficial de GitLab

Utilizamos la version Alpine ya que es la que tiene menor tamaño, sin embargo, también hay imágenes basadas en Debian y Ubuntu.

Expliquemos un poco los argumentos:

  • --name nombre-runner: Es el nombre que le vamos a dar a nuestro contenedor. Debe ser diferente si configuramos otro runner.
  • --restart always: Para que nuestro contenedor se reinicie siempre en caso de que se cierre por algún error e inicie de manera automática con nuestro sistema.
  • -v /srv/gitlab-runner/config:/etc/gitlab-runner: Aquí le indicamos donde va a estar nuestro archivo de configuración, la primera ruta es donde se va a almanecenar en nuestra máquina local, y la segunda después del signo : es donde va a ir dentro del contenedor. En caso de levantar otro runner, hay que especificar un nombre de archivo diferente en el host (como config-runner2, etc.)
  • -v /var/run/docker.sock:/var:run/docker.sock: Montamos como un volumen el socket de Docker del host en el contenedor para que pueda ejecutar trabajos como Docker In Docker: Ejecutar comandos de Docker, construir imágenes, etc.

Registrando el Runner
#

Con este proceso vamos a vincular nuestro runner recién instalado a GitLab y pueda recibir trabajos de CI. Podemos registrar multiples runner en la misma máquina host, con un ligero cambio en su configuración, repitiendo los mismos comandos a continuación.

docker exec -it nombre-runner gitlab-runner register

Nos va a pedir la URL de la instancia de GitLab. Si tuviéramos una instancia de GitLab propia (por ejemplo: https://gitlab.dominio.com) lo colocamos, sino la de gitlab.com. Luego Enter:

Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.com

Ingresamos nuestro Token de Registro del Runner:

Enter the registration token:
ejempl0detok3n

Le colocamos una descripción al Runner, lo más descriptiva posible si fuera necesario para que asignemos nuestros trabajos específicos, luego Enter:

Enter a description for the runner:
GitLab Runner de Ejemplo en amd64

Nos va a pedir a continuación que le asignemos etiquetas al Runner. La ventaja es que en base a estas etiquetas, podemos asignar ciertos jobs específicos a ciertos runners:

Enter tags for the runner (comma-separated):
amd64,docker,alpine

Lo siguiente es configurar un Optional Maintenance Note, en palabras sencillas, aqui podremos colocar cualquier información necesaria para que el equipo de desarrollo sepa que capacidad tiene el Runner, como: CPU, núcleos, memoria RAM, sistema operativo, etc. Como es opcional lo podemos dejar en blanco:

Enter optional maintenance note for the runner:

Nos va a pedir que configuremos que tipo de Runner vamos a utilizar, el cual va a ser docker:

Registering runner... succeeded                     runner=GR1348941XwCyTjRM
Enter an executor: ssh, instance, kubernetes, docker, docker-windows, parallels, shell, docker+machine, docker-ssh+machine, custom, docker-ssh, virtualbox, docker-autoscaler:
docker

Y ahora vamos a escoger que imagen va a ejecutar el Runner por defecto cuando no lo declaremos explicitamente en el .gitlab-ci.yml:

Enter the default Docker image (for example, ruby:2.7):
alpine

Una vez finalizado el proceso nos va a indicar que fue exitoso:

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" 

Y comprobamos que el Runner este funcionando:

Runner Funcionando
Runner Registrado

Ahora hay que modificar un par de cosas en la configuración del Runner. La primera es que el Runner por defecto no va a ejecutar los jobs de manera automática, por lo que hay que modificar ese comportamiento entrando al Runner en GitLab con el botón Edit a la derecha, y activamos la opción que dice: Run untagged jobs:

Habilitamos Run untagged jobs
Habilitamos Run untagged jobs

Y lo segundo que vamos a modificar es el archivo de configuración del Runner. Recordemos que se encuentra en la ruta /srv/gitlab-runner/config de nuestro host, lo abrimos con nuestro editor de texto de confianza:

nano /srv/gitlab-runner/config/config.toml
concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "GitLab Runner de Ejemplo en amd64"
  url = "https://gitlab.com"
  id = 23051351
  token = "id-token"
  token_obtained_at = 2023-04-30T17:25:46Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "alpine"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

Vamos a modificar las siguientes opciones:

  • concurrent = 10: Dependiendo del hardware de nuestra máquina, vamos a asignar los jobs concurrentes que va a ejecutar, en mi caso le voy a poner 10 jobs ejecutándose a la vez.
  • privileged = true: Habilitamos el modo privilegiado para que ejecute jobs con comandos de Docker.
  • volumes = ["/certs/client","/cache"]: Para que en el caso de construir imágenes de Docker cargue el certificado SSL.

El archivo de configuración quedaría entonces de la siguiente manera:

concurrent = 10
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "GitLab Runner de Ejemplo en amd64"
  url = "https://gitlab.com"
  id = 23051351
  token = "id-token"
  token_obtained_at = 2023-04-30T17:25:46Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "alpine"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/certs/client","/cache"]
    shm_size = 0

Guardamos los cambios, salimos del editor y debemos detener e iniciar nuevamente el contenedor:

docker stop nombre-runner && docker start nombre-runner

O con Docker Compose:

docker compose stop && docker compose up -d

Comprobando Funcionamiento
#

Creemos un proyecto de ejemplo en ese Grupo:

Creando Nuevo Proyecto
Creando Nuevo Proyecto

Proyecto en blanco
Proyecto en blanco

Dando nombre al Proyecto
Dando nombre al Proyecto

Damos click en Nuevo Archivo para que nos envie directamente al editor de GitLab, creamos el archivo .gitlab-ci-yml con el siguiente contenido:

stages:
  - test

test:
  stage: test
  image: alpine:3.17
  script:
    - echo "Esto es un ejemplo de un job corriendo en un Runner Self-Hosted"
    - sleep 5

Creando nuevo Archivo
Creando nuevo Archivo

.gitlab-ci.yml
.gitlab-ci.yml

Tenemos entonces un stage test donde va a ejecutar 2 comandos: un echo con un mensaje y luego un tiempo de espera de 5 segundos antes de acabar el job.

Ingresamos un mensaje de commit y luego hacemos Push:

Subiendo Cambios
Subiendo Cambios

Vamos entonces en la esquina izquierda, menú CI/CD, opción Pipelines, y ahi veremos nuestro stage test funcionando:

Stages
Stages

Si entramos a ese stage, veremos el job en ejecución y que terminó bien. Si nos fijamos más arriba del stdout, veremos el runner que ejecutó la tarea (on GitLab Runner de Ejemplo en amd64 Xr6Wn6cn, system ID: r_Uw2LQ4QZ8jGP)

stdout del Job
stdout del Job

Espero les haya gustado y nos vemos en la próxima!