GitHub ActionsのSelf Hosted Runnerでキャッシュを高速化する

kubernetes
gha

2025-10-07

#はじめに

GitHub ActionsのSelf Hosted Runnerでキャッシュを高速化したいと思います。
k8sではActions Runner Controller(ARC)をデプロイすることで、容易にSelf Hosted Runnerを導入することができますが、キャッシュが遅いのが悩みでした。

#なぜSelf Hosted Runnerだとキャッシュが遅いのか

下記の資料を参考にさせていただきました。

self-hosted runnerと actions/cache の噛み合わせが悪かった件 #githubactionsmeetup
Talked by <a href="https://gaugt.connpass.com/event/292175/">GitHub Actions Meetup Tokyo #2</a>
self-hosted runnerと actions/cache の噛み合わせが悪かった件 #githubactionsmeetup favicon speakerdeck.com
self-hosted runnerと actions/cache の噛み合わせが悪かった件 #githubactionsmeetup

GitHub ActionsではAzure blob storageを使っているようですが、GitHub Actionsの外からだとスループットがかなり下がるようです。

#解決策

actions/cacheを利用せず、キャッシュのバックエンドを選べるようなアクションを使えば良さそうです。

#runs-onとMinio

独自キャッシュのアクションは多数あります。今回は、runs-on/cacheとストレージにMinioを組み合わせました。

GitHub - runs-on/cache: Shockingly faster GitHub Action cache with S3 backend
Shockingly faster GitHub Action cache with S3 backend - runs-on/cache
GitHub - runs-on/cache: Shockingly faster GitHub Action cache with S3 backend favicon github.com
GitHub - runs-on/cache: Shockingly faster GitHub Action cache with S3 backend
S3 cache for GitHub Actions
Use an S3 bucket as a cache backend for your actions, to enjoy faster download and upload speeds + unlimited cache sizes
S3 cache for GitHub Actions favicon runs-on.com
S3 cache for GitHub Actions
GitHub - minio/minio: MinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.
MinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license. - minio/minio
GitHub - minio/minio: MinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license. favicon github.com
GitHub - minio/minio: MinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.

#事前準備

helmfileでk8sにデプロイする前提で記載します。

  • arc

arcはvaluesは空でそのままデプロイしました。

# helmfile.yaml
releases:
  - name: arc
    chart: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
    namespace: arc-systems
    version: 0.12.1
    inherit:
      - template: default

参考:

アクション ランナー コントローラーのクイック スタート - GitHub Enterprise Cloud Docs
アクション ランナー コントローラーのクイック スタート - GitHub Enterprise Cloud Docs favicon docs.github.com
アクション ランナー コントローラーのクイック スタート - GitHub Enterprise Cloud Docs
  • arc-runner-set

続いてランナースケールセットをデプロイします。

# helmfile.yaml
releases:
  # REF: https://github.com/actions/actions-runner-controller/tree/master/charts/gha-runner-scale-set
  - name: arc-runner-set
    chart: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
    namespace: arc-runners
    version: 0.12.1
    inherit:
      - template: default

GITHUB_CONFIG_URL,GITHUB_APP_ID,GITHUB_APP_INSTALLATION_ID,GITHUB_APP_PRIVATE_KEYプレースホルダーです。runnerにはカスタムイメージを指定しています。
githubConfigSecretに設定する値は、helm secretなどで暗号化するなどして秘匿情報として管理しましょう。

# values.yaml
## githubConfigUrl is the GitHub url for where you want to configure runners
## ex: https://github.com/myorg/myrepo or https://github.com/myorg or https://github.com/enterprises/myenterprise
githubConfigUrl: "${GITHUB_CONFIG_URL}"
controllerServiceAccount:
  name: arc-gha-rs-controller
  namespace: arc-systems

template:
  spec:
    containers:
      - name: runner
        image: ghcr.io/cloudandbuild/cloudandbuild-helmfile/actions-runner:2.328.0
        command: ["/home/runner/run.sh"]
githubConfigSecret:
    github_app_id: "${GITHUB_APP_ID}"
    github_app_installation_id: "${GITHUB_APP_INSTALLATION_ID}"
    github_app_private_key: "${GITHUB_APP_PRIVATE_KEY}"

参考:

アクション ランナー コントローラーを使用してランナー スケール セットをデプロイする - GitHub Enterprise Cloud Docs
アクション ランナー コントローラーを使用してランナー スケール セットをデプロイする - GitHub Enterprise Cloud Docs favicon docs.github.com
アクション ランナー コントローラーを使用してランナー スケール セットをデプロイする - GitHub Enterprise Cloud Docs

