Jenkins Pipeline内でGitフル機能を使う

Jenkinsのgit連携には、いくつかのシナリオがあります。

素朴な使い方は、ジョブで使うリポジトリをgit cloneするパターンで、これは gitステップで実装できます。

一方、git pushについてはPipelineステップやプラグインは存在せず、自ら実装する必要があります。

結論的に要点のコードを提示すると、以下のような実装になります。

sshagent(credentials: ['some-credential-id']) {
  sh('GIT_SSH_COMMAND="ssh -oStrictHostKeyChecking=no" git push origin master')
}
  • sh()ステップでJenkins実行環境内のgitコマンドを実行する
  • SSH鍵は SSH Agent Pluginから供給する
    • クレデンシャルIDは、Jenkinsの「認証情報」に登録した鍵IDを指定
  • GIT_SSH_COMMAND環境変数でsshの挙動を制御
    • 対話的に公開鍵を承認できないため、この例では-oStrictHostKeyChecking=noオプションで接続先ホスト認証をスキップ。man in middle攻撃への耐性は下がる
    • SSH接続ユーザーが決まっている環境では、ssh -lオプションを追加することでユーザー指定も可能

要するにJenkinsの実行環境にgitをインストールすればフル機能を使えるという素朴なアプローチです。最大の課題となる秘密鍵はsshagent()ステップでセットアップします。Jenkinsの「認証情報」に登録した秘密鍵はID文字列の指定のみで参照できるため、セキュアな方式と言えます。

ホスト認証については、known_hostsを適切にセットアップした方がセキュアです。ツールのサポートはなく、ビルド実行ユーザーの~/.ssh/known_hostsを参照する挙動になります。マルチノード構成の場合、実行ホストのスレーブノードに設定が必要です。
一般的な環境ではjenkinsユーザーで動作することが多いと思いますが、kubernetes pluginを用いてコンテナ内でビルドするケースでは特に指定しなければrootで動作します。known_hostsは以下のようなコマンドで生成できます。

$ ssh-keyscan some-host >> known_hosts

注意事項

git pushの前提として、以下のような準備が必要です。

  • JenkinsにSSH Agent Pluginをインストール
  • gitリポジトリにアクセス可能な秘密鍵をJenkinsの認証情報に登録しておく
  • ジョブの実行環境にgitをインストール
    • Kubernetes Plugin環境ではコンテナイメージにgitをインストールしておく
    • 上の例ではホスト確認をスキップしているがknown_hostsを登録してホスト確認した方がベター
  • git pushの前段階で、git configを用いて user.email と user.name を設定しておく

また、ジョブの内容にもよりますが、checkout scmなどでcloneしたリポジトリの場合、“detached head"になっていることがあります。push時に"src refspec master does not match any"といったエラーに遭遇する場合には、git checkoutなどでHEADを適切にセットアップしておく必要があるでしょう。

エラー時のプリントデバッグコマンドとして、以下のようなものが使えます。

  • git branch
    • detached headの確認
  • git remote -v
    • リモートリポジトリ設定の確認
  • ssh-add -l
    • ssh-agentが供給する鍵の確認

まとめ

この方式は、Jenkinsとgitとsshの3つのレイヤを適切にセットアップする必要があり、手軽な方法ではありません。

ただ、gitの高度な機能を利用したい場合、gitコマンドを直接使う方が見通しが良いケースがあります。

また、以下の点で明確なメリットもあります。

  • Pipelineに記述することでコード化でき、プラグイン依存を低減できる
  • Jenkins標準のクレデンシャル管理を活用して、秘密鍵をシンプルに供給できる
  • Kubernetes Pluginのコンテナ上でも実装を変えずに動作する

gitとsshのスキルは相当求められますが、目的に対して必要な柔軟性を得られます。

中馬崇尋
Chuma Takahiro