2026 年每日通報的 CVE 數量比前一年多 131%。

執行器

如何更換 GitHub Actions 執行器供應商:標籤、快取、機密、計費與備援

要切換供應商,請先串接供應商(通常透過 GitHub App),將 runs-on 改為其標籤,然後執行作業。接著確認標籤變更無法處理的六件事:執行器映像檔、快取、網路身分、OIDC 信任、備援機制與計費。請先在一個儲存庫上試行,並使用只需一項變更就能復原的切換方式。

更新日期

本指南不偏向任何廠商。它說明更換 GitHub Actions 執行器供應商時會移動哪些東西、最常出問題的地方,以及如何退回。 CRACI 是我們打造的產品,也是供應商之一;它會出現在有文件佐證之事實適用的地方,並在文末有專屬章節。若要先選擇供應商,請參閱 GitHub Actions 執行器供應商比較與 GitHub 託管執行器替代方案。

切換時哪些會改變、哪些維持不變

GitHub Actions 分為兩半。GitHub 是控制平面:它儲存儲存庫與工作流程檔案、觸發事件、儲存機密、指派作業、 顯示紀錄與檢查結果、保存建置產物並簽發 OIDC 權杖。 CI 執行器則是作業實際執行的地方:一台具備映像檔、CPU、磁碟、連往網際網路的網路路徑, 通常還有本機快取的機器。GitHub 將作業指派給執行器,在作業開始時傳送作業的機密,執行器再將紀錄串流回傳。

執行器供應商只取代後半部。

項目 留在 GitHub 移至供應商
儲存庫、工作流程檔案、觸發條件是否
機密儲存是機密會在作業開始時傳送到供應商的機器
作業指派、紀錄、檢查介面是執行器將紀錄串流回傳
來自 actions/upload-artifact 的建置產物是否
OIDC 權杖簽發者是否,但權杖會標示該執行器為自架
機器、映像檔、CPU、記憶體、磁碟否是
對外網路路徑與 IP 位址否是
快取儲存空間取決於供應商取決於供應商
移轉作業的按分鐘計費否是

第三方執行器是以自架執行器的身分向 GitHub 註冊。這就是為什麼 GitHub 對自架執行器的規則也適用於它: 標籤如何分派作業、執行器群組如何限制存取、OIDC 權杖如何描述它,以及 GitHub 如何對它計費。

runs-on 變更與標籤

GitHub 會尋找符合作業 runs-on 標籤與群組的執行器。若沒有符合的執行器上線, 作業會留在佇列中,直到有執行器上線;若被指派的執行器在 60 秒內沒有接手作業,作業會重新排入佇列; 而在佇列中停留超過 24 小時的作業會失敗 (GitHub 自架執行器參考文件)。標籤打錯字,或儲存庫未安裝供應商的應用程式,都會表現為一個永遠不會開始的作業。

供應商以下列兩種方式之一指定機器:

  • 寫在標籤中。Ubicloud 使用 ubicloud-standard-2 之類的標籤,Blacksmith 使用 blacksmith-2vcpu-ubuntu-2404,Avrea 使用 avrea-ubuntu-latest-2-vcpu,ARM 機器則在標籤中加上 arm。變更規格就代表變更標籤。
  • 寫在設定步驟中。CRACI 只使用一個標籤 runs-on: craci,再由 cracicorp/setup@v1 步驟選擇規格(1 至 32 個運算單位,每單位 1 vCPU 與 3 GB,預設為 2)、 映像檔、網路政策,或以 slug 指定組織的執行器範本。若 CRACI 無法解析某個輸入,它會執行預設環境, 並在作業紀錄中寫入警告;未知的映像檔或範本則會遭到拒絕。

讓切換只需一個變數

請將標籤放在儲存庫或組織變數中,而不是寫死在程式碼裡。如此一來,切換過去或切換回來都只是設定變更, 而不需要在每個儲存庫發 pull request。

jobs:
  build:
    # Falls back to GitHub-hosted when the variable is not set
    runs-on: ${{ vars.LINUX_RUNNER || 'ubuntu-latest' }}
    steps:
      - uses: actions/checkout@v7
      - run: make build

  deploy:
    needs: build
    # Stays on GitHub-hosted until you decide to move it
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

