APIを叩き、作成します。Group名を入れます。Setの取得、作成を行う関数を解説します。折りたたんでおりますので、興味あればご確認ください。Setの取得は、actionsClient.GetRunnerScaleSet関数で行います。以下のように、scaleSetEndpoint、runnerGroupId、runnerScaleSetNameを使用し、APIのパスを作成します。_apis/runtime/runnerscalesetsになります。Setの取得を行います。_apis/runtime/runnerscalesets対してPostメソッドをRequestして、作成します。リソースの作成の準備ができます。EphemeralRunnerSetリソースはr.createEphemeralRunnerSet関数で作成されます。EphemeralRunnerSetリソースのリストを取得し、最新のEphemeralRunnerSetリソースがない場合はr.createEphemeralRunnerSet関数が呼ばれます。}r.createEphemeralRunnerSet関数の定義は以下の通りです。r.resourceBuilder.newEphemeralRunnerSet関数で定義を作成し、ctrl.SetControllerReference関数でOwnerReferenceにAutoScalingRunnerSetリソースを親として設定後に、r.Create関数で作成といった流れとなります。nil}r.resourceBuilder.newEphemeralRunnerSet関数はEphemeralRunnerSetの定義を作成します。複数工程に分かれているので、細かく見ていきたいと思います。nil}autoscalingRunnerSet.RunnerSetSpecHash関数では、AutoScalingRunnerSetリソースの.specからHash値を求めます。このHash値をlabelKeyRunnerSpecHashラベルに入れます。labelKeyRunnerSpecHashラベルは、EphemeralRunnerSetリソースの再作成が必要かの判断に使われます。AutoScalingRunnerSetリソースの.specが変更されたら再度Hash値が求められ、labelKeyRunnerSpecHashラベルと比較することでEphemeralRunnerSetリソースが再作成されます。}余談ですが、各種ラベルやアノテーションのKeyは以下で定義されています。"runner-scale-set-name")次に、applyGitHubURLLabels関数でAutoScalingRunnerSetリソースの.Spec.GitHubConfigUrlがEnterpriseか、Organizationか、Repositoryかを判断して、LabelKeyGitHubEnterpriseまたはLabelKeyGitHubOrganizationまたはLabelKeyGitHubRepositoryラベルに値を入れます。}applyGitHubURLLabels関数の実装は面白いのですが、解説の粒度が細かくなるので今回はスコープ外とします。興味ある方は以下の折りたたみをご確認ください。nil}最後に、EphemeralRunnerSetリソースのMetadataおよびSpecに値を入れて、returnします。この定義を使って、r.createEphemeralRunnerSet関数内のr.Create関数でEphemeralRunnerSetリソースを作成します。リソースが作成済かを確認します。リソースをK8sから取得し、存在しなければlistenerFoundをfalseにします。リソースが見つからない場合、r.createAutoScalingListenerForRunnerSet関数で作成します。}r.createAutoScalingListenerForRunnerSet関数の定義は以下の通りです。imagePullSecretsを取得し、r.resourceBuilder.newAutoScalingListener関数で定義を作成し、r.Create関数で作成といった流れとなります。nil}r.resourceBuilder.newAutoScalingListener関数はEphemeralRunnerSetリソースの定義を作成します。r.resourceBuilder.newEphemeralRunnerSet関数と同様に、複数工程に分かれているので、細かく見ていきたいと思います。}次に、EphemeralRunnerSetリソースと同様にapplyGitHubURLLabels関数でAutoScalingRunnerSetリソースの.Spec.GitHubConfigUrlがEnterpriseか、Organizationか、Repositoryかを判断して、LabelKeyGitHubEnterpriseまたはLabelKeyGitHubOrganizationまたはLabelKeyGitHubRepositoryラベルに値を入れます。}最後に、AutoScalingListenerリソースのMetadataおよびSpecに値を入れて、returnします。この定義を使って、r.createAutoScalingListenerForRunnerSet関数内のr.Create関数でAutoScalingListenerリソースを作成します。Loopに再度戻ります。Loop処理を終了します。}ここまでで、AutoScaleRunnerSet、EphemeralRunnerSet、AutoScalingListenerリソースのそれぞれのリソースが作成できました。Podの作成ここからは、以下動作を解説します。Podの動作については次回に解説します。Service.各Controllerの管理対象リソース監視コードの説明のセクションで述べたように、各Controllerは自分自身も監視しています。Loopが呼ばれます。ここからは、AutoScalingListenerリソースのPod作成の流れを見ていきます。PodがWorkflowジョブの数に応じてEphemeralRunnerSetリソースの.Spec.Replicasを増やしたことをトリガーにして作成されます。この処理についても次回で解説します。AutoscalingRunnerSetの.Spec.GitHubConfigSecretに指定されているSecretを取得し、そのミラーとなるAutoScalingListener用のSecretを、r.createSecretsForListener関数で作成します。}r.createSecretsForListener関数では、Secret定義の作成、OwnerReferenceの設定と、r.Create関数での作成を行っているだけなので、深くは解説しません。return処理が少し面白いので、この部分のみ解説します。nilとあるように、ctrl.Result構造体のRequeueフィールドをtrueにしてreturnしています。これは、今まで出てきていなかった実装です。Loopが再実行されます。このため、上記コードでmirrorSecretが存在していなかった場合でも、後続処理を継続できるわけです。nil}ServiceAccount、Role、RoleBindingsを作成します。ServiceAccountとRoleが、RoleBindingsに紐づけられます。Roleの定義は特に重要なので、以降で解説します。}以下はRoleの定義の関数です。コードは今までのリソース作成関数の作りと変わりません。r.resourceBuilder.newScaleSetListenerRole関数で定義を作成し、r.Create関数でリソースを作成といった流れとなります。nil}r.resourceBuilder.newScaleSetListenerRole関数ではロールの定義を作成します。rulesForListenerRole関数で、ルールを作成して、ロール定義をreturnします。newRole}rulesForListenerRole関数がロール作成の上で、一番重要な箇所となります。EphemeralRunnerSetリソース、およびEphemeralRunnerのStatusサブリソースに対するpatch操作を許可します。Podは、EphemeralRunnerSetリソースの.Spec.ReplicasとEphemeralRunnerのStatusの変更をpatchで行います。}}Proxy経由でのGitHubとの接続もサポートされているため、以下のr.createProxySecret関数でSecretを作成します。今回は説明は割愛します。Podの作成を行います。r.Get関数でPodを取得し、存在しなければ、Podの作成します。}r.createListenerPod関数を見ていきます。コードは一部省略しています。省略している部分はProxyやTLS接続設定の箇所となります。今回は純粋なPodの作成のみを解説していきます。今回もr.resourceBuilder.newScaleSetListenerPod関数で定義を作成し、AutoScalingListenerリソースを親としてOwnerReferenceの設定、r.Create関数でリソースを作成といった流れとなります。nil}r.resourceBuilder.newScaleSetListenerPod関数でPod定義を作成します。複数工程に分かれているので、細かく見ていきたいと思います。nil}まずは、Podのコンテナで利用する環境変数を定義します。環境変数の値は、AutoScalingListeterリソースの.Specの値などです。Controllerが付与したものなどとなります。autoscalingListener.Spec.GitHubConfigUrlやautoscalingListener.Spec.MaxRunners、autoscalingListener.Spec.MinRunnersはAutoScalingRunnerSetリソースをhelmでデプロイする際のオプションの値です。ControllerがGitHubのAPI経由で取得した値です。}次に、GitHubへの接続に使用するSecretのDataを環境変数に入れます。Appかで環境変数を分けています。}最後に、Podの定義をreturnします。Podは、cmd/githubrunnerscalesetlistenerのコードを使ってGitHubとのやり取りおよび、EphemeralRunnerSetの操作を行います。してコマンド実行されています。buildされ、/github-runnerscaleset-listenerとしてdistrolessなimage内にCOPYされています。興味のある方は以下の折りたたみをご確認ください。Podが作成されます。Podが作成されました。PodがGitHubとのロングポーリングを確立することで、Workflow実行準備が完了します。Podの作成、Workflow終了時の動作をコードで追っていきます。後半は以下を参照ください。Enterpriseの導入のご支援をしております。一緒に働いていただける仲間も募集中です!今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。谷合純也AKS/ACA、GitHubをメインにインフラ系のご支援を担当しています。Engineeringの導入支援、データ&AI基盤に関連するサービスを提供しています。わたしたちは「エンジニアとお客様を笑顔にする」というVisionを掲げ、インフラエンジニアの未来を創るNeoSIerとして工夫と挑戦を行い続けます。読者になるこのブログについて引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。