Goでビルドするときにmakeを使っているのですが、runnerのデフォルトのイメージは、makeコマンドを含んでいなかったので、カスタムイメージを作りました。

FROM ghcr.io/actions/actions-runner:2.328.0
USER root
RUN apt-get update -qy \
    && apt-get install -y --no-install-recommends --fix-missing \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /home/runner
USER runner
  • Minio

ストレージにはMinioを利用します。

# helmfile.yaml
releases:
  - name: minio
    chart: oci://registry-1.docker.io/bitnamicharts/minio
    namespace: minio
    version: 17.0.16
    inherit:
      - template: default

MINIO_ROOT_USER, MINIO_ROOT_PASSWORDはプレースホルダーです。デフォルトでcacheというバケットが作られるようにしておきます。

# values.yaml
image:
  debug: false
defaultBuckets: "cache"
resourcesPreset: large
auth:
    rootUser: "${MINIO_ROOT_USER}"
    rootPassword: "${MINIO_ROOT_PASSWORD}"
  • github repostory secret

前述で設定したMINIO_ROOT_USER, MINIO_ROOT_PASSWORDをGitHub Repository Secretとして設定します。後述のGitHub Actionsのワークフローで参照します。

#動作確認

下記は、workflowの抜粋です。Goのビルドをします。

jobs:
  build:
-   runs-on: ubuntu-latest
+   runs-on: arc-runner-set
    permissions:
      contents: 'read'
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-go@v6
        with:
          go-version: 1.25
-         cache: true
-         cache-dependency-path: '**/*.sum'
+         cache: false
+     - uses: runs-on/cache@v4
+       with:
+         path: |
+           ~/go/pkg/mod
+           ~/.cache/go-build
+         key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+         restore-keys: |
+             ${{ runner.os }}-go-
+       env:
+         RUNS_ON_S3_BUCKET_CACHE: 'cache'
+         AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ROOT_USER }}
+         AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_ROOT_PASSWORD }}
+         AWS_ENDPOINT_URL: 'http://minio.minio.svc.cluster.local:9000'
+         AWS_REGION: 'auto'
+         AWS_S3_FORCE_PATH_STYLE: 'true'

#ビルド結果

  1. 変更前、actions/setup-goのキャッシュを利用する設定でキャッシュヒット無し
  2. 変更後、self hosted runnerでruns-on/cacheを利用する設定でキャッシュヒット無し
  3. 変更後、self hosted runnerでruns-on/cacheを利用する設定でキャッシュヒット有り

#ビルド結果を考察

  • Minioには1.2GB程度のGoのキャッシュが保存されていました
  • 本論とは関係ないですが、ビルド結果2でビルド結果1と比較して3倍近く早くなりました。セルフホストでCPU論理コア数が16個あるので、それが効いています。
  • ビルド結果2でPost Run runs-on/cache@v4が2分強程度。キャッシュの圧縮が想像より遅い
  • ビルド結果3でRun runs-on/cache@v4で30秒程度。S3 bucketからキャッシュを取得するのは450MBs/sec前後出ているので、本家のactions/cacheと比べても早い。

#課題

  • Post Run runs-on/cache@v4が遅い

    前述の通り。原因は調査中。

  • minioを大規模に運用するのは困難

    今回はオンプレミスのk8sにデプロイしたのでMinioを利用しましたが、EKSだったらS3、GKEならCloud Storageを選ぶのが良いでしょう。

  • github actionsのcache書き換え

    runs-on/cacheを使うよう書き換えています。追加でS3へのアクセス情報や資格情報を記載するのが冗長な感じがします。

  • セルフホストするのに人的コストがかかる

    cacheとは関係ないですが、セルフホストでコンピューティングコストをGitHub Actionsより削減して安くできるかもしれません。しかし、コンピューティングコストとは別にSelf Hosted Runnerの構築や運用にかかる人的コストが発生するので、TCOで安くなるのか判断する必要があると思います。またはSelf Hosted Runnerじゃないと解決できない課題があるのかを検討する必要があると思います。

#まとめ

GitHub ActionsのSelf Hosted Runnerでキャッシュを高速化について記載しました。
以前、Self Hosted Runnerを導入したけど、キャッシュが遅いのが悩みでした。
今回、runs-on/cacheとMinioを組み合わせることで、高速化できたので回数などを気にせずSelf Hosted Runnerをどんどん使っていこうと思いました。