選擇是以作業為單位,因此建置與測試作業可以移轉,部署作業則維持不變。變數可在組織層級設定, 並在個別儲存庫覆寫,因此一項設定就能移轉一整組儲存庫,個別儲存庫也能選擇不參與。

可重複使用的工作流程

如果相同的管線被複製到許多儲存庫,請將它移入可重複使用的工作流程(reusable workflow),並從輸入或變數讀取執行器。 在那裡變更 runs-on,就會變更所有呼叫它的儲存庫。規則集(ruleset)可以要求組織的儲存庫執行某個工作流程, 讓共用版本持續被使用。

執行器映像檔:相容性與版本固定

GitHub 的託管映像檔內含大量預先安裝的工具與託管工具快取。供應商提供的映像檔,要不是與 GitHub 相容,就是較為精簡。 作業經常依賴一些從未宣告的東西:

  • 預先安裝的程式語言版本與命令列工具;
  • 免密碼的 sudo,以及 systemd(供以 systemctl 啟動的服務使用);
  • 執行中的 Docker 常駐程式,以及 Buildx 與 Compose;
  • setup-* actions 在下載前會讀取的託管工具快取;
  • 大型建置所需的可用磁碟空間。

判斷原則:先使用供應商與 GitHub 相容的映像檔。等作業順利通過後,再將它移到精簡映像檔, 並為它原本隱含使用的所有項目加上明確的 setup-* 步驟。

版本固定:ubuntu-latest 會依 GitHub 的時程移至新版本,而 ubuntu-24.04 只固定作業系統版本,不固定其上的套件版本。請在作業內固定重要的項目: 以明確版本指定 setup actions,並以摘要值指定容器映像檔。請詢問各供應商允許您固定哪些項目。 執行器應用程式本身則必須持續更新,才能與 GitHub 通訊。

在 CRACI 上,映像檔包括 x86-64 與 ARM64 上的 CRACI Slim(Ubuntu 24.04,不含 systemd),以及與 GitHub Actions 完全相容的 Ubuntu 24.04 映像檔;後者以 ubuntu-24.04 或 ubuntu-latest 選用, 跟隨 GitHub 的 Ubuntu 24.04 執行器映像檔,並包含託管工具快取。所有映像檔都內含 Docker Engine、Buildx 與 Compose v2。

快取:哪些會延續、哪些從零開始

在新供應商上的最初幾次執行往往較慢,常見原因是快取還是空的,而不是機器較慢。 actions/cache 的運作方式決定了您會看到什麼 (actions/cache README):

  • 項目是依其鍵值與版本找到的,版本是快取路徑與壓縮工具的雜湊值。
  • 項目以分支為範圍;預設分支的項目可供其他分支使用。
  • 預設情況下,一個儲存庫最多可保存 10 GB 的快取,超過後會淘汰最舊的項目。儲存庫管理員以及組織或企業擁有者可以提高上限;超過 10 GB 的用量會向帳戶收費(GitHub 相依套件快取)。
  • 在 Windows 上儲存的快取不會在其他作業系統上還原,反之亦然,除非設定了 enableCrossOsArchive;使用不同的壓縮工具也會產生不同的版本。

供應商以下列兩種方式之一提供快取:

模式 最初幾次執行 取捨
執行器使用 GitHub 的快取服務,與 GitHub 託管執行器相同 既有項目可以還原 快取流量需經由網際網路在供應商與 GitHub 之間傳輸
供應商從其執行器旁的儲存空間提供快取 API 通常是空的,直到最初幾次執行將它填滿,除非供應商會匯入或回退讀取 GitHub 的項目 還原更快;寫入其中的項目通常對 GitHub 託管執行器不可見

第二點對混合機群與復原很重要:如果您將作業切換回來,它在 GitHub 上也可能從空快取開始。 請詢問供應商採用哪種模式,以及項目存放在哪裡。

