Файл промаха кэша Gitlab runner после завершения этапа

# #spring #gitlab #gitlab-ci #gitlab-runner

Вопрос:

Краткие сведения

В моем gitlab-ci.yml есть 3 этапа для развертывания приложения в приложении okd pod под управлением spring boot на tomcat:8 Иногда cache.zip не обновляется после завершения этапа, так что следующий шаг не может быть выполнен правильно

Шаги по воспроизведению

Мой gitlab-ci выполняет следующий этап

Этап 1: запустите тестовую компиляцию —> ОК

Этап 2: упакуйте файл войны в качестве вывода для развертывания —> Журнал Gitlab-ci показывает успех, но cache.zip не имеет файла войны (просто иногда cache.zip нет файла войны, иногда он работает правильно)

Этап 3: Развертывание файла войны в pod —> Из-за войны файл не существует в cache.zip, ошибка сценария -> сбой

.gitlab-ci.yml

 image: openshift/origin-cli

stages:
  - build
  - test
  - staging

cache:
  paths:
    - .m2/repository
    - target
    - artifact

validate:jdk8:
  stage: build
  script:
    - 'mvn test-compile'
  only:
    - master
  image: maven:3.3.9-jdk-8

verify:jdk8:
  stage: test
  script:
    - 'mvn verify'
    - 'mvn package' # =====> this command generate war file
  only:
    - master
  image: maven:3.3.9-jdk-8

staging:
  script:
    - "mkdir -p artifact"
    - "cp ./target/*.war ./artifact/" # ======> Sometimes error at this line because of previous step not add war file into cache
    - "oc start-build $APP"
    - "rm -rf ./target/* amp;amp; rm -rf ./artifact/*" # Remove war amp; class file, only cache m2 lib
  stage: staging
  variables:
    APP: $CI_PROJECT_NAME
  environment:
    name: staging
    url: http://$CI_PROJECT_NAME-staging.$OPENSHIFT_DOMAIN
  only:
    - master
 

Фактическое поведение
Иногда в кэше нет файла war после завершения этапа тестирования (зависит ли это от размера файла war?)

Ожидаемое поведение Обновление файла войны в кэш после этапа тестирования для развертывания на промежуточной стадии

Соответствующие журналы и/или скриншоты

скриншот

журнал заданий

 Running with gitlab-runner 13.7.0 (943fc252)
  on gitlab-runner-node1 y6awygsj
