GitHub Actionsの「待ち時間」に殺されるな:KEDAで構築する、無限にスケールする最強のCI/CDインフラ
「またビルド待ちか……」
GitHubホストランナーのキューで数分間足止めを食らう。あるいは、コスト削減のために立てた常駐型のセルフホストランナーが、夜間は無駄にCPUを回し、日中はリソース不足でパンクする。そんな非効率なインフラで、現代の高速デプロイを支えられるはずがない。
DevOpsの現場において、「CI/CDの実行環境」は、ただの実行場所ではなく、チームの生産性を左右する「心臓部」だ。 今回は、Kubernetesのイベント駆動オートスケーラー「KEDA」を活用し、GitHub Actionsランナーを「必要最小限のコストで、瞬時に無限増殖させる」ための極限のアーキテクチャを伝授する。
—
1. 従来のセルフホストランナー管理という「負債」
多くの現場が陥る罠は、`actions-runner-controller (ARC)` の旧来的な運用だ。
- 固定インスタンス: 常に起動し続けるため、夜間や週末は無駄なクラウド利用料が発生する。
- 静的スケーリング: HPA(Horizontal Pod Autoscaler)でCPU使用率を見ているだけでは、キューの増加には追いつけない。
私たちが目指すべきは、「イベント駆動」だ。
GitHubのWebHookやAPIをトリガーに、キューが積まれた瞬間にPodを爆速で立ち上げ、終われば即座に消滅させる。この「ゼロか全か」のスパイク運用こそが、コストとパフォーマンスの最適解である。
—
2. KEDA × ARC:次世代のスケーリングアーキテクチャ
現在、GitHub Actions Runner Controller (ARC) は KEDA とネイティブに統合されている。これを利用することで、GitHubの「未処理ジョブ数」をメトリクスとして直接監視できる。
実用的な設定:`RunnerDeployment` の最適化
以下は、本番環境で実際に叩くべき設定のベストプラクティスだ。
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: k8s-runner-pool
spec:
template:
spec:
repository: my-org/my-repo
# 実行時間を制限し、ゾンビプロセスを防止する(必須)
dockerDockerdNetwork: bridge
containers:
- name: runner
image: summerwind/actions-runner:latest
resources:
requests:
cpu: “1000m”
memory: “1Gi”
limits:
cpu: “2000m”
memory: “2Gi”
—
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: github-runner-scaler
spec:
scaleTargetRef:
name: k8s-runner-pool
minReplicaCount: 0 # 誰も使わなければ0にするのが「鉄則」
maxReplicaCount: 50 # 突発的なビルドラッシュにも対応
triggers:
- type: github-runner
metadata:
githubRunnerScaleSetName: “k8s-runner-pool”
runnerScope: “repo”
owner: “my-org”
repo: “my-repo”
# スケールダウンの猶予期間を短く設定し、即時回収する
targetWorkflowQueueLength: “1”
この設定の「魂」
- `minReplicaCount: 0`: これがコスト削減の核心。使わない時は1円もかからない。
- `targetWorkflowQueueLength: “1”`: キューが1つでも増えたらすぐにPodを増やす。待ち時間を「ミリ秒単位」で削り取る。
—
3. 開発スピードを底上げする「現場のハック」
インフラを整えただけでは足りない。エンジニア一人ひとりがCI/CDとどう向き合うかが重要だ。
① GitHub CLI (`gh`) は「空気」にせよ
Webブラウザでポチポチとアクション画面を見るのは時間の無駄だ。`gh` コマンドでターミナルから完結させる。
- 神ショートカット: `gh run watch`
ビルドログをターミナルに垂れ流す。エラーが出たらそのまま修正して `gh run rerun`。ブラウザへのコンテキストスイッチを排除する。
② `.github/workflows` の秘伝のタレ
YAMLのDRY(Don’t Repeat Yourself)を徹底せよ。
- Composite Actions: 再利用可能なビルド・テストステップを `actions/composite` で共通化。リポジトリを跨いで「ビルドの作法」を標準化する。
- Cache戦略: `actions/cache` を使うのは当たり前。キー設定に `hashFiles(‘/go.sum’)` 等を厳密に使い、キャッシュのヒット率を95%以上に保て。これだけでビルド時間は3分短縮できる。
③ チーム開発における「絶対ルール」
1. Fail-Fast: テストの依存関係を解き、失敗するテストは一番最初に走らせる。
2. Lintの強制: CIの最初のステップで `lint` を通さないPRは、マージボタンを押せなくする(GitHub Branch Protection Rules)。
3. セルフホストランナーのタグ付け: プロジェクトごとに異なるマシンスペック(GPUが必要なもの、高速IOが必要なもの)を `runs-on` のラベルで切り分ける。
—
結論:DevOpsは「待ち時間との戦い」である
KEDAによるオートスケーリングは、単なるインフラの自動化ではない。「エンジニアが思考を中断させられる時間を最小化する」ための投資だ。
ビルドを待っている間に淹れるコーヒーは美味しいかもしれないが、チームの生産性を考えれば、そのコーヒータイムは「技術的負債」である。今すぐARCとKEDAを導入し、キューの待ち時間を0に近づけろ。それが、現代のテックリードが果たすべき最初で最後の義務だ。
さあ、次はどのパイプラインを最適化する?