分辨空快取與緩慢的執行器。以一個快取大型 node_modules 目錄的 Node 建置為例。在新供應商上第一次執行時,actions/cache 會回報未命中, 安裝步驟會下載所有內容,後置步驟則會儲存快取。從同一分支的下一次執行起,該步驟會回報命中,安裝步驟所需時間也隨之縮短。 請等快取暖機後再比較執行結果:讀取 cache-hit 輸出,並將還原步驟與安裝步驟的時間和建置本身分開計算。 關於鍵值、範圍與快取下毒,請參閱 GitHub Actions 快取的運作方式。

在 CRACI 上,actions/cache 的運作方式與現在相同,而建置紀錄會以套件為單位標示它是從 CI 快取還原,還是實際擷取的。

Docker 層快取

機制 層存放位置 須知事項
BuildKit type=gha GitHub Actions 快取 範圍與大小規則同上;需要支援它的建置器
BuildKit type=registry 您登錄庫中的另一個映像檔 可在任何執行器上運作,更換供應商後依然保留;您需支付登錄庫的儲存與傳輸費用
供應商本機的層快取或永久磁碟 位於供應商的執行器旁 通常最快;若您離開該供應商,它會留在原處

登錄庫快取是可攜的選項(Docker 快取後端):

- uses: docker/build-push-action@v7
  with:
    push: true
    tags: ghcr.io/acme/app:latest
    cache-from: type=registry,ref=ghcr.io/acme/app:buildcache
    cache-to: type=registry,ref=ghcr.io/acme/app:buildcache,mode=max

兩個同時開始的作業會還原同一份快取,並且都會建置快取中缺少的層。這在任何 CI 上都會發生, 因此請不要將它視為供應商的問題。

CRACI 提供容器層快取,包括本機層快取、遠端層快取與 bind mount 快取。

機密、OIDC 與雲端憑證

GitHub 儲存您的機密,並將它們傳送給執行作業的執行器。將作業移至供應商,就代表把該作業的機密託付給該供應商。 請詢問:

  • 每個作業擁有自己的虛擬機器,還是共用主機上的容器?
  • 機器是否會在作業結束後銷毀?是否有任何資料被保留?
  • 供應商會保留哪些紀錄?GitHub 會在作業紀錄中遮蔽已註冊的機密,但表示對經過轉換的值不保證能自動遮蔽; 也請詢問供應商自身的系統紀錄。

OIDC 仍可運作,但有一個需要注意的地方。OIDC 權杖是由 GitHub 而非執行器簽發,因此 permissions: id-token: write 在任何執行器上都能運作。但權杖的 runner_environment 宣告為 github-hosted 或 self-hosted (GitHub OIDC 參考文件), 而在第三方執行器上,它會是 self-hosted。要求 github-hosted 的雲端信任政策會拒絕該作業。例如,具有下列屬性條件的 Google Cloud 工作負載身分集區:

# Before: only GitHub-hosted runners in the acme organization
assertion.repository_owner == 'acme' && assertion.runner_environment == 'github-hosted'

# After: drop the runner check, and narrow by repository and branch instead
assertion.repository == 'acme/app' && assertion.ref == 'refs/heads/main'

移除執行器檢查會擴大可取得憑證的對象,因此請同時收緊另一項條件。在切換之前, 請搜尋每一項雲端信任政策與工作負載身分設定中的 runner_environment。

推送映像檔:GITHUB_TOKEN 只要具備 packages: write,就能從任何執行器推送到 GitHub Container Registry,使用已儲存機密的登錄庫登入方式也維持不變。

在 CRACI 上,GitHub App 會讀取您的程式碼與 Actions 執行紀錄,並管理它為您的組織註冊的執行器。 每個作業都在各自隔離的虛擬機器中執行,CRACI 不會儲存您的原始碼。

網路身分:IP 允許清單與對外連線

新的執行器會從新的 IP 位址連出。請列出所有依來源位址進行篩選的項目:

  • 資料庫與建置產物儲存庫的允許清單;
  • 設有 IP 限制的 SaaS API;
  • 合作夥伴的 SFTP 伺服器,以及位於防火牆後方的內部服務。

可行的選項是供應商的固定或穩定對外 IP 位址,或是由您掌控的代理伺服器。這也是決定作業究竟可以連線到哪裡的時機: 執行器上的對外連線(egress)政策 可以阻止遭入侵的相依套件將機密傳送到建置根本不需要的主機。請參閱 GitHub Actions 對外連線政策。

