8

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 を実行しています。

更新:

ランナーをバージョン 1.0.1 (cffb5c7) にアップグレードしても問題は解決しません。

4

2 に答える 2

17

どうしてダメなのかと言うと…

ドキュメントに明確に記載されているように、GitLab Runnerは「テストを実行し、結果を GitLab に送信します」。

また、テストはタイムリーに開始および停止する必要があるため、ランナーは各ビルドの終了後に作成されたすべてのプロセスを強制終了するように設計されています。

したがって、サービスが強制終了されるのはバグではなく、機能です。;)


GitLab CI のドキュメントでは、デプロイに dplを使用することを推奨しています。

dpl は、Google App Engine、Heroku、Elastic Beanstalk などのさまざまな PaaS プロバイダーにアプリをデプロイできるようにするプロジェクトです。

そのため、いくつかの REST API に対していくつかのリクエストを発行したり、インターネット経由で他のデータをプッシュしたりして、そのプロセスを正常に終了します。


したがって、やりたいことを実際に行うには、ハッキングが必要です-デフォルトのランナーの動作をオーバーライドします。また、ランナー/gitlabの更新で動作しなくなる可能性があるため、長期的な解決策としては実行しないでください。

...しかし、あなたが主張するなら、ここにハウツーがあります:)

あなたの場合、実際にランナーのホスト自体にアプリをデプロイして実行したい場合は、2 つのハックを使用する必要があります。

  • デフォルトのshellランナーエグゼキューターを使用せず、エグゼキューターをそれ自体にsshします(この質問に対するマイケルの解決策にssh触発されました(私のものに賛成する場合は、彼の答えにも賛成してください!)、
  • initスクリプトによって実行されているプロセスを否認します(この質問に対するJoeの解決策(もう一度-賛成してください!)

わかりましたので、手順は次のとおりです。

  1. /root/.ssh/id_rsa指紋を確認せずに、パスフレーズなしで、ランナーホストからそれ自体に SSH 秘密鍵を使用して SSH 接続できることを確認してください。ssh localhostrun byrootは非対話的に動作する必要があります。

  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"
    

(設定ファイルを保存した後、ランナーは自分自身をリロードします)

  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
    

最後のビルドを再試行するか、プロジェクト リポジトリにコミットしてテストします。


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

.. gitlab-multi-runner v. 1.02 および GitLab CE 8.5.0 を搭載した Ubuntu 14.04 で。

于 2016-02-04T19:54:51.790 に答える
0

@GregDubicki によって投稿されたソリューションは完璧に機能し、各ステップの説明が含まれていますが、各ビルド後にサービスを再起動する監視サービスを使用したソリューションになってしまいました。

このアプローチには、次の利点があります。

  1. rootユーザーの下でランナーを開始しないでください
  2. ランナーによって殺されたプロセスを気にするべきではありません
  3. (+ボーナス) 監視システムができました!
于 2016-02-05T17:16:46.147 に答える