Docker Machine Executorのオートスケール設定

オートスケール機能はGitLab Runner 1.1.0で導入されました。

オートスケールは、より弾力的で動的な方法でリソースを使用する機能を提供します。

GitLab Runnerはオートスケールが可能なので、インフラストラクチャにはいつでも必要な数のビルドインスタンスしか含まれません。GitLab Runnerがオートスケールのみを使用するように設定した場合、GitLab Runnerがインストールされたシステムは、GitLab Runnerが作成するすべてのマシンの拠点として機能します。このマシンは “Runner Manager” と呼ばれます。

note
Dockerは、公開クラウドの仮想マシン上でRunnerをオートスケールするために使われていた基礎技術であるDocker Machineを非推奨としました。Docker Machineの非推奨化に対する戦略について議論しているイシューをお読みください。

概要

この機能を有効にして適切に設定すると、ジョブは_オンデマンドで_作成されたマシンで実行されます。これらのマシンはジョブ終了後、次のジョブの実行を待つか、設定されたIdleTime の後に削除することができます。多くのクラウドプロバイダーの場合、これは既に使用されているインスタンスのコストを利用するのに役立ちます。

以下は、GitLabCommunity EditionプロジェクトのためにGitLab.comでテストされたGitLab Runnerのオートスケール機能の実例です:

Real life example of autoscaling

Chart上の各マシンは独立したクラウドインスタンスで、Dockerコンテナ内でジョブを実行しています。

システム要件

オートスケールを設定する前に、次のことが必要です:

サポートされているクラウドプロバイダー

オートスケールの仕組みはDocker Machineに基づいています。サポートされているすべての仮想化とクラウドプロバイダのパラメータは、Docker MachineのGitLab管理フォークで利用可能です。

ランナーの設定

このセクションでは、重要なオートスケールパラメータについて説明します。設定の詳細については、高度な設定をお読みください。

Runnerグローバルオプション

パラメータ説明
concurrent整数。グローバルに同時実行できるジョブ数を制限します。これは、定義された_すべての_ランナー、ローカルおよびオートスケールを使用するジョブ数の上限です。limit ([[runners]] セクションより) およびIdleCount ([runners.machine] セクションより) と共に、作成されるマシンの上限に影響します。

[[runners]] オプション

パラメータ説明
executor文字列です。オートスケール機能を使用するには、executordocker+machine に設定する必要があります。
limit整数。このトークンが同時に処理できるジョブの数を制限します。0 は単に制限しないことを意味します。autoscale の場合は、このプロバイダが作成するマシンの上限です (concurrentIdleCount と併用します)。

[runners.machine] オプション

設定パラメータの詳細はGitLab Runner - Advanced Configuration - The[runners.machine] sectionにあります。

[runners.cache] オプション

設定パラメータの詳細はGitLab Runner - Advanced Configuration - The[runners.cache] セクションにあります。

その他の設定情報

IdleCount = 0 を設定した場合、特別なモードもあります。このモードでは、各ジョブの前にマシンが常に オンデマンドで作成されます(_アイドル_状態の利用可能なマシンがない場合)。ジョブが終了すると、オートスケーリングアルゴリズムは以下の説明と同じように動作します。マシンは次のジョブを待機し、IdleTime 期間が経過しても実行されない場合、マシンは削除されます。ジョブがない場合、_アイドル_状態のマシンはありません。

IdleCount0 より大きい値に設定されている場合、バックグラウンドでアイドル状態の VM が作成されます。Runnerは新しいジョブを要求する前に、既存のアイドルVMを取得します。

  • ジョブがRunnerに割り当てられると、そのジョブは以前に取得したVMに送信されます。
  • ジョブがRunnerに割り当てられていない場合、アイドルVMのロックはリリースされ、VMはプールに戻されます。

Docker Machine Executorによって作成されるVMの数を制限します。

Docker Machine Executorによって作成される仮想マシン(VM)の数を制限するには、config.toml ファイルの[[runners]] セクションでlimit パラメータを使用します。

concurrent パラメータは、VM の数を制限しません

ここで詳しく説明するように、1 つのプロセスで複数の Runner Worker を管理するように設定できます。

この例では、1つの Runner プロセスのconfig.toml ファイルに設定された値を示します:

concurrent = 100

[[runners]]
name = "first"
executor = "shell"
limit = 40
(...)

[[runners]]
name = "second"
executor = "docker+machine"
limit = 30
(...)