CRACI 提供穩定的對外 IP 範圍,以及可設為預設拒絕或允許的對外連線政策,政策會在作業開始前驗證, 並採失效即封鎖(fail closed)。若未設定 network 輸入,預設範本會允許其他對外連線, 因此對外連線控管需要由您自行設定。

混合機群:移轉 Linux,讓 macOS 與 iOS 留在原處

執行器是以作業為單位選擇,因此一個工作流程可以在供應商上執行其 Linux 作業,在 GitHub 託管執行器上執行其 macOS 作業。以 actions/upload-artifact 上傳的建置產物由 GitHub 儲存, 因此一個執行器上的作業可以將檔案交給另一個執行器上的作業。

jobs:
  backend:
    runs-on: ${{ vars.LINUX_RUNNER || 'ubuntu-latest' }}
    steps:
      - uses: actions/checkout@v7
      - run: ./gradlew test

  android:
    runs-on: ${{ vars.LINUX_RUNNER || 'ubuntu-latest' }}
    steps:
      - uses: actions/checkout@v7
      - run: ./gradlew assembleRelease
      - uses: actions/upload-artifact@v7
        with:
          name: android
          path: app/build/outputs/apk/release/

  ios:
    # Signing and the iOS build stay on GitHub-hosted macOS
    runs-on: macos-latest
    needs: backend
    steps:
      - uses: actions/checkout@v7
      - run: xcodebuild -scheme App -configuration Release archive

留在 GitHub 上的作業仍會使用您方案的內含額度,超出部分由 GitHub 收費。CRACI 目前在 x86-64 與 ARM64 上執行 Linux,Windows 與 macOS 已列入產品藍圖,因此搭配 CRACI 的混合機群,代表 Linux 使用 CRACI, 其餘則使用 GitHub 託管執行器。

供應商停擺時的備援

GitHub 沒有內建執行器標籤之間的備援機制。如果該標籤沒有任何執行器上線,作業就會等待, 並在 24 小時後失敗。請事先規劃:

  • 上述的變數切換:將它改回 ubuntu-latest,新的執行就會送往 GitHub 託管執行器。
  • 手動覆寫,用於緊急執行:一個 workflow_dispatch 輸入,讀取方式為 runs-on: ${{ inputs.runner || vars.LINUX_RUNNER || 'ubuntu-latest' }}。
  • 為作業設定 timeout-minutes,避免停滯的作業將部署卡住好幾個小時。
  • 監控佇列等候時間,以便在作業等待時間比平常更長時察覺。

請詢問各供應商是否提供自動備援,以及觸發條件為何。也請為另一個方向做好規劃: GitHub 負責排入佇列並指派每個作業,因此 GitHub Actions 發生服務中斷時,所有執行器供應商上的作業也都會停止。

計費:GitHub 還會收費嗎?

GitHub 不對自架執行器按分鐘收費,而第三方執行器是以自架執行器身分註冊,因此您移轉出去的分鐘數 將不再出現在 GitHub 帳單上 (GitHub Actions 計費說明)。GitHub 仍會收取:

  • 您方案中的席次費用;
  • 超出內含額度、由其保存的建置產物與快取儲存空間;
  • 留在 GitHub 託管執行器上、超出您方案內含用量的作業,且內含額度不會退還。

試行期間,您會收到兩張帳單。各供應商計算建置分鐘數的方式不同: GitHub 將每個作業無條件進位到整分鐘,有些供應商則按秒計量。要估算切換前後的用量,請使用 GitHub Actions 成本計算器。CRACI 只對 建置分鐘數收費:每 vCPU 分鐘 $0.002(預設 2 vCPU 執行器為 $0.004),按秒計量,無月費。

資安隔離:應向任何供應商詢問的問題

