如何使用 GitLab runner 启动服务并防止其停止?

How to start a service using GitLab runner and prevent it from stopping?

我将使用 GitLab CI 服务器部署简单的 Spring 启动应用程序。我的.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 引导启动脚本、GitLab 配置、我的服务脚本或其他什么?

我是 运行 Ubuntu 14.04 与 GitLab CI 多运行器版本 0.5.0 (c38415a)。

更新:

将 runner 升级到版本 1.0.1 (cffb5c7) 并不能解决问题。

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

正如其文档明确指出的那样,GitLab Runner "runs tests and sends the results to GitLab".

并且由于测试应该及时开始和停止,运行ner 旨在在完成每个构建后终止所有创建的进程。

因此,您的服务被终止并不是 错误,而是 功能。 ;)


GitLab CI 文档 recommends using dpl 部署

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

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


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

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

在你的情况下,当你想在你的 运行 用户的主机上实际部署和 运行 应用程序时,我们需要使用两个技巧:

  • 不要使用默认的 shell 运行ner 执行器,而是 ssh 并使执行器 ssh 到它自己(受 启发(也请对他的回答投赞成票)如果支持我的!),
  • 拒绝初始化脚本正在 运行 的进程(Joe's solution to this question(再次 - 请点赞!)

好的,这是说明:

  1. 确保您可以使用 /root/.ssh/id_rsa 中的 SSH 私钥从您的 运行ner 主机通过 SSH 连接到它自己,无需密码,无需确认指纹。 ssh localhost 运行 by root 应该以非交互方式工作。

  2. 编辑你的 gitlab-运行ner 的配置文件,/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"
    

(运行ner 将在保存配置文件后自行重新加载)

  1. 编辑您的服务脚本,使其创建的进程不会成为初始化脚本的子进程,也不会打开标准输入、标准输出和标准错误:

    #!/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
    

通过重试上次构建或提交您的项目存储库来进行测试。


PS 我用如下所示的初始化脚本测试了我的解决方案:

#!/usr/bin/env bash

start() {
  # Completely disowned process, not a child
  # Credits: Joe at 
  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 [=12=] {start|stop}"
    exit 1
esac

..on Ubuntu 14.04 with gitlab-multi-运行ner v. 1.02 and GitLab CE 8.5.0.

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

这种方法有以下优点:

  1. 您不应该在 root 用户
  2. 下启动跑步者
  3. 你不应该关心被runner杀死的进程
  4. (+ bonus) 你现在有监控系统了!