Preparing the "docker" executor
00:01
Using Docker executor with image openshift/origin-cli ...
Using locally found image version due to if-not-present pull policy
Using docker image sha256:7ebb6be01117a50344d63f77c385a13302afecd33480b97c36a518d4f5ebc25a for openshift/origin-cli with digest docker.io/openshift/origin-cli@sha256:509e052d0f2d531b666b7da9fa49c5558c76ce5d286456f0859c0a49b16d6bf2 ...
Preparing environment
00:00
Running on runner-y6awygsj-project-489-concurrent-0 via gitlab.runner.node1...
Getting source from Git repository
00:01
Fetching changes...
Reinitialized existing Git repository in /builds/my-project/.git/
Checking out b4c97428 as master...
Removing .m2/
Removing artifact/
Removing target/
Skipping Git submodules setup
Restoring cache
00:05
Checking cache for default-23...
No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted. 
Successfully extracted cache
Executing "step_script" stage of the job script
00:01
$ mkdir -p artifact
$ cp ./target/*.war ./artifact/
cp: cannot stat './target/*.war': No such file or directory
Cleaning up file based variables
00:00
ERROR: Job failed: exit code 1
 

Описание окружающей среды

конфигурация.toml

 concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "gitlab-runner-node1"
  url = "https://gitlab.mycompany.vn/"
  token = "y6awygsj9zks18nU6PDt"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    dns = ["192.168.100.1"]
    tls_verify = false
    image = "alpine:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/mnt/nfs/nfsshare-gitlab/cache:/cache"]
    shm_size = 0
    pull_policy = "if-not-present"
 

Используемая версия GitLab Runner

Версия: 13.7.0

Редакция Git: 943fc252

Ветвь Git: 13-7-стабильная

Версия GO: go1.13.8

Построено: 2020-12-21T13:47:06 0000

ОС/Arch: linux/amd64

Возможные исправления

Повторите этап тестирования, пока в кэше не появится файл war

Комментарии:

1. Может ли быть так, что задания выполняются на разных бегунах? Кстати, mvn verify уже включает в package себя фазу, так что в этом mvn package нет необходимости.

2. @slauth в моей системе есть 2 бегуна, и они используют один и тот же общий каталог nfs

Ответ №1:

Давайте пойдем шаг за шагом.

Во-первых, о том, как управлять файлами между этапами.

Это правда, что вы можете получить прямой доступ к файлам между заданиями и этапами, если оба они выполняются в одной и той же среде, но это не всегда так (даже если оба исполнителя используют один и тот же общий каталог nfs), и вам следует использовать artifacts для этого.

Когда вы определяете artifact задание внутри, вы указываете список файлов, которые будут прикреплены к заданию при его успешном выполнении, сбое или всегда, в зависимости от имеющейся у вас конфигурации.

По умолчанию все artifacts предыдущие этапы передаются каждому заданию, но в любом случае вы можете dependencies также определить, из каких заданий вы хотите извлекать артефакты.

Поэтому в основном вы должны использовать следующее .gitlab-ci.yml

 image: openshift/origin-cli

stages:
  - build
  - test
  - staging

cache:
  paths:
    - .m2/repository

validate:jdk8:
  stage: build
  script:
    - 'mvn test-compile'
  only:
    - master
  image: maven:3.3.9-jdk-8

verify:jdk8:
  stage: test
  script:
    - 'mvn verify' # =====> verify already includes: validate, compile, test and package
  artifacts:
    paths:
      - target/[YOUR_APP_NAME].war
  only:
    - master
  image: maven:3.3.9-jdk-8

staging:
  dependencies:
    - verify:jdk8
  script:
    - "mkdir -p artifact"
    - "cp ./target/[YOUR_APP_NAME].war ./artifact/"
    - "oc start-build $APP"
  stage: staging
  variables:
    APP: $CI_PROJECT_NAME
  environment:
    name: staging
    url: http://$CI_PROJECT_NAME-staging.$OPENSHIFT_DOMAIN
  only:
    - master
 

Кроме того, обратите внимание, что я удалил mvn package инструкцию. Я бы рекомендовал вам ознакомиться с основами жизненного цикла сборки Maven.

Комментарии:

1. Неплохой идеал, но не могу решить мою проблему, потому что, если артефакт конфигурации вместо кэша, gitlab-runner загрузит файл артефактов на сервер gitlab (слишком большой и не подходит для производительности сервера gitlab), пожалуйста, обратитесь к изображению: imgur.com/a/0oW0RdF

2. Ну, конечно, это было предложение, учитывая, что я не знаю фактического названия вашего сгенерированного артефакта. Вы должны сохранить только этот, whatever.jar а не все скомпилированные классы.

3. Только развернутый файл war(или jar) имеет более 500 МБ и все еще слишком велик, чтобы загружать его как артефакт. Но, с другой стороны, в требовании говорилось, что нам нужно сохранить всю библиотеку maven для следующего цикла (чтобы предотвратить повторную загрузку из Интернета).

4. Загруженные зависимости из Maven хранятся не в target , а в .m2/repository , вот почему я не отключил эту зависимость из вашего определенного кэша. Но, как вы можете видеть, вы cache локальны, поэтому, если вы переключитесь между бегунами даже с одной и той же файловой системой, она не восстановит ее. Это не проблема для зависимостей, которые проверяются, но это касается результирующих артефактов. Поэтому вам нужно выбрать: вы настраиваете общий кэш, вы настраиваете реестр, в который загружаете свою войну, или вы настраиваете его как CI GitLab artifact ; но с двумя бегунами и локальным кэшем это не сработает.

5. Спасибо @Daniel Campos, я понял, но эта проблема появляется не в каждом запуске, просто иногда.