[[runners]]
name = "third"
executor = "ssh"
limit = 10

[[runners]]
name = "fourth"
executor = "virtualbox"
limit = 20
(...)

この設定では

  • 1つのRunnerプロセスで、異なる実行環境を使用する4つの異なるRunner Workerを作成できます。
  • concurrent の値は 100 に設定されているので、この 1 つの Runner は最大 100 の GitLab CI/CD ジョブを同時に実行します。
  • second Runner WorkerだけがDocker Machine Executorを使うように設定されているので、自動的にVMを作成することができます。
  • 30limit 設定は、second Runner Worker が自動スケールされた VM 上で、いつでも最大 30 の CI/CD ジョブを実行できることを意味します。
  • concurrent が複数の[[runners]] ワーカーにわたるグローバルな同時実行数制限を定義するのに対して、limit は単一の[[runners]] ワーカーの最大同時実行数を定義します。

この例では、Runnerプロセスが処理します:

  • [[runners]] ワーカー全体で、最大 100 の同時ジョブを処理します。
  • first ワーカーでは、shell Executor で実行されるジョブは 40 以下です。
  • second ワーカーでは、docker+machine Executor で実行されるジョブは 30 以下です。さらに、Runnerは[runners.machine] のオートスケーリング設定に基づいてVMをメンテナーしますが、すべての状態(アイドル、使用中、作成中、削除中)で30VMを超えないようにします。
  • third ワーカーについては、ssh Executor で実行されるジョブは10個以下です。
  • fourth ワーカーでは、virtualbox Executor で実行されるジョブは 20 個以下です。

この2番目の例では、docker+machine Executor を使うように設定された[[runners]] ワーカーが2つあります。この設定では、各 Runner ワーカーは、limit パラメータの値によって制約される VM の個別のプールを管理します。

concurrent = 100

[[runners]]
name = "first"
executor = "docker+machine"
limit = 80
(...)

[[runners]]
name = "second"
executor = "docker+machine"
limit = 50
(...)

この例では:

  • Runner が処理するジョブは 100 件までです (concurrent の値 )。
  • Runner プロセスは 2 つの[[runners]] ワーカーでジョブを実行し、それぞれのワーカーはdocker+machine Executor を使用します。
  • first Runnerは最大80個のVMを作成できます。したがって、この Runner は任意の時点で最大 80 ジョブを実行できます。
  • second ランナーは最大 50 VM を作成できます。したがって、この Runner は任意の時点で最大 50 ジョブを実行できます。
note
制限値の合計が130 (80 + 50 = 130)であっても、グローバル・レベルでのconcurrent の値100 は、このランナー・プロセスが最大100のジョブを同時に実行できることを意味します。

オートスケーリングアルゴリズムとパラメータ

オートスケーリング・アルゴリズムは、以下のパラメータに基づいています:

  • IdleCount
  • IdleCountMin
  • IdleScaleFactor
  • IdleTime
  • MaxGrowthRate
  • limit

ジョブを実行していない各マシンを_Idle_状態と呼びます。GitLab Runnerがオートスケールモードであるとき、全てのマシンを監視し、_Idle_状態のマシンが常にIdleCount

note
GitLab Runner 14.5では、この動作を少し変更するIdleScaleFactorIdleCountMin の設定を追加しました。詳しくは専用のセクションを参照してください。

_Idle_マシンの数が不足している場合、GitLab Runner はMaxGrowthRate 制限に従って MaxGrowthRate新しいマシンのプロビジョニングを開始します。MaxGrowthRate この MaxGrowthRate値をMaxGrowthRate 超えるマシンのリクエストは MaxGrowthRate、作成されるマシンの数がMaxGrowthRate を下回るまで保留されます。

同時に、GitLab Runnerは各マシンの_Idle_状態の時間をチェックしています。時間がIdleTime の値を超えると、マシンは自動的に削除されます。


以下のオートスケールパラメータでGitLab Runnerを設定したとします:

[[runners]]
  limit = 10
  # (...)
  executor = "docker+machine"
  [runners.machine]
    MaxGrowthRate = 1
    IdleCount = 2
    IdleTime = 1800
    # (...)

ジョブがキューに入っていない最初の段階で、GitLab Runnerは2台のマシンを起動し(IdleCount = 2)、_アイドル_状態にします。また、IdleTime を30分に設定していることに注目してください (IdleTime = 1800)。

