Indice:
- Introducción
- Gitlab vía máquina virtual
2.1 Uso de Vagrant
2.2 Instalación
2.3 Runners
2.4 Testeo del runner - Gitlab vía Docker
3.1 Instalación
3.2 Registro de Runners
3.3 Testeo del runner - Conclusión
Introducción:
Gitlab es una solución open source, host de repositorios Git tanto privados como públicos y una herramienta DevOps para planificar el proyecto en su ciclo de vida, desde el planning del proyecto hasta la monitorización y securización del mismo.
Gracias a esta herramienta, los equipos de desarrollo pueden hacer un trabajo de manera más productiva, aumentando el valor que entregan al cliente.
En este tutorial, haremos una instalación de esta solución en una máquina virtual en VirtualBox mediante Vagrant. También haremos la misma instalación a través de contenedores de Docker.
Gitlab vía máquina virtual:
Uso de Vagrant
Para empezar, vamos a crear el código de Vagrant que nos servirá de plantilla para las máquinas de Virtual box, crearemos una máquina que contendrá GitLab y otra que contendrá los runners.
Primero, creamos un Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.define "host" do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network :private_network, ip: "192.168.33.21"
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", 5120]
vb.customize ["modifyvm", :id, "--name", "ubuntu-host-gitLab"]
vb.customize ["modifyvm", :id, "--ioapic", "on"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
config.vm.define "runner" do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network :private_network, ip: "192.168.33.22"
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", 5120]
vb.customize ["modifyvm", :id, "--name", "ubuntu-runners"]
vb.customize ["modifyvm", :id, "--ioapic", "on"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
end
Lo que hacemos en este Vagrantfile es:
- Crear dos máquinas mediante los bloques
config.vm.define "NOMBREMAQUINA" do |config|
, a cada una de ellas le asignaremos varios parámetros. - Configurar la imagen que se usará para la máquina con
config.vm.box = "ubuntu/focal64"
, sacada de los repositorios de Vagrant. - Establecer la IP de la máquina virtual con
config.vm.network :private_network, ip: "X.X.X.X"
. - Por último, personalizar la configuración de la máquina en VirtualBox mediante código con el bloque
config.vm.provider :virtualbox do |vb|
. En las líneas devb.customize
que hacen referencia a la memoria, CPUs y nombre, puedes cambiarlo a tu gusto, asignando más o menos memoria o CPUs a la máquina. El nombre será el que muestre VirtualBox como nombre de la máquina.
Guardamos el Vagrantfile y, mediante la terminal, dentro del directorio donde tenemos guardado el Vagrantfile, ejecutamosvagrant up <nombre-m>
para levantar la máquina correspondiente (En el caso de este ejemplo, los nombres de la máquina serían host y runner). Una vez levantada las máquinas, accederemos a ellas convagrant ssh <nombre-máquina>
Instalación
Una vez dentro de la máquina que vayamos a usar como host, ejecutaremos una serie de comandos, siguiendo la guía de instalación de Gitlab.
Durante la instalación de postfix, nos aparecerá en la terminal una pantalla como la siguiente:
Elegiremos internet site. Tras esto, como System mail name, usaremos algo parecido a gitlab.example.org.
Pero… ¿Qué es postfix? Postfix es una herramienta de tortura psicológica disfrazada de servidor SMTP. Para no alargarnos mucho en este tutorial, ya configuraremos Postfix adecuadamente en otro momento, ahora mismo no estamos mentalmente preparados para este terror.
Seguimos con los comandos de la documentación hasta llegar a sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ee
. En la variable EXTERNAL_URL pondremos la dirección IP de la máquina que hosteara gitlab, asignada durante la creación de la máquina mediante Vagrant, en este caso «192.168.33.21».
Esto comenzará la instalación de Gitlab, que podría tardar más o menos según los recursos asignados a la máquina.
Finalizada la instalación, tendremos un mensaje muy similar a este de la imagen. En rojo están subrayadas las partes importantes:
- El usuario creado por defecto es root
- La contraseña de este usuario está alojada en /etc/gitlab/initial_root_password, y se borra tras 24h de la instalación.
- Justo debajo del icono del tanuki, encontraremos la URL para acceder a este GitLab recién instalado.
Una vez accedamos a nuestra instancia de Gitlab, primero cambiaremos la contraseña del usuario root desde preferencias.
Tras esto, crearemos todos los usuarios que nos hagan falta para nuestro equipo. En caso de no haber cambiado las opciones, necesitarás aprobar al usuario para que pueda ser usado. Crea también un proyecto para ir trasteando con el.
Runners
Pero… ¿Qué es un runner de Gitlab? Aplicaciones escritas en Go que usaremos para ejecutar las tareas mandadas en el pipeline.
Para instalar y registrar los runners, nos dirigiremos a los ajustes del proyecto que vayamos a usar y una vez dentro iremos a Settings -> CI/CD -> Runners:
Una vez desplegada la sección de los runners, copiamos el token de registro marcado con el círculo negro y él usamos «Show runner installation instructions»:
Viene todo lo necesario para instalar y registrar el runner. Solo haría falta, al usar el comando de registro del runner, sustituir la variable REGISTRATION_TOKEN por el Token de registro que copiamos antes. También podemos usar solo gitlab-runner register
e ir añadiendo a mano los datos que pide. Importante, añade un tag, si puede ser «test», mejor. Lo necesitaremos mas adelante.
Abajo mi resultado con el comando que brinda GitLab:
Verás que el registro pide un executor. ¿Y qué es un executor? ¿Qué más quiere GitLab de nosotros en esta espiral infinita de configuraciones? Básicamente, es el entorno donde correrán las tareas. Hay varios tipos de executors, todos documentados aquí, por si quieres profundizar más.
En mi caso, escojo Docker, además de la imagen openjdk:latest. Si sigues estos mismos pasos, deberás instalar Docker en la máquina, si no, no habrá executor que valga.
¿Todo bien? Entonces nos dirigiremos a nuestra página de GitLab, justo donde la dejamos. Al recargar podremos ver que ha aparecido un runner disponible.
Testeo del runner
Ahora vamos a testearlo. Crea una carpeta con un programa sencillo, con un «Hola mundo» valdría.
También vamos a crear un script sencillo para que compile el programa:
#!/bin/bash
javac AlleVoy.java
echo "build completed"
Y por último, crearemos el archivo de configuración que usara el proyecto, .gitlab-ci.yml, y le añadiremos:
build:
script:
- bash build_script.sh
tags: [test]
Tal y como tenemos la configuración hasta ahora, es importante que el tag de este archivo coincida con el tag que le dimos al runner a la hora de registrarlo.
Iniciamos un repositorio de git en la carpeta, y hacemos push del archivo. Si tienes dudas, dentro del README del proyecto creado en GitLab hay instrucciones para ello.
Una vez hecho el push, nos aparecerá un nuevo icono:
Ya sabemos que el pipeline ha salido bien, pero, y si queremos ver como ha sido la magia, ¿Qué hacemos? De primeras, el icono nos indica que todo OK, pero podemos ver un log de la tarea. Al pinchar en el icono, nos llevará a la información del pipeline:
Aquí volvemos a pinchar donde marca la flecha y…:
Viendo el log, podemos ver que el echo que añadimos en el script se imprime y que la tarea esta terminada con éxito.
Ya tenemos una instancia de Gitlab funcional, capaz de alojar un proyecto y correr las pruebas necesarias en él, todo metido y bien empaquetado en una máquina virtual.
Ahora, vayamos con esta misma instalación por Docker.
Gitlab vía Docker:
Instalación
Como requisito principal, vamos a necesitar Docker en la máquina en la que vayamos a llevar a cabo toda esta operación.
Podremos tener una instancia de GitLab mediante el comando docker run
, referenciado aquí, o mediante un Docker Compose. En este tutorial usaremos la via de Docker Compose.
version: "3.8"
services:
gitlab-host:
image: 'gitlab/gitlab-ee:latest'
container_name: gitlab-host
restart: always
hostname: 'localhost'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://localhost'
ports:
- '8080:80'
- '443:43'
- '22:22'
volumes:
- './gitlab/config:/etc/gitlab'
- './gitlab/logs:/var/log/gitlab'
- './gitlab/data:/var/opt/gitlab'
networks:
- gitlab
gitlab-runner:
image: gitlab/gitlab-runner:alpine
container_name: gitlab-runner
restart: always
depends_on:
- gitlab-host
volumes:
- ./runner/config/:/etc/gitlab-runner/
- /var/run/docker.sock:/var/run/docker.sock
networks:
- gitlab
networks:
gitlab:
name: gitlab-network
Con docker compose up -d
levantaremos los dos contenedores, la instancia de GitLab y el runner. Tras darle unos 5 minutos a que GitLab se configure en el contenedor, podemos ir a http://localhost:8080/ y nos aparecerá la instancia de Gitlab.
Volvemos a necesitar la contraseña de root, y en el contenedor, la contraseña temporal se crea igual que durante la instalación en la MV que hicimos antes. Para recuperar esta contraseña: docker exec -it gitlab-host grep 'Password:' /etc/gitlab/initial_root_password
.
Pero, antes de seguir, tal vez te habrás percatado de ese volumen tan raro que le estamos asignando al runner de GitLab. ¿Estamos montando un volumen sobre un socket, en concreto, de Docker? Con esto, le damos al contenedor el control sobre el daemon dockerd, pudiendo crear y eliminar contenedores, o incluso editar archivos en el host. Gracias a esto, el runner podrá correr el executor de Docker sin problemas. Pero… OJITO. Usar el docker.sock puede ser peligroso. Si alguien tomase el control de tu contenedor, también ganaría acceso sobre el host de este contenedor. Usa con cuidado este poder, solo cuando sea estrictamente necesario y con imágenes/contenedores de confianza. Además, Docker provee documentación al respecto.
Una vez obtenida la contraseña de root, accedemos, trasteamos un poco, y luego seguiremos con el registro de los runners.
Registro de Runners
El contenedor del runner ya viene con el Docker Compose, y está conectado al contenedor de la instancia de GitLab mediante la red que hemos creado en el Compose, «gitlab-network».
Creamos un repositorio nuevo, y dentro de este nos volvemos a dirigir a Settings -> CI/CD -> Runners, igual que en el paso de las MV, para obtener el token de registro.
Para registrar el runner ejecutaremos docker exec -it gitlab-runner gitlab-runner register --url "http://gitlab-host" --clone_url "http://gitlab-host"
.
De esta manera, le estamos pasando al register varios parámetros más.
- La URL: que referencia al nombre del otro contenedor
- La clone_url: Para indicar la URL desde la cual hará la clonación del repositorio, que también referencia al nombre del otro contenedor. Si no hacemos esto, cuando el runner ejecute el pipeline, intentará clonar el repositorio desde http://localhost y dará error, ya que el contenedor del runner estaría buscando en su propio localhost, donde no hay ningún repo.
Una vez registrado el runner, cambiaremos la configuración de este para que funcione correctamente. Dentro del volumen creado para guardar la configuración del runner, en ./runner/config/config.toml, añadiremos una línea más,network_mode = "gitlab-network"
, al final del archivo, en las opciones de [runners.docker].
De esta manera, unimos los Docker executor a la misma red, para que sea capaz de traducir la clone_url a la dirección correcta, y así, trabajar con el repositorio.Testeo del runner
Podemos usar el mismo repo que usamos para la parte de las MV. Subimos los archivos al repositorio y podemos ir a comprobar si el pipeline se ejecutó correctamente de la misma manera que se comprobó en la parte de las MV.
Conclusión
Como podemos ver, la instalación con Docker puede ser más rápida que la instalación en «crudo», ya que solo levantamos el contenedor y listo. No he querido profundizar mucho en cuanto se puede personalizar este contenedor de GitLab mediante GITLAB_OMNIBUS_CONFIG a la hora de crear el Docker Compose, pero, por ejemplo, añadiendo unas pocas opciones, podríamos tener un servidor SMTP de GitLab, en vez de usar Postfix como en la máquina Virtual, del cual ya hablaremos más adelante.
En cuanto a la instalación en «crudo» de las máquinas virtuales, decir que siempre está bien como funciona el proceso de instalación y configuración, además, creo que, este tipo de instalación, aporta mayor personalización.