こんにちは。テクマトリックスの監物です。

今回は、JenkinsのLockable Resourcesプラグインでエージェントを排他的に利用する方法を試してみたのでご紹介します。

Lockable Resourcesプラグインとは

ジョブのビルド間でエージェントなどのリソースを排他的に利用するためのプラグインです。
Lockable Resources | Jenkins plugin

ビルドが実行されるとリソースがロックされ他のビルドはロックが解放されるまでリソースを利用することができません。例えば、エージェント用にリソースを定義してジョブのビルドAから利用した場合、ビルドBはビルドAがリソースを解放するまで待機します。なお、排他制御はプラグインを利用したジョブのビルドが対象となります。

試してみる

パイプラインジョブでエージェントを排他的に利用してみます。

プラグインのインストール

JenkinsにLockable Resourcesプラグインをインストールします。

  1. Jenkinsダッシュボード > [Jenkinsの管理] > [Plugins] を開く
  2. [Available plugins] > “Lockable Resources plugin” をインストール

リソースの設定

エージェント用のリソースを設定します。

  1. Jenkinsダッシュボード > [Jenkinsの管理] > [System] を開く
  2. “Lockable Resources Manager” にリソースを追加
    • Name:my-resource1(リソースの名前)
    • Description:my-resource1(リソースの説明)
    • Labels:agent1(リソースをグループ化するためのラベル)
      • エージェントのラベルではありません
    • Reserved by:<空>(ロックの理由)
      • 空でない場合はジョブで利用できません(設定時点でリソースがロックされます)

ジョブの設定

リソースを利用するジョブを作成します。

  1. Jenkinsダッシュボード > [新規ジョブ作成] を開く
  2. ジョブを作成
    • ジョブ名:lockable-resources
    • タイプ:パイプライン
  3. ジョブにパイプラインを設定
    • このパイプラインはエグゼキューターを2つもつ(同時実行数2)agent1エージェントを利用しています
    • 事前に設定したmy-resource1リソースをlock()によりロックしています
pipeline {
    agent {
        label 'agent1'
    }
    stages {
        stage('Test') {
            steps {
                lock('my-resource1') {
                    sleep 60
                }
            }
        }
    }
}

結果の確認

排他制御を確認するために作成したジョブを連続で2回実行すると、最初のビルドでリソース(エージェント)がロックされて、次のビルドはロックの解除待ちで待機していることが分かります。エージェントのエグゼキューターは2つのため、通常は2つのビルドが同時に実行されるはずですが、ビルドがエグゼキューターに割り当てられているものの同時に実行されていません。

なお、この排他制御はプラグインを利用しているジョブのビルドが対象となるため、ロック中でもプラグインを利用していないジョブからは空いているエグゼキューターを利用することができます。リソースの利用状況はダッシュボードのLockable Resourcesビューから確認できます。このビューからは手動でリソースのロックや解放をおこなうこともできます。

その他(同時実行数を制限する)

ジョブで商用ツールを実行していて、同時実行数などのライセンスの制約をケアしなければいけないこともあると思います。例えば、ライセンスの形態がフローティングで、どのサーバーで実行してもよいが同時に実行できるのは2つまでというような同時実行数に制限がある場合です。このような場合でも利用できます。例として3つのエージェントがある環境で同時に実行できる数を2つに制限してみます。

リソースの設定

許容する同時実行数分のリソースを設定します。”Lockable Resources Manager” にグループ化するために同じラベル(tool)を設定した2つのリソースを追加します。

  • 1つ目
    • Name:my-resource1
    • Description:my-resource1
    • Labels:tool
    • Reserved by:<空>
  • 2つ目
    • Name:my-resource2
    • Description:my-resource2
    • Labels:tool
    • Reserved by:<空>

ジョブの設定

リソースを利用するジョブを作成します。

  • このパイプラインはエージェントをanyで指定しているため、3つのエージェントのうちいずれかで実行されます
  • lock()labelオプションでリソースをラベルで指定しています
    • toolラベルのリソースを指定
  • lock()quantityオプションでロックするリソースの数を指定しています
    • toolラベルのリソースのうち1つロック
  • lock()resourceオプションでロックするリソース名を指定しています
    • リソースはリソース名ではなくラベルで指定するためnullを指定
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                lock(label: 'tool', quantity: 1, resource : null) {
                    sleep 60
                }
            }
        }
    }
}

結果の確認

同時実行数の制限を確認するために作成したジョブを連続で3回実行すると、最初の2回のビルドでtoolラベルのついた2つのリソースがそれぞれロックされるため、3回目のビルドはリソースの解放待ちになります。このように同時実行数を制限することもできます。

まとめ

本記事では、Lockable Resourcesプラグインを利用したエージェントの排他制御をご紹介しました。今回は紹介していませんがロックの解放待ちをしているビルドの優先度付けなど、より細かい制御をおこなうための機能も用意されています。排他制御に興味がある方は試してみてはいかがでしょうか。