さて、GitLab CIに5つのジョブがキューイングされているとしましょう。最初の2つのジョブは_Idle_マシンに送られます。GitLab Runnerは_Idleの_数がIdleCount (0 < 2) より少ないことに気づき、新しいマシンを起動します。これらのマシンは、MaxGrowthRate を超えないように順次プロビジョニングされます。

残りの3つのジョブは、準備ができた最初のマシンに割り当てられます。最適化として、これはビジー状態であったがジョブが完了したマシンでも、新しくプロビジョニングされたマシンでもかまいません。この例では、プロビジョニングは高速で、新しいマシンのプロビジョニングは、それ以前のジョブが完了する前に完了したと仮定します。

1台の_Idle_マシンができたので、GitLab RunnerはIdleCount を満たすためにもう1台の新しいマシンを起動します。キューには新しいジョブがないので、これら2台のマシンは_Idle_状態のままとなり、GitLab Runnerは満足します。


これが起こったことです:2台のマシンが_アイドル_状態で新しいジョブを待っていました。5つのジョブがキューに入った後、新しいマシンが作られ、合計で7つのマシンができました。そのうち5台はジョブを実行中で、2台は次のジョブを待つ_アイドル_状態でした。

GitLab Runnerはジョブの実行に使われたマシンごとに、IdleCount が満たされるまで新しい_Idle_マシンを作成します。これらのマシンはlimit パラメータで limit定義された数まで作成されます。limit GitLab Runner limitが作成されたマシンの総数に達したことに気づいたら、オートスケールを停止し、新しいジョブはマシンが_Idle_状態に戻り始めるまでジョブキューで待たなければなりません。

上記の例では、常に2台のアイドル状態のマシンがあります。IdleTimeIdleCount. IdleCountIdleを超えた時のみ適用されます。IdleCount 次に、マシンの数を.Idleに減らす IdleCountことを試みます。


スケールダウン:ジョブが終了すると、マシンは_アイドル_状態になり、次のジョブが実行されるのを待ちます。キューに新しいジョブがないとします。IdleTime で指定された時間が経過すると、_Idle_マシンは削除されます。この例では、30分後に全てのマシンが削除され(各マシンは最後のジョブ実行終了から30分後)、GitLab Runnerは例の最初と同じように、IdleCount の_Idle_マシンを稼働させておくようになります。


まとめると

  1. GitLab Runnerを起動します。
  2. GitLab Runnerは2台のアイドルマシンを作成します。
  3. GitLab Runnerがジョブを1つ選択
  4. GitLab Runnerは、常に2台のアイドルマシンを持つという強い要求を満たすために、もう1台マシンを作成します。
  5. ジョブが終了し、アイドル状態のマシンが3台になりました。
  6. 3台のアイドリングマシンのうち1台が、前回ジョブをピックアップした時刻からIdleTime を超えると、そのマシンは削除されます。
  7. GitLab Runnerは常に少なくとも2台のアイドルマシンでジョブの高速ピッキングを待機しています。

下記はジョブのステータスとマシンのステータスの比較表です:

Autoscale state chart

concurrent,limit,IdleCount がどのように稼働マシンの上限を生成するか。

limitconcurrent に何を設定すればよいかを教えてくれる魔法の方程式は存在しません。ニーズに合わせて行動してください。IdleCount の_アイドル_マシンを持つことはスピードアップ機能です。インスタンスが作成されるまで10秒、20秒、30秒待つ必要はありません。しかし、ユーザーとしては、(お金を払う必要のある)すべてのマシンが_アイドル_状態ではなく、ジョブを実行していることを望むでしょう。そのため、concurrentlimit は、あなたがお金を払ってもいいと思うマシンの最大数を実行する値に設定する必要があります。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 台しか持つことができません。

IdleScaleFactor 戦略

GitLab Runner 14.6 で実験的な機能として導入されました。

IdleCount パラメーターは、Runner が維持すべき_アイドル_マシンの数を定義します。割り当てる値はユースケースによって異なります。

_アイドル_状態のマシンの数を合理的な少 数に設定することから始め、現在の使用状況に応じて自動的に大きな数に調整することができます。そのためには、実験的なIdleScaleFactor 設定を使用します。

caution
IdleScaleFactor 内部的にはfloat64 の値で、例えば float フォーマットを使用する必要があります:0.0または1.0 または ,1.5 など。整数フォーマットが使用される場合 (例えばIdleScaleFactor = 1)、Runnerの処理はエラー:IdleScaleFactor で失敗します。