問題 為何重要
每個作業一台虛擬機器,還是共用主機上的容器? 共用主機會讓遭入侵的作業能觸及其相鄰作業
機器是否會在作業結束後銷毀? 持續存在的機器會將檔案、憑證與處理程序帶入下一個作業
硬體位於何處,由誰維運? 資料所在地、司法管轄權,以及您與客戶的合約
供應商會儲存哪些資料,保存多久? 紀錄、快取與網路資料可能包含敏感內容
它持有哪些認證? 您的廠商審查會問到
您能控管對外連線嗎? 阻止機密透過惡意套件外洩
它的 GitHub App 可以讀取與變更什麼? 應用程式的權限適用於您安裝它的每個儲存庫

GitHub 表示,公開儲存庫幾乎永遠不應使用自架執行器,因為任何人都能開啟 pull request 並入侵該環境;而即時(just-in-time)執行器在移除前最多只執行一個作業 (GitHub 安全使用 參考文件)。每個作業使用全新虛擬機器,就能解決大部分這類疑慮。

CRACI 的回答:每個作業都在歐洲裸機基礎架構上、各自隔離的虛擬機器中執行。CRACI Corporation Oy 針對 CRACI 平台開發與維運的資訊安全管理系統, 已取得 Into Certification 核發的 ISO/IEC 27001 認證,詳情請見 Trust Center。CRACI 會儲存建置中繼資料、套件資料、網路追蹤、SBOM、 來源證明、快取與稽核紀錄,但絕不儲存您的原始碼。請參閱 CRACI 可以存取哪些內容 與資安。

先在一個儲存庫上試用

  1. 挑選一個具代表性、經常執行 Linux 工作流程的儲存庫,而不是版本發布管線。
  2. 在 GitHub 託管執行器上記錄基準:最近 30 次執行的執行時間與佇列等候時間中位數,以及計費分鐘數。
  3. 只在該儲存庫上安裝供應商的 GitHub App。
  4. 在分支上透過儲存庫變數切換一個作業。
  5. 至少執行十次,並將前三次視為快取暖機而捨棄。
  6. 比較執行時間、佇列等候時間、快取命中率、失敗次數與成本;檢查紀錄、OIDC 與對外呼叫。
  7. 變更變數以復原,並確認作業回到 GitHub 託管執行器。
指標 GitHub 託管基準 供應商 通過門檻
作業執行時間中位數您的目標,例如縮短 30%
佇列等候時間中位數不比基準差
暖機後的快取命中率與基準相同
非程式碼造成的失敗執行無
每次執行成本低於基準
OIDC、允許清單與對外呼叫全部正常運作

請用您自己的工作流程衡量速度。每家供應商都會公布自己的數據,而唯一能決定您情況的數字, 是來自您自己管線的那一個。

CRACI 的定位

CRACI 是 GitHub Actions 執行器。它取代的是執行器,而不是 GitHub Actions:作業以 runs-on: craci 移轉,規格與映像檔透過 cracicorp/setup@v1 或組織執行器範本設定, 執行紀錄仍會顯示在 GitHub 中。憑藉更快的硬體、更短的佇列等候時間與快取,CRACI 的建置速度約為 GitHub 託管執行器的兩倍。

選擇它而非其他供應商的理由,在於每個作業留下的東西:一份記錄建置所擷取內容的 SBOM,附有 完整性狀態,並在採失效即封鎖的對外連線政策下記錄。docs.craci.com 也提供一段給程式碼代理(coding agent)使用的提示詞, 可為您的工作流程提出以作業為單位的移轉計畫。請參閱 CI/CD 整合。

CRACI 不適用的情況

  • 您需要 macOS 或 Windows 執行器:它們已列入 CRACI 的產品藍圖。
  • 您使用 GitHub Enterprise Server,而 CRACI 不支援它。
  • 您的 CI 是 GitLab CI 或 Jenkins:兩者都已列入產品藍圖。
  • 執行器必須位於您自己的雲端帳戶中:客戶自行託管執行器已列入產品藍圖。RunsOn 與 WarpBuild 的 自帶雲端選項目前就能做到;請參閱 CRACI 與 RunsOn 比較與 CRACI 與 WarpBuild 比較。
  • 您的主要目標是 CI 可觀測性與除錯;請參閱 CRACI 與 Avrea 比較。若要 自行維運執行器,請參閱代管與自架執行器比較。

