Despliegue continuo en GitLab para Project Managers

6 April 2022| Tags: formación, cicd, product management

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:

  1. 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
  1. 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).

  2. 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)

  3. 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
  1. 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

SO WHAT DO YOU THINK ?

Contact us and tell us your needs
+34 644 237 135

Contact hola@taniwa.es