如何使用GitLab runner启动服务并阻止它停止?

时间:2016-01-29 16:10:40

标签: spring-boot gitlab gitlab-ci-runner

我将使用GitLab CI服务器部署简单的Spring Boot应用程序。我的.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]

但是,我无法加载应用程序,因为一旦跑步者完成阶段,服务已经停止:

$ 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启动脚本,GitLab配置,我的服务脚本还是别的什么?

我使用GitLab CI多跑者版本0.5.0(c38415a)运行Ubuntu 14.04。

UPD:

将跑步者升级到版本1.0.1(cffb5c7)无法解决问题。

2 个答案:

答案 0 :(得分:10)

为什么这样做是个坏主意......

正如其文档明确指出的那样,GitLab Runner“运行测试并将结果发送给GitLab”。

由于测试应该及时启动和停止,因此运行器旨在在完成每个构建后终止所有创建的进程。

因此,您的服务被杀死不是错误,而是功能。 ;)


部署的GitLab CI文档recommends using dpl

dpl是一个项目,可让您在各种PaaS提供商(例如Google App Engine,Heroku或Elastic Beanstalk)上部署您的应用。

因此,它会向某些REST API发出一些请求,或者通过互联网推送其他一些数据,并且它的进程可以很好地退出。


所以做你想做的事实际上需要一些黑客攻击 - 覆盖默认的跑步者行为。你不应该把它作为一个长期的解决方案,因为它可能会停止使用一些runner / gitlab更新。

...但如果你坚持,那么这里是方法:)

在您的情况下,当您想要在跑步者的主机上实际部署和运行应用程序时,我们需要使用两个黑客:

好的,以下是说明:

  1. 确保您可以使用/root/.ssh/id_rsa中的SSH私钥从您的转轮主机SSH连接到自己,而无需密码,而无需确认指纹。由ssh localhost运行的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"
    
  3. (跑步者将在保存配置文件后重新加载)

    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
      
    2. 通过重试上一次构建或提交项目回购来进行测试。

      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 "$1" in
        start)
          start
          ;;
        stop)
          stop
          ;;
        *)
          echo $"Use this options $0 {start|stop}"
          exit 1
      esac
      

      ..在Ubuntu 14.04上使用gitlab-multi-runner v.1.02和GitLab CE 8.5.0。

答案 1 :(得分:-1)

虽然由@GregDubicki发布的解决方案非常完美并且包含每个步骤的解释,但我最终得到了一个监控服务的解决方案,它会在每次构建后重新启动我的服务。

这种方法具有以下优点:

  1. 您不应该在root user
  2. 下开始参赛
  3. 你不应该关心由跑步者杀死的进程
  4. (+红利)你现在有一个监控系统!