GitLab CI/CD
Conceptul de CI/CD se referă la:
- continuous integration - integrarea automată în sistem a modificărilor de cod
- continuous deployment - plasarea automată a codului modificat în testare/producție.
Acest concept se mulează natural pe filozofia microserviciilor, unde o aplicație este „spartă” în mai multe module separate și independente. Pe măsură ce codul unui modul este actualizat, acesta este integrat automat în sistem, fără să perturbe execuția celorlalte module.
În acest laborator, se exemplifică procesul de CI/CD folosind GitLab. GitLab CI/CD se bazează pe două componente:
- GitLab Runners - procese care execută pipeline-uri
- .gitlab-ci.yml - fișier YAML de configurații declarative, care descrie ce face fiecare etapă dintr-un pipeline.
Un runner execută un pipeline. Un pipeline este format din etape. Fiecare etapă este descrisă în fișierul de configurație .gitlab-ci.yml.
Structura codului sursă
Pentru a putea folosi conceptul de CI/CD cu GitLab cat mai eficient, se recomandă ca fiecare microserviciu să se afle în propriul său repository, iar toate repository-urile să fie grupate într-un grup. Așadar, pentru acest laborator, vom avea următoarele repository-uri:
- IOService - conține codul pentru microserviciul IO implementat la laboratoarele anterioare
- BooksService - conține codul pentru microserviciul de cărți implementat la laboratoarele anterioare
- Configs - conține fișierele de configurare necesare rulării stivei de servicii.
Codul este accesibil pe repo-ul oficial al laboratorului.
GitLab Runners
GitLab Runners sunt procese care execută pipeline-uri. Atunci când se dă comanda git push, este lansat în execuție un pipeline aferent repository-ului respectiv (de aici recomandarea de a avea un repository per serviciu).
Acestea vin în mai multe forme, însă modul cel mai facil de a lansa un runner în execuție este sub formă de containere Docker.
Configurare
Pentru a folosi un runner, este nevoie, în primul rând, să se acceseze pagina repository-ului sau a grupului GitLab.
Un runner de grup va putea rula pipeline-uri pentru fiecare repository din grupul respectiv. Un runner de repository va putea rula pipeline-uri doar pentru acel repository.
Se intră în meniul de CI/CD al paginii de proiect și apoi se selectează opțiunea „Expand” din dreptul „Runners”.
GitLab Runners în Docker
Configuraera unui runner folosind Docker este simplă și necesită trei pași:
- instalarea
- înregistrarea
- modificarea fișierului de configurație config.toml.
Pentru instalare, se rulează următoarea comandă:
$ docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
Runner-ul va rula în modul bind mount. Calea de pe gazdă dată runner-ului (în cazul de față, /srv/gitlab-runner/config) trebuie să existe. În ea vor fi reținute configurațiile runner-ului din interiorul containerului. În mod similar, se poate folosi un volum.
Pentru înregistrare, se rulează următoarea comandă și se urmează pașii specificați:
$ docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
Token-ul de înregistrare este cel din pagina grupului de GitLab.
Trebuie ținut minte ce se specifică la tag, deoarece tag-ul runner-ului va fi folosit în cadrul script-ului .gitlab-ci.yml.
Atunci când se cere imaginea de Docker, se poate specifica docker:19.03.
Trebuie specificată aceeași cale de bind mount ca la comanda de instalare.
Runner-ul de GitLab care rulează în Docker se bazează pe conceptul DinD („Docker in Docker”). Pentru anumite operații, este nevoie de acces elevat asupra sistemului Docker din gazdă. Așadar, trebuie făcute două modificări asupra fișierului de configurație config.toml.
Fișierul config.toml se găsește la calea specificata în comanda de instalare de la etapa 1.
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "IDP lab 4 runner"
url = "https://gitlab.com/"
token = "jEzCz9PACYL4Y1FB8vs2"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "docker:19.03"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
shm_size = 0
Modificările necesare sunt următoarele:
- privileged trebuie să fie setat pe true
- la volume, trebuie adăugat și /var/run/docker.sock:/var/run/docker.sock.
Dupa ce se efectuează modificările, se execută următoarea comandă:
$ docker restart gitlab-runner
Script-ul de pipeline
Script-ul .gitlab-ci.yml descrie execuția unui pipeline pe un runner. Puteți observa un astfel de script mai jos.
docker-build-master:
stage: build
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
only:
- master
tags:
- idp
- lab4
deploy-service-master:
stage: deploy
script:
- apk add --update curl
- curl -XPOST http://192.168.99.126:9000/api/webhooks/e37c80b1-9315-49d2-b0ad-5b3d8dade98e
only:
- master
tags:
- idp
- lab4
Trebuie câte un astfel de script .gitlab-ci.yml pentru fiecare repository.
Script-ul prezentat mai sus descrie două etape ale pipeline-ului:
- build - codul este construit într-o imagine de Docker și salvat într-un registru
- deploy - serviciul de Docker este încărcat in cluster-ul de Swarm, utilizând un webhook Portainer.
Un webhook se poate genera doar după ce serviciul rulează deja în Swarm.
Un pipeline se poate observa din GitLab mergând la meniul „CI/CD” al unui repository, la opțiunea „Pipelines”.
Un exemplu de fișier .gitlab-ci.yml funcțional poate fi găsit aici.