この設定を使用すると、GitLab Runnerは定義された数のマシンを_アイドル_状態で維持しようとします。しかし、この数はもはや固定ではありません。IdleCount を使用する代わりに、GitLab Runner は現在使用されているマシンの数をチェックし、その数の係数として望ましい_アイドル_容量を定義します。

もちろん、現在使われているマシンがなければ、IdleScaleFactor 、メンテナーする_アイドルの_マシンはないと評価されます。オートスケーリングアルゴリズムがどのように機能するかのため、もしIdleCount0 より大きい場合(そしてその場合のみ、 がIdleScaleFactor 適用されます)、Runnerは処理できる_アイドル_マシンがない場合、ジョブを要求しません IdleScaleFactor 00 IdleScaleFactor 新しいジョブがなければ、使用されるマシンの数は増えないので、 IdleScaleFactor常に. 0そして、これはRunnerを使用できない状態でブロックします。

そこで、2つ目の設定IdleCountMin 。この設定は、IdleScaleFactor がどのように評価されようとも、維持する必要のある_アイドル_マシンの最小数を定義します。** IdleScaleFactor を使用する場合、この設定を1未満に設定することはできません。その場合、Runnerは自動的に1に設定します。**

また、IdleCountMin を使用して、常に利用可能であるべき_アイドル_マシンの最小数を定義することもできます。これにより、キューに入る新しいジョブが迅速に開始できるようになります。IdleCount と同様に、割り当てる値は使用ケースによって異なります。

使用例:

concurrent=200

[[runners]]
  limit = 200
  [runners.machine]
    IdleCount = 100
    IdleCountMin = 10
    IdleScaleFactor = 1.1

この場合、Runnerが決定ポイントに近づくと、現在使用中のマシンの台数をチェックします。現在、_アイドル_マシンが5台、使用中のマシンが10台あるとします。これにIdleScaleFactor をかけると、Runnerは11台の_アイドル_マシンを持つべきだと判断します。そこで、さらに6台が作られます。

_アイドル_マシンが90台、使用中のマシンが100台の場合、IdleScaleFactor、GitLab Runnerは100 * 1.1 = 110 _アイドル_マシンがあるべきだと判断します。そこで、また新しいマシンを作り始めます。しかし、100 _アイドル_マシンの数に達すると、これがIdleCount で定義された上限であることを認識し、それ以上の_アイドル_マシンは作成されません。

使用中の100台の_Idle_マシンが20台まで減ると、望ましい_Idle_マシンの数は20 * 1.1 = 22 、GitLab Runnerはマシンをゆっくりと終了させ始めます。上述したように、GitLab RunnerはIdleTime に使われなかったマシンを削除します。そのため、多すぎる_Idle_VMの削除があまり積極的に行われることはありません。

_Idle_マシンの数が0になった場合、望ましい_Idle_マシンの数は0 * 1.1 = 0 。しかし、これは定義されたIdleCountMin の設定より少ないため、Runnerは10台が残るまで、ゆっくりと_アイドル_VMの削除を開始します。その後、スケールダウンは停止し、Runnerは10台のマシンを_アイドル_状態に維持します。

オートスケール期間の設定

GitLab Runner 13.0で導入されました。

オートスケーリングは期間によって異なる値を設定することができます。組織には、ジョブが大量に実行される時間帯と、ジョブがほとんど実行されない時間帯があります。例えば、ほとんどの営利企業は月曜日から金曜日まで、午前10時から午後6時までといった決まった時間帯に働いています。それ以外の週の夜間や週末には、パイプラインは開始されません。

これらの時間帯は、[[runners.machine.autoscaling]] のセクションで設定できます。それぞれのセクションはIdleCountIdleTimePeriods のセットに基づいて設定します。

オートスケーリング期間の仕組み

[runners.machine] 設定では、複数の[[runners.machine.autoscaling]] セクションを追加できます。各セクションは、それぞれ独自のIdleCountIdleTimePeriodsTimezone プロパティを持ちます。最も一般的なシナリオから最も具体的なシナリオの順に、設定ごとにセクションを定義する必要があります。

すべてのセクションが解析されます。現在時刻に最後にマッチしたものがアクティビティとなります。一致するものがない場合は、[runners.machine] のルートの値が使われます。