更換執行器供應商:常見問題

要改用其他 GitHub Actions 執行器供應商,需要變更哪些地方?

安裝供應商的 GitHub App,再將作業的 runs-on 標籤改為供應商的標籤。工作流程、觸發條件、機密與 GitHub 介面都維持不變。在移轉重要作業之前,請先確認執行器映像檔、快取、對外 IP 位址、使用 OIDC 的雲端信任政策、備援機制與計費方式。

我的 GitHub Actions 快取會延續到新的執行器供應商嗎?

取決於供應商從哪裡提供快取。如果其執行器使用 GitHub 的快取服務,既有項目就能還原。如果它從執行器旁的儲存空間提供快取 API,快取通常會從空的開始,並在最初幾次執行時逐步填滿。請詢問供應商採用哪種模式,以及在其執行器上寫入的項目是否對 GitHub 託管執行器可見。

Docker 層快取在第三方執行器上能運作嗎?

可以,有三種機制可選:使用 Actions 快取的 BuildKit type=gha 後端;可在任何執行器上運作、採用 type=registry 的登錄庫快取;或由供應商保存在其執行器旁的層快取或永久磁碟。

Linux 作業移轉後,可以把 macOS 與 iOS 建置留在 GitHub 上嗎?

可以。執行器是以作業為單位選擇,因此在同一個工作流程中,Linux 作業可以在供應商上執行,macOS 作業則留在 GitHub 託管執行器上。以 needs: 串連它們,並透過由 GitHub 儲存的 actions/upload-artifact 與 actions/download-artifact 傳遞檔案。

如果第三方執行器停擺,作業會怎樣?有備援機制嗎?

GitHub 沒有內建執行器標籤之間的備援機制。若沒有任何上線中的執行器符合作業的標籤,作業會一直留在佇列中,並在 24 小時後失敗。請將標籤放在儲存庫或組織變數中,讓切換回來只需一項變更;設定 timeout-minutes;並詢問各供應商是否提供自己的備援機制。

機密與 OIDC 在第三方執行器上還能運作嗎?

可以。機密由 GitHub 儲存,並在作業開始時傳送到執行器;OIDC 權杖也是由 GitHub 簽發,因此 id-token: write 在任何執行器上都能運作。需要注意的是:在第三方執行器上,權杖的 runner_environment 宣告為 self-hosted,因此要求 github-hosted 的雲端信任政策會拒絕該作業。

改用其他執行器供應商後,GitHub 還會向我收取分鐘數費用嗎?

移轉出去的作業不會。第三方執行器是以自架執行器的身分向 GitHub 註冊,而 GitHub 表示自架執行器不按分鐘收費。GitHub 仍會收取席次費用、超出內含額度的儲存空間費用,以及留在 GitHub 託管執行器上之作業的費用。供應商則會另外收取自己的分鐘數費用。

如何固定執行器映像檔,避免它在我不知情時變動?

ubuntu-latest 會依 GitHub 的時程更新,而 ubuntu-24.04 只固定作業系統版本,不固定其上的套件版本。請在作業內固定重要的項目:以明確版本指定 setup actions,並以摘要值(digest)指定容器映像檔。請詢問各供應商允許您固定哪些項目;執行器應用程式本身則必須持續更新,才能與 GitHub 正常運作。

在第三方執行器上,作業之間如何隔離?

各供應商不同。請詢問每個作業是否擁有自己的虛擬機器,還是共用主機上的容器;機器是否會在作業結束後銷毀;以及供應商事後會保留哪些資料。每個作業使用全新虛擬機器是常見模式中最強的一種,因為上一個作業不會留下任何東西給下一個作業。

如何先在一個儲存庫上測試執行器供應商?

在一個儲存庫上安裝供應商的 GitHub App,在分支上透過儲存庫變數切換一個經常執行的 Linux 作業,至少執行十次,並與 GitHub 託管的基準比較執行時間、佇列等候時間、快取命中、失敗次數與成本。只要變更變數即可復原。

與我們一起移轉一個工作流程

預約示範,我們會與您一起將一個工作流程移至 CRACI,再比較執行時間、成本與它產出的 SBOM。

預約示範