- 概要
- システム要件
- 対応クラウドプロバイダー
- ランナーの構成
- オートスケーリング・アルゴリズムとパラメータ
concurrent
、limit
、IdleCount
はどのようにしてランニングマシンの上限を生成するのでしょうか?- オートスケーリング期間の設定
- オフピーク時間モードの設定(非推奨)
- ディストリビューション・ランナー・キャッシング
- 分散コンテナレジストリミラーリング
- 完全な例
config.toml
ランナーのオートスケール設定
オートスケール機能は GitLab Runner 1.1.0 で導入されました。
オートスケールは、より弾力的でダイナミックな方法でリソースを利用する能力を提供します。
オートスケールが可能なRunnerのおかげで、インフラストラクチャにはいつでも必要なだけのビルドインスタンスしか含まれません。 オートスケールのみを使用するようにRunnerを設定すると、Runnerがインストールされているシステムは、Runnerが作成するすべてのマシンの拠点として機能します。
概要
この機能が有効で適切に設定されている場合、ジョブは_オンデマンドで_作成されたマシンで実行されます。 これらのマシンはジョブ終了後、次のジョブの実行を待つか、設定されたIdleTime
の後に削除することができます。多くのクラウドプロバイダーの場合、これは既に使用されているインスタンスのコストを利用するのに役立ちます。
以下は、GitLab.comのGitLab Community Editionプロジェクトでテストされたrunner autoscale機能の実例です:
Chart上の各マシンは独立したクラウドインスタンスであり、Dockerコンテナ内でジョブを実行しています。
システム要件
オートスケールを設定する前に、以下を行う必要があります:
対応クラウドプロバイダー
オートスケールの仕組みはDockerMachineに基づいています。 サポートされている仮想化/クラウドプロバイダのパラメータはすべて、Docker Machineドライバのドキュメントで入手できます。
ランナーの構成
このセクションでは、オートスケール機能の観点から重要なパラメータのみを説明します。 より詳細な設定については、詳細設定をお読みください。
Runner グローバルオプション
パラメータ | 値 | 説明 |
---|---|---|
concurrent
| 整数 | グローバルに同時に実行できるジョブの数を制限します。 これは、定義された_すべての_ランナー、ローカルおよびオートスケールを使用するジョブの数の上限です。limit ([[runners]] セクションより) およびIdleCount ([runners.machine] セクションより) とともに、作成されるマシンの上限に影響します。
|
[[runners]]
オプション
パラメータ | 値 | 説明 |
---|---|---|
executor
| 列 | オートスケール機能を使用するには、executor をdocker+machine またはdocker-ssh+machine に設定する必要があります。
|
limit
| 整数 | この特定のトークンが同時に処理できるジョブの数を制限します。0は単に制限しないことを意味します。 オートスケールの場合、このプロバイダが作成するマシンの上限です(concurrent とIdleCount と併用)。
|
[runners.machine]
オプション
設定パラメータの詳細はGitLab Runner - Advanced Configuration - The[runners.machine]
sectionにあります。
[runners.cache]
オプション
設定パラメータの詳細はGitLab Runner - Advanced Configuration - The[runners.cache]
セクションにあります。
追加設定情報
また、IdleCount = 0
を設定すると、特別なモードもあります。 このモードでは、各ジョブの前に、マシンは常に オンデマンドで作成されます(_アイドル_状態のマシンがない場合)。 ジョブが終了すると、オートスケーリング・アルゴリズムは、以下に説明するのと同じように動作します。 マシンは次のジョブを待ち、IdleTime
の期間が経過しても、1つも実行されない場合、マシンは削除されます。 ジョブがない場合、_アイドル_状態のマシンはありません。
オートスケーリング・アルゴリズムとパラメータ
オートスケーリング・アルゴリズムは、IdleCount
、IdleTime
、limit
の3つの主要パラメータに基づいています。
GitLab Runnerがオートスケールモードの場合、全てのマシンを監視し、常に_Idle_状態のマシンがIdleCount
。
同時に、GitLab Runnerは各マシンの_Idle_状態の時間をチェックしています。 時間がIdleTime
の値を超えた場合、マシンは自動的に削除されます。
例:GitLab Runnerに以下のオートスケールパラメータを設定したとします:
[[runners]]
limit = 10
# (...)
executor = "docker+machine"
[runners.machine]
IdleCount = 2
IdleTime = 1800
# (...)
ジョブがキューに入っていない最初の段階で、GitLab Runnerは2台のマシン(IdleCount = 2
)を起動し、_Idle_状態にします。IdleTime
も30分に設定していることに注目してください(IdleTime = 1800
)。
ここで、GitLab CIに5つのジョブがキューに入っているとします。最初の2つのジョブは、2台ある_Idle_マシンに送られます。GitLab Runnerは、_Idle_マシンの数がIdleCount
(0 < 2
)より少ないことに気づき、2台の新しいマシンを起動します。次に、キューから次の2つのジョブが新しく作成されたマシンに送られます。ここでも、_Idle_マシンの数はIdleCount
より少ないので、GitLab Runnerは2台の新しいマシンを起動し、最後のキューに入ったジョブは_Idle_マシンの1台に送られます。
1台の_Idle_マシンができたので、GitLab RunnerはIdleCount
。キューに新しいジョブがないので、これら2台のマシンは_Idleの_ままとなり、GitLab Runnerは満足します。
5つのジョブがキューに入った後、新しいマシンが作成され、合計で7台のマシンが稼働しました。 そのうち5台がジョブを実行中で、2台が次のジョブを待つ_アイドル_状態でした。
GitLab Runnerは、IdleCount
が満たされるまで、ジョブの実行に使われたマシンごとに新しい_Idle_マシンを作成します。これらのマシンは、limit
パラメータで limit
定義された数まで作成されますlimit
。 limit
GitLablimit
Runnerが limit
作成されたマシンの総数が多いlimit
ことに気づいたら limit
、自動スケーリングを停止し、新しいジョブはマシンが_Idle_状態に戻り始めるまでジョブキューで待つ必要があります。
上記の例では、常にアイドル状態のマシンが2台あることになります。IdleTime
が適用されるのは、IdleCount
マシンの台数が. IdleCount
を超えた場合のみです。
スケールダウン:ジョブが終了した後、マシンは_Idle_状態に設定され、次のジョブが実行されるのを待ちます。 キューに新しいジョブがないとします。IdleTime
で指定された時間が経過すると、_Idle_マシンは削除されます。この例では、30分後に全てのマシンが削除され(最後のジョブ実行が終了してから30分後に各マシンが削除されます)、GitLab Runnerは例の最初と同じように、IdleCount
の_Idle_マシンを稼働させ続けます。
というわけで、まとめます:
- ランナースタート
- Runnerは2台のアイドルマシンを作成します。
- ランナーは1つのジョブを選択
- Runnerは、常に2台のアイドル状態のマシンを持つという強い要求を満たすために、もう1台マシンを作成します。
- ジョブ終了後、3台のアイドリングマシンがあります。
- 3台のアイドリングマシンのうち1台が、前回ジョブを選んだ時間から
IdleTime
を超えると、そのマシンは削除されます。 - Runnerは、ジョブの高速ピッキングのために、少なくとも2台のアイドルマシンを常に待機させています。
下記はジョブステータスとマシンステータスの比較表です:
concurrent
、limit
、IdleCount
はどのようにしてランニングマシンの上限を生成するのでしょうか?
limit
やconcurrent
を何に設定すればいいかを教えてくれる魔法の方程式は存在しません。ニーズに合わせて行動してください。_アイドル_マシンのIdleCount
を持つことはスピードアップ機能です。 インスタンスが作成されるまで10s/20s/30sも待つ必要はありません。 しかし、ユーザーとしては、(お金を払う必要のある)すべてのマシンを_アイドル_状態ではなく、ジョブを実行するようにしたいはずです。 そのため、concurrent
とlimit
は、お金を払ってもいいマシンの最大数を実行する値に設定すべきです。IdleCount
については、ジョブキューが空のときに、_使用されていない_マシンが最小量生成される値に設定すべきです。
次のような例を考えてみましょう:
concurrent=20
[[runners]]
limit = 40
[runners.machine]
IdleCount = 10
上記のシナリオでは、マシンの総量は30台です。limit
(ビルドとアイドル)マシンの総量は40台です。アイドルマシンは10台ですが、concurrent
ジョブは20台です。つまり、ジョブを実行しているマシンの同時実行台数は20台、アイドルマシンは10台で、合計は30台です。
しかし、limit
、作成可能なマシンの総量よりも少ない場合はどうなるのでしょうか?以下の例でそのケースを説明します:
concurrent=20
[[runners]]
limit = 25
[runners.machine]
IdleCount = 10
この例では、同時実行ジョブは最大20ジョブ、作成されるマシンは最大25台です。アイドル状態のマシンに関する最悪のシナリオでは、limit
が25であるため、アイドル状態のマシンを10台用意することはできず、5台しか用意できません。
オートスケーリング期間の設定
GitLab Runner 13.0で導入されました。
オートスケーリングは、時間帯によって異なる値に設定できます。 組織には、ジョブの実行が急増する時間帯が定期的にある場合と、ジョブがほとんどない時間帯がある場合があります。 たとえば、ほとんどの営利企業は、月曜日から金曜日まで、午前10時から午後6時までといった決まった時間帯に働きます。 それ以外の週の夜間と週末は、パイプラインが開始されません。
これらの期間は、[[runners.machine.autoscaling]]
セクションの助けを借りて設定することができます。各セクションは、Periods
のセットに基づいて、IdleCount
とIdleTime
を設定することができます。
オートスケーリング期間の仕組み
[runners.machine]
の設定では、複数の[[runners.machine.autoscaling]]
セクションを追加することができ、それぞれにIdleCount
、IdleTime
、Periods
、Timezone
プロパティを設定することができます。最も一般的なシナリオから最も具体的なシナリオの順に、各構成ごとにセクションを定義する必要があります。
すべてのセクションが解析され、現在の時刻に最後にマッチしたものがアクティブになります。 マッチするものがない場合は、[runners.machine]
のルートの値が使われます。
使用例:
[runners.machine]
MachineName = "auto-scale-%s"
MachineDriver = "digitalocean"
IdleCount = 10
IdleTime = 1800
[[runners.machine.autoscaling]]
Periods = ["* * 9-17 * * mon-fri *"]
IdleCount = 50
IdleTime = 3600
Timezone = "UTC"
[[runners.machine.autoscaling]]
Periods = ["* * * * * sat,sun *"]
IdleCount = 5
IdleTime = 60
Timezone = "UTC"
この設定では、平日の9時から17時(UTC)までの間、オペレーション時間中の大量のトラフィックを処理するために、マシンがオーバープロビジョニングされます。 週末には、トラフィックの減少を考慮して、IdleCount
が 5 に下がります。それ以外の時間帯は、ルート内のデフォルト値 -IdleCount = 10
とIdleTime = 1800
- が使用されます。
"Australia/Sydney"
のように、ピリオドのTimezone
を指定することができます。指定しない場合、すべてのランナーのホストマシンのシステム設定が使用されます。このデフォルトは、Timezone = "Local"
と明示的に指定することができます。
[[runner.machine.autoscaling]]
セクションの構文についての詳細はGitLab Runner - Advanced Configuration - The[runners.machine]
sectionを参照してください。
オフピーク時間モードの設定(非推奨)
この設定は非推奨であり、14.0で削除される予定です。 代わりにオートスケーリング期間を使用してください。 両方の設定が使用されている場合、オフピーク設定は無視されます。
オートスケールは、_オフピーク_時間モード期間をサポートして設定することができます。
_オフピークとは_何ですか?
組織によっては、定期的に仕事がない時間帯を設定することができます。 この時間帯は_オフピークと_呼ばれます。
_オフピークの_時間帯が発生する内部では、この時間帯にジョブが実行されないことが確実な場合、_アイドル_マシンの料金を支払いたくはないでしょう。特に、IdleCount
が大きな数字に設定されている場合はなおさらです。
どのように機能しているのですか?
_オフピークの_設定は、OffPeakPeriods
、OffPeakTimezone
、OffPeakIdleCount
、OffPeakIdleTime
の4つのパラメータで行います。OffPeakPeriods
の設定には、_オフピークタイムモードを_いつオンにするかを定義する cron スタイルのパターンの配列が含まれています。 例えば、以下のようになります:
[runners.machine]
OffPeakPeriods = [
"* * 0-8,18-23 * * mon-fri *",
"* * * * * sat,sun *"
]
Machinesスケジューラはアレイからすべてのパターンをチェックし、そのうちの少なくとも1つが現在の時刻を表していれば、_オフピークモードが_有効になります。
_オフピークモードが_有効になっている場合、マシンスケジューラは、IdleCount
の代わりにOffPeakIdleCount
を、IdleTime
の代わりにOffPeakIdleTime
を使用します。 オートスケーリングアルゴリズムは変更されず、パラメータのみが変更されます。マシンスケジューラは、OffPeakPeriods
パターンのどれもが満たされていないことを発見すると、IdleCount
とIdleTime
の設定に切り替えます。
ディストリビューション・ランナー・キャッシング
ジョブを高速化するために、GitLab Runnerは選択したディレクトリやファイルを保存し、後続のジョブ間で共有するキャッシュメカニズムを提供します。
ジョブが同じホストで実行されている場合は問題ありませんが、Runnerのオートスケール機能を使い始めると、ほとんどのジョブが新しい(またはほとんど新しい)ホストで実行されるようになり、新しいDockerコンテナで各ジョブが実行されるようになります。 その場合、キャッシュ機能を利用することができなくなります。
このイシューを克服するために、オートスケール機能とともに、ディストリビューション・ランナー・キャッシュ機能が導入されました。
使用するDockerホスト間でキャッシュを共有するために、設定されたオブジェクトストレージサーバを使用します。 キャッシュのリストアやアーカイブを行う際、GitLab Runnerはサーバにクエリを発行し、それぞれアーカイブをダウンロードまたはアップロードします。
分散キャッシュを有効にするには、[runners.cache]
ディレクティブを使って、config.toml
で定義する必要があります:
[[runners]]
limit = 10
executor = "docker+machine"
[runners.cache]
Type = "s3"
Path = "path/to/prefix"
Shared = false
[runners.cache.s3]
ServerAddress = "s3.example.com"
AccessKey = "access-key"
SecretKey = "secret-key"
BucketName = "runner"
Insecure = false
上記の例では、S3のURLはhttp(s)://<ServerAddress>/<BucketName>/<Path>/runner/<runner-id>/project/<id>/<cache-key>
の構造に従っています。
2つ以上のRunner間でキャッシュを共有するには、Shared
フラグをtrueに設定します。これにより、URL (runner/<runner-id>
)からRunnerトークンが削除され、設定されたすべてのRunnerが同じキャッシュを共有します。キャッシュ共有が有効な場合、Path
を設定してRunner間でキャッシュを分離することもできます。
分散コンテナレジストリミラーリング
Dockerコンテナ内で実行されるジョブを高速化するために、Dockerレジストリミラーリングサービスを使用することができます。 これはDockerマシンと使用されている全てのレジストリの間にプロキシを提供します。 イメージはレジストリミラーによって一度ダウンロードされます。 新しいホスト、またはイメージが利用できない既存のホストでは、設定されたレジストリミラーからダウンロードされます。
ミラーがDockerマシンのLANに存在するのであれば、イメージのダウンロードステップは各ホスト上でより速くなるはずです。
Dockerレジストリのミラーリングを設定するには、config.toml
の設定にMachineOptions
を追加する必要があります:
[[runners]]
limit = 10
executor = "docker+machine"
[runners.machine]
(...)
MachineOptions = [
(...)
"engine-registry-mirror=http://10.11.12.13:12345"
]
10.11.12.13:12345
はレジストリミラーがDockerサービスからの接続をリッスンしているIPアドレスとポートです。 Docker Machineによって作成された各ホストからアクセスできる必要があります。
完全な例config.toml
以下のconfig.toml
はdigitalocean
Docker Machine ドライバを使っています:
concurrent = 50 # All registered Runners can run up to 50 concurrent jobs
[[runners]]
url = "https://gitlab.com"
token = "RUNNER_TOKEN" # Note this is different from the registration token used by `gitlab-runner register`
name = "autoscale-runner"
executor = "docker+machine" # This Runner is using the 'docker+machine' executor
limit = 10 # This Runner can execute up to 10 jobs (created machines)
[runners.docker]
image = "ruby:2.6" # The default image used for jobs is 'ruby:2.6'
[runners.machine]
IdleCount = 5 # There must be 5 machines in Idle state - when Off Peak time mode is off
IdleTime = 600 # Each machine can be in Idle state up to 600 seconds (after this it will be removed) - when Off Peak time mode is off
MaxBuilds = 100 # Each machine can handle up to 100 jobs in a row (after this it will be removed)
MachineName = "auto-scale-%s" # Each machine will have a unique name ('%s' is required)
MachineDriver = "digitalocean" # Docker Machine is using the 'digitalocean' driver
MachineOptions = [
"digitalocean-image=coreos-stable",
"digitalocean-ssh-user=core",
"digitalocean-access-token=DO_ACCESS_TOKEN",
"digitalocean-region=nyc2",
"digitalocean-size=4gb",
"digitalocean-private-networking",
"engine-registry-mirror=http://10.11.12.13:12345" # Docker Machine is using registry mirroring
]
[[runners.machine.autoscaling]] # Define periods with different settings
Periods = ["* * 9-17 * * mon-fri *"] # Every workday between 9 and 17 UTC
IdleCount = 50
IdleTime = 3600
Timezone = "UTC"
[[runners.machine.autoscaling]]
Periods = ["* * * * * sat,sun *"] # During the weekends
IdleCount = 5
IdleTime = 60
Timezone = "UTC"
[runners.cache]
Type = "s3"
[runners.cache.s3]
ServerAddress = "s3-eu-west-1.amazonaws.com"
AccessKey = "AMAZON_S3_ACCESS_KEY"
SecretKey = "AMAZON_S3_SECRET_KEY"
BucketName = "runner"
Insecure = false
MachineOptions
パラメータには、Digital Ocean上でホストされているマシンを起動するためにDocker Machineが使用するdigitalocean
ドライバのオプションと、Docker Machine自体のオプション (engine-registry-mirror
) が含まれていることに注意してください。