Skip to content

GitLab

Основные функции GitLab

  • Система контроля версий
  • Система построения CI/CD
  • Встроенный Docker Registry

Схема CI/CD процессов

![[media/CI-CD-scheme.png]]

Continuous Delivery могут называть также CDL, а Continuous Deployment - CDP.


Pipeline

Пример пайплайна сборки docker образа после тестов:

![[media/docker-build-after-tests-pipeline.png]]

Как сохранять состояния между job-ами: Caching in GitLab CI/CD

Ручной запуск job-а

Задачи по типу docker build не всегда нужно повторять. Банально, не всегда есть смысл заново собирать образ, который уже собран и ждем в Container Registry.
Поэтому такие задачи можно оставить на ручной запуск в gitlab-ci.yml:

Text Only
script:

    - echo test
when: manual


Predefined CI/CD variables

Предопределенные переменные генерируются при запуске пайплайна в рамках этого пайплайна и каждого job-а.

Predefined variable examples


Сервисы

Сервис - это дополнительный контейнер, поднимающийся вместе с основным в момент выполнения задачи.

Серсивы имеют доступ к переменным.
Сервисы можно конфигурировать:

YAML
services:
    - name: custom-postgres:11.7
      alias: shmostgress
      entrypoint: ["/usr/local/bin/db-postgres"]
      command: ["start"]

Можно юзать разные версии одного сервиса, например, для тестирования.

docker:dind или "Docker in Docker"

Образ docker:dind (dind - docker in docker) нужен, если хочешь работать с docker и его командами, но не в хостовой системе.

dind share-ит свой сокет наружу, что позволяет, юзать команды docker из других контейнеров.

Самый частый use case - сборка образов, каждый из которых сохраняется локально и если каждый образ собирать на хостовой системе - там просто кончится место на диске, потому что образы заполнят всё. Поэтому берется контейнер с docker-ом, внутри которого уже собирается образ, который сохранится в рамках этого контейнера.

Вызывается как сервис:

YAML
...
    services:
        - docker:dind
...

GitLab Container Registry

Контейнеры это stateless и immutable инфраструктура:
+ stateless: контейнеры не сохраняют состояние между запусками (в этом же и идея docker-а, что все данные должны быть внешними / в виде volume-ов).
+ immutable: контейнеры неизменяемы после создания, то есть, для обновлений создаются новые образы, а старые удаляются.
Это к тому, что всё, что произошло внутри контейнера будет потеряно, когда контейнер выключится. То есть, образ, собранный внутри контейнера, не сохранится никак в системе после выключения этого контейнера.

Поэтому нужен какой-нибудь Container Registry 👇.

GitLab Container Registry - доп. функция GitLab-а, позволяющая хранить docker-образы для проектов.

  • Для каждого проекта - свой реестр
  • Доступ по учетке в GitLab
  • Доступ через CI по токену

Для того, чтобы собрать и запушить образ в GitLab Container Registry нужно:
1. docker login
2. docker build
3. docker push

Text Only
Docker build:
    stage: build
    image: docker:stable
    services:
        - docker:dind
    script:
        - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
        - docker build -t ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG} .
        - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG}
        - docker tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG} ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latest
        - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latest
    tags:
        - docker
login
Bash
docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}

логин, где gitlab-ci-token - автоматически созданный юзер для тебя с такими же правами, как у тебя.

build и push
Bash
docker build -t ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG} .
docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG}

Используются GitLab CI predefined variables, чтобы собрать и запушить образ, который после этого будет доступен по подобной ссылке: registry.gitlab.com/arut-plus/docker-cicd-django/docker-cicd-django:master.
Но нужен образ с тегом latest, поэтому следующий шаг это реализует.

tag и push
Bash
docker tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG} ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latest
docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latest

Заново тегируется образ и опять пушится. В итоге в registry запушится один образ с двумя тегами.
В итоге, можно будет юзать ссылку на образ с тегом latest: registry.gitlab.com/arut-plus/docker-cicd-django/docker-cicd-django:latest

Ссылку на образ можно скопировать в Deploy > Container Registry.

В docker-compose.yml это будет выглядеть, например, так:

Text Only
services:
  web:
    image: registry.gitlab.com/arut-plus/docker-cicd-django/docker-cicd-django:latest

При чем, при деплое, а конкретнее, до docker-compose, можно заменить latest на имя ветки такой командой:

Bash
- sed s/:latest/:${CI_COMMIT_REF_SLUG}/g -i ./docker-compose.yml
- docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
- docker-compose pull
...


after_script не останавливает пайплайн

Ошибка при выполнении кода в блоке after_script не пометит пайплайн как failed. Это такое исключение, которое отличает after_script от before_script и script.


Сохранение результатов в пайплайне

Cache

Используется для сохранения результата между задачами в рамках этапа.
За cache отвечает runner.

YAML
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - .npm/

key нужен для обращения к кешу.

В тестах может понадобится еще одна конфигурация:

YAML
some test:
  artifacts:
    when: on_failure

Artifacts

Используется для передачи состояния между этапами.
Артефакты можно скачать прямо в GitLab WebUI - поэтому их и юзают для получения, например, тест-репортов или apk-пакетов.
Артефакты сохраняет GitLab - runner здесь не при чем, ибо это зона ответственности самой платформы (GitLab).

YAML
pdf:
  script: xelatex mycv.tex
    artifacts:
      paths:
        - mycv.pdf
      expired_in: 1 week

[[gitlab-runner]]

gitlab #devops #CI/CD