Как запустить службу с помощью GitLab runner и предотвратить ее остановку?

Я собираюсь развернуть простое приложение Spring Boot с помощью сервера GitLab CI. Мой .gitlab-ci.yml следующим образом:

stages:
  - build_and_test
  - deploy

web_server_build_and_test:
  stage: build_and_test
  script:
    - mvn clean package

web_server_deploy:
  stage: deploy
  script:
    - mvn clean package -Pprod
    - service gitlab-runner-test stop
    - cp target/*.war /var/gitlab-runner-test/gitlab-runner-test.war
    - chmod +x /var/gitlab-runner-test/gitlab-runner-test.war
    - service gitlab-runner-test start

и deploy этап производит следующий вывод:

$ service gitlab-runner-test stop
Stopped [13247]
$ cp target/*.war /var/gitlab-runner-test/gitlab-runner-test.war
$ chmod +x /var/gitlab-runner-test/gitlab-runner-test.war
$ service gitlab-runner-test start
Started [21177]

однако я не могу загрузить приложение, так как служба была остановлена, как только runner завершает этап:

$ service gitlab-runner-test status
Not running (process 21177 not found)

мои сценарии обслуживания делегируют фактическую работу собранному war пакет:

#!/usr/bin/env bash

export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java
export MODE=service
export APP_NAME=gitlab-runner-test
export PID_FOLDER=/var/run/gitlab-runner-test


/var/gitlab-runner-test/gitlab-runner-test.war $*

кроме того, когда я начинаю обслуживания руками (service gitlab-runner-test start) он остается запущенным даже после закрытия сеанса пользователя.

Я не уверен, в чем корень проблемы - Spring Boot startup script, конфигурация GitLab, мои сценарии обслуживания или что-то еще?

Я запускаю Ubuntu 14.04 с GitLab CI multi runner версии 0.5.0 (c38415a).

UPD:

обновление runner до версии 1.0.1 (cffb5c7) не решает проблему.

2 ответов


почему это плохая идея, чтобы сделать это...

как четко указано в его документации,GitLab Runner "трассы тесты и отправляет результаты в GitLab".

и поскольку тесты должны запускаться и останавливаться своевременно, runner предназначен для уничтожения всех созданных процессов после завершения каждой сборки.

так это не ошибка что ваша служба убита, это характеристика. ;)


документация GitLab CI рекомендует использовать dpl на развертывание.

dpl-это проект, который позволяет развертывать приложение в различных провайдерах PaaS, таких как Google App Engine, Heroku или Elastic Beanstalk.

таким образом, он запускает некоторые запросы к некоторым API REST или проталкивает некоторые другие данные через интернеты, и его процесс красиво завершается.


так выполнение того, что вы хотите сделать, на самом деле требует некоторого взлома - переопределения поведения бегуна по умолчанию. И вы не должны делать это как долгосрочное решение, потому что оно может перестать работать с некоторым обновлением runner/gitlab.

...но если вы настаиваете, то вот как :)

в вашем случае, когда вы хотите фактически развернуть и запустить приложение на хосте вашего бегуна, нам нужно использовать два Хака:

  • не используйте значение по умолчанию shell runner исполнитель, но ssh и сделать исполнитель ssh для себя (вдохновленный решение Майкла на этот вопрос (пожалуйста, upvote его ответ тоже, если upvoting мой!),
  • откреститься от процесса запуска скриптов init (решение Джо этого вопроса (еще раз-пожалуйста, upvote его!)

хорошо, вот инструкции:

  1. убедитесь, что вы можете SSH от вашего хоста runner к себе с закрытым ключом SSH в /root/.ssh/id_rsa, без парольной фразы, без подтверждения отпечатка пальца. ssh localhost run by root должен работать неинтерактивно.

  2. отредактируйте конфигурационный файл GitLab-runner,/etc/gitlab-runner/config.toml чтобы это выглядело так:

    [[runners]]
      name = "your-runner-name"
      url = "https://<your_gitlab_instance_fqdn>/ci"
      token = "<your_project_CI_token>"
      tls-ca-file = ""
      executor = "ssh"
      [runners.ssh]
        user = "root"
        password = ""
        host = "localhost"
        port = "22"
        identity_file = "/root/.ssh/id_rsa"
    

(runner перезагрузится после сохранения файла конфигурации)

  1. отредактируйте свой скрипт службы, чтобы процесс, который он создаст, не был дочерним скриптом init и не открывался stdin, stdout и stderr:

    #!/usr/bin/env bash
    
    export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java
    export MODE=service
    export APP_NAME=gitlab-runner-test
    export PID_FOLDER=/var/run/gitlab-runner-test
    
    
    /var/gitlab-runner-test/gitlab-runner-test.war $* <&- >&- 2>&- & disown
    

Test, повторив последнюю сборку или сделав фиксацию в репо проекта.


PS Я тестировал свое решение с помощью сценария init, который выглядел так:

#!/usr/bin/env bash

start() {
  # Completely disowned process, not a child
  # Credits: Joe at https://stackoverflow.com/a/26420299/2693875
  sleep 99999 <&- >&- 2>&- & disown
  exit 0
}

stop() {
  echo "doing nothing"
  exit 0
}

echo "running on $HOSTNAME..."

case "" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  *)
    echo $"Use this options  {start|stop}"
    exit 1
esac

..на Ubuntu 14.04 с GitLab-multi-runner V. 1.02 и GitLab CE 8.5.0.


в то время как решение, опубликованное @GregDubicki, работает просто отлично и содержит объяснения для каждого шага, у меня есть solition со службой мониторинга, которая перезапускает мою службу после каждой сборки.

этот подход имеет следующие преимущества:

  1. вы не должны запускать runner под root пользователей
  2. вы не должны заботиться о процессах, убитых runner
  3. (+бонус) теперь у вас есть система мониторинга!