Introducción
Este artículo es parte de la serie de píldoras para Product Managers que quieren tomarle el pulso a la tecnología, que puedan probarla, instalarla y demostrar sus capacidades.
Saber es poder
En Taniwa usamos máquinas en la nube dónde desplegamos nuestros propios productos (madriwa, mememtum, biolabeler, tanimage, etc) y otros tantos de algunos de nuestros clientes.
Desde hace tiempo nos dimos cuenta, como muchos otros, de que ibamos a vivir mejor (tener menos problemas y encima trabajar menos!!!) si tanto en el desarrollo como en nuestras operaciones de despliegue y mantenimiento utilizábamos:
- Contenedores.
- Integración continua.
- Despliegue continuo.
Y así lo hacemos, solo desplegamos aplicaciones en contenedores y de momento sin orquestador ninguno utilizando sólo docker-compose; y para la CI/CD utilizamos el servicio SaaS (GitLab).
El servicio GitLab es una herramienta estandar de DevOps que permite:
- Albergar el código de la aplicación en repositorios git.
- Ejecutar un conjunto de acciones llamado pipeline cuando ocurre algo en el código, para en primer lugar compilarlo, pasar los tests automáticos y construir la aplicación.
- Y después desplegar automáticamente esa aplicación en la mayoría de los proveedores de Cloud usados (Azure, AWS, GCloud, etc) o en tus propias máquinas.
Los pipelines se ejecutan en máquinas compartidas de la infraestructura de GitLab y no funcionan mal si no tienes demásiada urgencia en los despliegues y no eres muy paranoico con la seguridad.
Pero aunque no estemos muy obsesionados (en la seguridad por lo menos) en nuestro caso GitLab tiene que acceder a nuestras máquinas para desplegar nuestra aplicación, y para hacerlo con algo más de “privacidad” utilizamos los runners de GitLab.
GitLab Runner
GitLab Runner es una aplicación que se comunica con el sistema CI/CD de GitLab y es capaz de ejecutar los comandos de los pipelines que tiene asignados.
Puedes desplegar runners en la infraestructura de GitLab (runners manejados) pero también en tus propias máquinas. Los runner son aplicaciones open source escritas en Go, que además se pueden desplegar en contenedores (oeoeoe!!!)
Los pasos a seguir son:
- Lanzar el registro del runner con Gitlab
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register --docker-privileged
-
Te pide registrarlo para que se puedan ejecutar pipelines de un determinado proyecto o de un grupo de proyectos. Para ello te hay que introducir el token correspondiente que sale en la consola de GitLab (settings->ci/cd->runners).
-
También tienes que elegir un tipo de ejecutor, en nuestro caso “docker executor” pero dependiendo de tu instalación y necesidades hay otros (shell, ssh, virtual machine, kubernetes, etc)
-
Y por último configurar otros parámetros como número de jobs concurrentes, intervalo de chequear en gitlab si hay trabajos que realizar, timeouts sesión activa después de ejecutar un trabajo, etc.
Nuestro fichero de configuración del runner (/srv/gitlab-runner/config/config.toml) luce así:
concurrent = 5
check_interval = 5
[session_server]
session_timeout = 1800
[[runners]]
name = "taniwa runners"
url = "https://gitlab.com/"
token = "noseascotillaqueestonosepuedeleer"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "ubuntu:20.04"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
- Lanzar el docker del runner en tú máquina
docker run -d --name gitlab-runner --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:latest
Variables Pipelines
Lo que vamos a hacer dentro de los pipelines de nuestras aplicaciones es ejecutarlos en el runner de una de nuestras máquinas y desde allí hacer ssh y desplegarlas en las máquinas que necesitemos.
Para ello tenemos que configurar las siguientes variables del pipeline (settings->ci/cd->runners))
CICD_SERVER = "servidor donde desplegaremos la aplicación"
SSH_PRIVATE_KEY = "Private Key para poder hacer ssh a ese servidor"
Pipeline
Un pipeline de ejemplo de una de nuestras aplicaciones es el siguiente:
stages:
- build
- publish
build:
image: docker:dind
stage: build
script:
- if [ '$CI_COMMIT_BRANCH == "develop"' ]; then DOCKER_TAG="$CI_COMMIT_SHORT_SHA"; else DOCKER_TAG="$CI_COMMIT_TAG"; fi
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build -t registry.gitlab.com/taniwa/taniweb2022:$DOCKER_TAG .
- docker push registry.gitlab.com/taniwa/taniweb2022:$DOCKER_TAG
- echo "export DOCKER_TAG=$DOCKER_TAG" > $VARIABLES_FILE
artifacts:
paths:
- $VARIABLES_FILE
only:
- master
- tags
publish:
image: ubuntu:20.04
stage: publish
dependencies:
- build
script:
- source $VARIABLES_FILE
##
## Install ssh-agent if not already installed, it is required by Docker.
## (change apt-get to yum if you use an RPM-based image)
##
- 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
##
## Run ssh-agent (inside the build environment)
##
- eval $(ssh-agent -s)
##
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
## We're using tr to fix line endings which makes ed25519 keys work
## without extra base64 encoding.
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
##
- echo "$SSH_PRIVATE_KEY" | base64 -d | tr -d '\r' | ssh-add -
##
## Create the SSH directory and give it the right permissions
##
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
##
## Use ssh to deploy
##
- echo $DOCKER_TAG
- ssh taniwa@$CICD_SERVER "cd /home/taniwa/taniwa && docker-compose down && TAG=$DOCKER_TAG docker-compose up -d && exit"
only:
- master
- tags
En el stage de build podemos ver que usamos
- Una imagen de docker:dind (docker in docker) para poder ejecutar las órdenes de docker (login, build y push)
- Las variables predefinidas de GitLab $CI_REGISTRY_USER $CI_JOB_TOKEN $CI_REGISTRY que nos permiten hacer login con el repositorio de contenedores que GitLab lleva integrado en cada proyecto (Packages & Registries -> Container Registry)
Por último en el stage de publish lo que hacemos es hacer ssh al servidor dónde va a correr la aplicación y lanzar el docker con la imagen de la misma a través de docker-compose.
Chupao!!! … si alguna vez llego a ser PM o Leader de un proyecto (que no creo) seguro que no me acuerdo de nada …
Ir a Madriwa | Encuentra el sitio que mejor se adapta a ti en Madrid