в GitLab

GitLab CI: Часть 4, этап spawn в .gitlab-ci.yml


В предыдущей статье цикла о настройке GitLab CI мы познакомились со специальным файлом .gitlab-ci.yml, в котором описываются инструкции для раннеров, рассмотрели несколько примеров и подготовили «скелет» для внедрения continuous integration в проекте.

Как и обещал, каждый из этапов (stage) мы будем рассматривать отдельно, так что для начала давайте разберемся с этапом spawn из нашего файла .gitlab-ci.yml!

Сразу стоит отметить, что названия этапов (stage) и задач (jobs) не являются зарезервированными или ключевыми словами, поэтому их можно называть как угодно (лишь бы вы понимали, что там написано).

В данном случае самый первый этап из continuous integration я обозначил как spawn (порождение) — запуск всех контейнеров, необходимых при сборке проекта. В конфигурационном файле .gitlab-ci.yml этот этап выглядит следующим образом:

...
spawn_containers:
  stage: spawn
  before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  script:
    - set -o allexport; . ./docker/.env.staging.lc
    - docker-compose -f docker/docker-compose-build.yml up -d
  only:
    - develop
    - docker
...

Задачи, которые необходимо выполнить раннеру описываются в секции script. В нашем примере это две задачи — первая считывает переменные окружения из файла /docker/.env.staging.lc, вторая — создает и запускает контейнеры, описанные в конфигурационном файле /docker/docker-compose-build.yml.

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

Как оказалось в процессе тестирования, перед выполнением задач, описанных в секции script необходимо залогиниться в локальный Docker Registry, где хранятся нужные нам образы. Действия, которые необходимо выполнить перед основными задачами (из секции script) обозначить довольно легко с помощью ключевого слова before_script. Соответственно, действия которые выполняются после основных задач, должны описываться в секции after_script.

Переменные $CI_JOB_TOKEN и $CI_REGISTRY — это специальные (предопределенные) переменные, весь список которых находится здесь.

С помощью ключевого слова only мы также определяем для каких веток нужно производить все описанные действия (develop и docker), здесь можно также использовать регулярные выражения.

Запускаемые контейнеры описаны в конфигурационном файле docker-compose-build.yml и выглядят так:

version: '2'
services:
### Applications Code Container #############################
    applications:
        container_name: application
        image: tianon/true
        volumes:
            - ../:${PROJECT_PATH}
### Workspace Utilities Container ###########################
    workspace:
        container_name: workspace
        image: registry.gitlab.lc:5000/develop/ed:workspace-ed-sq
        volumes_from:
            - applications
### PHP-FPM Container #######################################
    php-fpm:
        container_name: php-fpm
        image: registry.gitlab.lc:5000/develop/ed:php-fpm-ed-sq
        volumes_from:
            - applications
        expose:
            - "9000"
        links:
            - workspace
### Node+npm Container ######################################
    node:
        container_name: node
        image: registry.gitlab.lc:5000/develop/ed:node-npm-ed-sq
        volumes_from:
            - applications
        ports:
            - "${NODE_PORT}:${NODE_PORT}"
### Redis Container #########################################
    redis:
        container_name: redis
        image: registry.gitlab.lc:5000/develop/ed:redis-ed-sq
        volumes:
            - redis:/data
        ports:
            - "${REDIS_PORT}:${REDIS_PORT}"
        links:
            - php-fpm
### Memcached Container #####################################
    memcached:
        container_name: memcached
        image: registry.gitlab.lc:5000/develop/ed:memcached-ed-sq
        volumes:
            - memcached:/var/lib/memcached
        ports:
            - "${MC_PORT}:${MC_PORT}"
        links:
            - php-fpm
### Websocket Container #####################################
    websocket:
        container_name: websocket
        restart: always
        image: registry.gitlab.lc:5000/develop/ed:websocket-ed-sq
        volumes_from:
            - applications
        ports:
            - "${WS_PORT}:${WS_PORT}"
### Volumes Setup ###########################################
volumes:
    memcached:
        driver: "local"
    redis:
        driver: "local"

Все docker-образы были заранее собраны и загружены в локальный docker registry проекта. Самый первый запуск задачи spawn_containers в процессе continuous integration может занять до нескольких минут (раннер должен скачать образы), но при последующих запусках это время сократится до нескольких секунд.

В моем случае, запуск контейнеров занимает 18 секунд, а на вкладке pipelines детали выполнения задачи выглядят следующим образом:

Running with gitlab-ci-multi-runner 1.10.0 (4a71a97)
Using Docker executor with image registry.gitlab.lc:5000/develop/ed:tmaier-dc-ssh ...
Starting service registry.gitlab.lc/develop/ed:my-docker-dind ...
Using locally found image version due to if-not-present pull policy
Waiting for services to be up and running...
Using locally found image version due to if-not-present pull policy
Running on runner-9e68759f-project-8-concurrent-0 via c7662d5025ba...
HEAD is now at 679227f2ed Merge branch 'feature/LK-7341' into 'develop'
From http://gitlab.lc:10087/develop/ed
  679227f2ed..635e14c14a  develop    -> origin/develop
Checking out 635e14c1 as develop...
Skipping Git submodules setup
$ docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
Login Succeeded
$ set -o allexport; . ./docker/.env.staging.lc
$ docker-compose -f docker/docker-compose-build.yml up -d
Creating network "docker_default" with the default driver
Creating application
Creating websocket
Creating workspace
Creating node
Creating php-fpm
Creating redis
Creating memcached
Build succeeded

С первым этапом из файла .gitlab-ci.yml разобрались, в следующей статье рассмотрим второй этап — процесс сборки проекта.

Добавить комментарий

  1. Евгений приветствую!

    Не очень понятно откуда взялись image
    image: registry.gitlab.lc:5000/develop/ed:workspace-ed-sq
    image: registry.gitlab.lc:5000/develop/ed:php-fpm-ed-sq
    image: registry.gitlab.lc:5000/develop/ed:node-npm-ed-sq
    image: registry.gitlab.lc:5000/develop/ed:redis-ed-sq
    image: registry.gitlab.lc:5000/develop/ed:memcached-ed-sq
    image: registry.gitlab.lc:5000/develop/ed:websocket-ed-sq

    в предыдущих 3 статьях ничего не сказано про них, что с этим делать?

    • Добрый день!
      Эти образы находятся в моем локальном docker-registry (registry.gitlab.lc:5000). В основном это стандартные образы, взятые с docker hub (redis / memcached / php-fpm), или чуть «допиленные»: workspace это тот же composer + несколько нужных мне консольных утилит; node-npm — образ с нужной мне версией npm, и т.д. Образы находятся в локальном docker-registry только для удобства и скорости их скачивания…

  2. Возникла проблема при запуске задания.

    Сделал все как указано, но поднятый контейнер

    «`
    spawn_containers:
    stage: spawn
    before_script:
    — docker version
    — ls -l /var/run/docker.sock
    — docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    script:
    — set -o allexport; . ./docker/.env.staging.lc
    — docker-compose -f docker/docker-compose-build.yml up -d
    «`

    Пишет:

    «`
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    «`

    Есть идеи с чем может возникнуть проблема?

    • Возможно, сам runner у вас запущен не в привилегированном режиме…

      Я регистрирую раннер так:
      docker exec -it gitlab-runner gitlab-runner register -n \
      --url http://gitlab.lc:10087/ci \
      --tag-list "release" \
      --registration-token xgKNBymStCfry3iSHfxp \
      --executor docker \
      --description "release-build-runner" \
      --builds-dir "/srv/release_build_directory" \
      --docker-image "tmaier/docker-compose:17.03" \
      --docker-dns 192.168.0.20 \
      --docker-privileged \
      --docker-volumes /var/run/docker.sock:/var/run/docker.sock \
      --docker-volumes /srv/release_build_directory:/srv/release_build_directory \
      --docker-pull-policy "if-not-present"

  3. С огромным нетерпением каждый раз жду следующей статьи, а тут бац и затык на 10 дней, я чуть с ума не сошел ))) и как всегда обрывается все на самом интересном месте, а у меня работа горит, а толковых манов по гитлаб сиай нет ни на русском, ни на ангельском, особенно про установку гитлаба сиай через докер компоуз и дальнейший деплой кода… жду, жду и еще раз жду, быстрее бы )))
    з.ы. сколько же я траблов огреб пытаясь развернуть все по твоим статьям под центосом седьмым — жуть )))

    • Сам прошел через все это, мучился не один месяц — теперь решил все записать/объяснить.
      Это только 4-я статья, а всего их запланировано 10 — информации много, все сразу и не распишешь…

      • Евгений, у тебя получилось поднять gitlab на https? я уже всю голову сломал, не получается хоть ты тресни подружить gitlab c https через docker-compose, думал все дело в centos7, поднял ubuntu и там не работает (((

        • Нет, гитлаб у меня тоже работает на http. По сути, https нужен только для корректной работы docker-registry, для этого в docker-compose есть параметр:

              - GITLAB_REGISTRY_API_URL="https://registry.git.labs.lc:5000/"

          Для локальной сети вполне сойдет, но если гитлаб доступен «из мира», то лучше его разместить за nginx, как я описывал в этой статье