使用例:

[runners.machine]
  MachineName = "auto-scale-%s"
  MachineDriver = "google"
  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~16:59(UTC)の間、オペレーション時間中の大量のトラフィックを処理するためにマシンがオーバープロビジョニングされます。週末には、IdleCount 、トラフィックの減少を考慮して5に低下します。それ以外の時間は、ルート内のデフォルト値、IdleCount = 10IdleTime = 1800 を使用します。

note
指定した期間の最後の59秒は、その期間の一部とはみなされません。詳しくはイシュー#2170を参照してください。

例えば、"Australia/Sydney" のように、期間のTimezone を指定することができます。指定しない場合、すべてのランナーのホストマシンのシステム設定が使用されます。このデフォルトは、Timezone = "Local" と明示的に指定することができます。

[[runner.machine.autoscaling]] セクションの構文の詳細については、GitLab Runner - Advanced Configuration - The[runners.machine] sectionを参照してください。

オフピーク時間モード設定(非推奨)

この設定は非推奨であり、GitLab Runner 14.0で削除されました。

オートスケールは_オフピークタイムモード_期間では設定できなくなりました。代わりにオートスケール期間に変換してください。

オフピーク設定からオートスケール設定への変換

オフピーク設定をオートスケーリング設定に変換するには、[[runners.machine.autoscaling]] セクションを作成し、以下のように入力します:

  • Periods フィールドにはOffpeakPeriods
  • IdleCount フィールドにはOffpeakIdleCount
  • IdleTime フィールドにはOffpeakIdleTime
  • Timezone フィールドにはOffpeakTimezone

例として、以下のOffpeak設定の変換を考えてみましょう:

[runners.machine]
  MachineName = "auto-scale-%s"
  MachineDriver = "google"
  IdleCount = 10
  IdleTime = 1800
  OffPeakPeriods = ["* * 9-17 * * mon-fri *"]
  OffPeakIdleCount = 50
  OffPeakIdleTime = 3600
  OffPeakTimezone = "UTC"

変換結果は以下のようになります:

[runners.machine]
  MachineName = "auto-scale-%s"
  MachineDriver = "google"
  IdleCount = 10
  IdleTime = 1800
  [[runners.machine.autoscaling]]
    Periods = ["* * 9-17 * * mon-fri *"]
    IdleCount = 50
    IdleTime = 3600
    Timezone = "UTC"

分散Runnerキャッシング

note
分散キャッシュの使い方をお読みください。

ジョブを高速化するために、GitLab Runnerは選択したディレクトリやファイルを保存し、後続のジョブ間で共有するキャッシュメカニズムを提供します。

これは同じホスト上でジョブが実行されている場合には問題なく機能しますが、GitLab 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 Machineと使用されている全てのレジストリ間のプロキシを提供します。イメージはレジストリミラーによって一度だけダウンロードされます。新しいホスト、またはイメージが利用できない既存のホストでは、設定されたレジストリミラーからイメージがダウンロードされます。

ミラーがDocker Machine 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.tomlgoogle 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.7"               # The default image used for jobs is 'ruby:2.7'
  [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 = "google" # Refer to Docker Machine docs on how to authenticate: https://docs.docker.com/machine/drivers/gce/#credentials
    MachineOptions = [
      "google-project=GOOGLE-PROJECT-ID",
      "google-zone=GOOGLE-ZONE", # e.g. 'us-central-1'
      "google-machine-type=GOOGLE-MACHINE-TYPE", # e.g. 'n1-standard-8'
      "google-machine-image=ubuntu-os-cloud/global/images/family/ubuntu-1804-lts",
      "google-username=root",
      "google-use-internal-ip",
      "engine-registry-mirror=https://mirror.gcr.io"
    ]
    [[runners.machine.autoscaling]]  # Define periods with different settings
      Periods = ["* * 9-17 * * mon-fri *"] # Every workday between 9 and 17 UTC
      IdleCount = 50
      IdleCountMin = 5
      IdleScaleFactor = 1.5 # Means that current number of Idle machines will be 1.5*in-use machines,
                            # no more than 50 (the value of IdleCount) and no less than 5 (the value of IdleCountMin)
      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 パラメータには、Docker MachineがGoogle Compute Engine上でホストされているマシンを起動するために使用するgoogle ドライバのオプションと、Docker Machine自体のオプション (engine-registry-mirror) が含まれていることに注意してください。