建置 K8s Native 的 CI/CD 引擎:GitHub Actions Runner Controller

更新 發佈閱讀 19 分鐘

1. 決策背景:為什麼我們需要自建 Runner? (Context & Motivation)

在導入 ARC 之前,我們的 CI/CD 環境面臨以下 5 大現況與挑戰,這促使我們尋求容器化的解決方案:

  1. 成本與額度限制: GitHub Official Hosted Runners 雖然方便,但有免費分鐘數限制與併發數 (Concurrency) 限制。隨著專案擴大,容易遇到排隊或額度耗盡的問題。
  2. 缺乏專用基礎設施: Organization 目前沒有配置專門用於 CI/CD 的實體機或虛擬機 (VM),導致建置資源不穩定。
  3. 既有資源最大化: Org 內部已經維運一套穩定的 RKE2 Kubernetes Cluster。利用現有的 K8s 算力來跑 Runner,既不用額外採購機器,也能統一維運管理。
  4. 安全性考量 (Supply Chain Security): 我們希望對執行環境有 100% 的掌控權。直接使用 Docker Hub 上第三方個人維護的 Runner Image 存在資安風險;透過 ARC,我們可以使用官方 Image 或自行建置安全合規的基底映像檔。
  5. 維運彈性與擴展性 (Scalability): GitHub 官方建議的「在 Windows/Linux/macOS 直接安裝 Binary」方式屬於「寵物模式 (Pet)」,維護困難、無法自動水平擴展,且遷移時需要重新設定環境。我們需要的是「免洗筷模式 (Cattle)」,能隨用隨丟、自動擴展。

2. 什麼是 ARC?它的優勢

導入 Actions Runner Controller (ARC) 後,我們解決了上述痛點:

  • 自動擴展 (Auto-scaling):有任務時自動在 K8s 建立 Pod,沒任務時自動歸零,完美利用 RKE2 資源。
  • 環境隔離 (Ephemeral):每次跑完任務就銷毀容器,保證環境乾淨,不會有殘留檔案污染下一次建置。
  • GitOps 管理:所有設定(權限、映像檔、資源限制)皆透過 Helm Chart 與 YAML 管理 (IaC),告別手動 SSH 進機器設定的時代。

架構簡介

ARC 的運作分為兩個核心部分:

  1. Controller:負責監聽 GitHub 的 Webhook,當發現有 Workflow 處於 Queued 狀態時,指揮 K8s 建立 Runner。
  2. Runner Scale Set:實際執行任務的 Pod。我們採用 Docker-in-Docker (DinD) 模式,讓我們可以在 Runner 裡面執行 docker build 指令。

3. 關鍵前置設定:建立 GitHub App

為了讓 K8s 能夠合法的向 GitHub 申請 Runner,我們不使用個人的 Access Token (PAT),而是建立一個 GitHub App。 這有兩個好處:

  1. 不受個人離職影響:App 屬於組織,不會因為某個員工離職導致 CI/CD 全掛。
  2. API Rate Limit 更高:GitHub App 的 API 呼叫額度遠高於個人帳號。

Step 1: 建立 App

  1. 進入 Organization Settings (組織設定)
vocus|新世代的創作平台
  1. 左側選單滑到最下方:Developer settings > GitHub Apps
vocus|新世代的創作平台
  1. 左側選單滑到最下方:Developer settings > GitHub Apps
vocus|新世代的創作平台
  1. 點擊右上角 New GitHub App
vocus|新世代的創作平台
  1. 填寫基本資料:
    • GitHub App name: 取個易辨識的名字,例如 arc-runner-my-org (全網唯一,若重複請加後綴)
      • 這邊範例取 tw-aquaman-arc-demo-app
    • Homepage URL: 填寫公司官網或組織 GitHub 網址即可 (例如 https://github.com/my-org)
      • 這邊範例取 https://github.com/tw-aquaman
    • Webhook取消勾選 (Active)
      • 說明:新版 ARC (Scale Set) 採主動連線 (Long Polling),無需對外開放 K8s Public IP,內網環境更安全
vocus|新世代的創作平台
vocus|新世代的創作平台

 

Step 2:設定權限 (Permissions)

這是 ARC 能否正常運作的核心。請精確設定以下權限:

  • Repository permissions (儲存庫權限)
    • ActionsRead-only (讓 Controller 能讀取 Workflow 檔案)
    • MetadataRead-only (預設必選)
vocus|新世代的創作平台
  • Organization permissions (組織權限)
    • Self-hosted runnersRead and write (若未開啟此權限,註冊時將回傳 403 Error)
vocus|新世代的創作平台

(設定完後,點擊最下方的 Create GitHub App)

Step 3:取得憑證 (Credentials)

建立成功後,您會進入 App 的設定頁面,請收集以下三樣東西:

  1. App ID: 頁面上方會顯示 (例如 2681460)。
vocus|新世代的創作平台
  1. Private Key(私鑰):
    • 滑到頁面最下方 Private keys 區塊。
    • 點擊 Generate a private key
    • 電腦會自動下載一個 .pem 檔案
    • 注意:這是唯一的鑰匙,請妥善保存,不要 commit 到 git repo 中! 
vocus|新世代的創作平台
vocus|新世代的創作平台

Step 4:安裝 App 到組織並取得 Installation ID

App 建立好只是「存在」而已,必須「安裝」到組織才算生效。

  1. 點擊左側 Install App > 選擇組織 > Install
vocus|新世代的創作平台
  1. 選擇 All repositories 或特定 Repo,點擊 Install。
vocus|新世代的創作平台
  1. 獲取 Installation ID:
    • 安裝完成後,網頁會跳轉到該 App 在組織內的設定頁。
    • 請看瀏覽器的網址列,以範例來說是 https://github.com/organizations/tw-aquaman/settings/installations/104849848
    • 最後面那串數字 104849848 就是 Installation ID
    • (請務必記錄下來,這跟 App ID 是不一樣的!)
vocus|新世代的創作平台
vocus|新世代的創作平台

4. K8s 部署實作 (Helm Chart)

4.1 設定環境變數

為了避免指令出錯,建議先將憑證資訊設為變數

export APP_ID="2681460" # Step 3 取得 
export INSTALLATION_ID="104849848" # Step 4 取得
export PRIVATE_KEY_PATH="github-arc-private-key.pem"

4.2 安裝 Controller

Controller 負責全域管理,建議安裝在獨立 Namespace。

這邊範例的 namespace 為 github-arc-systems

helm install arc \ 
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller \
--namespace github-arc-systems \
--create-namespace

4.3 配置 Runner Set (支援 Docker Build)

為了讓 Runner 能打包 Docker Image,我們需要開啟 Privileged 模式並掛載 DinD Sidecar。

所以先建立一個 values-dind.yaml 檔案。

values-dind.yaml 配置檔:

githubConfigUrl: "https://github.com/YOUR_ORG_NAME" # 替換為你的 Org 網址 
githubConfigSecret: "github-arc-secret" # 必須對應 K8s Secret 名稱

template:
spec:
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
command: ["/home/runner/run.sh"]
env:
- name: DOCKER_HOST
value: tcp://localhost:2375
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind
image: docker:dind
args: ["dockerd", "--host=tcp://0.0.0.0:2375"]
securityContext:
privileged: true
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-storage
mountPath: /var/lib/docker
volumes:
- name: work
emptyDir: {}
- name: dind-storage
emptyDir: {}

4.4 建立 Secret 與部署 Runner

將 GitHub App 憑證寫入 K8s Secret,並啟動 Runner Set。

# 1. 建立 github-arc-runners namespace 
kubectl create ns github-arc-runners

# 2. 建立 Secret (注意 Namespace 要跟 Runner 一樣)
kubectl create secret generic github-arc-secret \
--namespace github-arc-runners \
--from-literal=github_app_id=${APP_ID} \
--from-literal=github_app_installation_id=${INSTALLATION_ID} \
--from-file=github_app_private_key=${PRIVATE_KEY_PATH}

# 3. 安裝 Runner Set
helm install org-runner-set \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set \
--namespace github-arc-runners \
--values values-dind.yaml

5. 實際應用:撰寫第一個 K8s Runner Workflow

環境建置完成後,我們就可以在 GitHub Actions 中使用這個強大的 K8s Runner。與使用 GitHub 官方 Runner 唯一的區別在於 runs-on 的標籤設定。

5.1 關鍵語法:runs-on

在 Workflow YAML 中,runs-on 的值必須對應我們在 Helm 安裝時設定的 Runner Scale Set Name

  • GitHub Hosted Runnerruns-on: ubuntu-latest
  • Our K8s Runnerruns-on: org-runner-set
    • (註:org-runner-set 是我們在 Helm 安裝指令中取的名字)

5.2 範例:測試 Docker Build 功能

由於我們配置了 DinD (Docker-in-Docker) 模式,這裡提供一個測試 Docker 建置的 Workflow 範例。請在專案中建立 .github/workflows/test-arc.yml 和一個簡單的 dockerfile

test-arc.yml 配置檔:

name: Test ARC Runner 

on:
workflow_dispatch:
push:

jobs:
simple-test:
runs-on: org-runner-set ## 這裏要指定我們在 Hele 設定的名字(4.4 的第 3 步)

steps:
- name: Run Echo
run: echo "Hello! Successfully running on Rancher ARC Runner."

test-build:
runs-on: org-runner-set ## 這裏要指定我們在 Hele 設定的名字(4.4 的第 3 步)

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Wait for Docker to be ready
run: |
echo "Waiting for Docker daemon to be ready..."
timeout=60
while ! docker info > /dev/null 2>&1; do
if [ $timeout -le 0 ]; then
echo "❌ Docker daemon failed to start within 60 seconds."
exit 1
fi
echo "Sleeping... ($timeout seconds left)"
sleep 2
timeout=$((timeout - 2))
done
echo "✅ Docker is ready!"

- name: Build Docker Image
run: |
echo "🚀 Starting build..."
docker build -t test-image:v1 .

- name: Run Container Verification
run: |
echo "🧪 Testing container execution..."
docker run --rm test-image:v1

dockerfile 內容:

FROM alpine:latest 
RUN echo "🚧 Image is building on K8s Runner..." > build_log.txt
CMD ["echo", "🎉 Success! Docker-in-Docker is working perfectly!"]

把程式碼推上到 GitHub 後,到 Repo 的 Actions 點擊我們剛剛的 action 後可以看到我剛寫的 Jobs 都有被執行

vocus|新世代的創作平台

在我們的 test-build Job 也有正常執行

vocus|新世代的創作平台

6. 常見錯誤排查 (Troubleshooting)

在建置過程中,我們解決了以下幾個核心問題:

  1. Runner Pod 沒出現
    • 原因:Controller 找不到 Secret
    • 解決方案:檢查 Secret 是否建立在 github-arc-runners Namespace,且名稱與 YAML 中的 githubConfigSecret 一致。
  1. Log 顯示 403 Forbidden
    • 原因:GitHub App 權限不足
    • 解決方案:檢查 GitHub App 設定:Organization permissions -> Self-hosted runners 是否已設為 Read and write
  1. Log 顯示 "Resource not accessible"
    • 原因:誤用 Installation ID
    • 解決方案:檢查 Secret 內的 ID 是否誤填為「個人帳號安裝的 ID」,需更新為「組織安裝的 ID」。
  1. Docker Build 失敗
    • 原因:無法連線 Docker Daemon
    • 解決方案:確認 values.yaml 已設定 DOCKER_HOST 且 Sidecar 已開啟 privileged: true

7. 結論

透過 ARC,我們成功利用現有的 RKE2 K8s 資源,建立了一套低成本、高擴展、且符合資安要求的 CI/CD 基礎設施。這不僅解決了當前的額度問題,也為未來的 DevOps 流程打下標準化的基礎。

留言
avatar-img
Mingyu Chiang 的全端開發筆記
0會員
1內容數
一位熱衷於 .NET 生態系的軟體開發者。擅長以 Vue/React 打造流暢 UI,並透過 Linux、VM 與 K8s 容器化技術優化系統彈性。本空間專門收錄全端開發實務、DevOps 自動化部署與生產環境的踩坑排錯經驗,致力於將複雜的架構轉化為優雅的解決方案。
你可能也想看
Thumbnail
Redis主要是運行在Linux系統環境中的,官方下載區找不到windows安裝程式,不過微軟有維護windows版本的,可以到github release page下載安裝。 直接下載msi來安裝: 測試是否安裝成功: 回傳PONG表示服務正常。 查看版本資訊: 列出所有key:
Thumbnail
Redis主要是運行在Linux系統環境中的,官方下載區找不到windows安裝程式,不過微軟有維護windows版本的,可以到github release page下載安裝。 直接下載msi來安裝: 測試是否安裝成功: 回傳PONG表示服務正常。 查看版本資訊: 列出所有key:
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
Arduino是一個開源的電子原型平台,它讓您能夠輕鬆地創建各種互動式電子項目。在開始之前,您需要安裝Arduino的開發環境。本文將詳細說明如何在台灣使用台灣用語來安裝Arduino環境。
Thumbnail
Arduino是一個開源的電子原型平台,它讓您能夠輕鬆地創建各種互動式電子項目。在開始之前,您需要安裝Arduino的開發環境。本文將詳細說明如何在台灣使用台灣用語來安裝Arduino環境。
Thumbnail
這篇文章說明如何在Win11系統下,使用VirtualBox虛擬機器(Ubuntu Linux系統),有關於環境設定及操作方式的常見問題,例如:畫面尺寸調整、終端機開啟、剪貼簿共用及檔案共享等,並提供詳細步驟與圖示說明。
Thumbnail
這篇文章說明如何在Win11系統下,使用VirtualBox虛擬機器(Ubuntu Linux系統),有關於環境設定及操作方式的常見問題,例如:畫面尺寸調整、終端機開啟、剪貼簿共用及檔案共享等,並提供詳細步驟與圖示說明。
Thumbnail
別再用肥大的Aniconda! Miniconda下載與安裝。
Thumbnail
別再用肥大的Aniconda! Miniconda下載與安裝。
Thumbnail
Environment: GCP Linux version: CentOS 7 Laradock的初衷原是為了將Laravel環境容器化,但隨著時間的演進,慢慢包含了各種常用的工具了,如php-fpm, apache, nginx, mysql, phpmyadmin, redis等等這些常用的東
Thumbnail
Environment: GCP Linux version: CentOS 7 Laradock的初衷原是為了將Laravel環境容器化,但隨著時間的演進,慢慢包含了各種常用的工具了,如php-fpm, apache, nginx, mysql, phpmyadmin, redis等等這些常用的東
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
本文提供詳細的 Playwright 開發環境設置步驟,包括作業系統需求、VS Code 編輯器安裝、Node.js 環境配置,及如何初始化 Playwright 專案。
Thumbnail
本文提供詳細的 Playwright 開發環境設置步驟,包括作業系統需求、VS Code 編輯器安裝、Node.js 環境配置,及如何初始化 Playwright 專案。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
Note: 本筆記使用的是Windows 10作業系統 1. 下載並安裝WAMP或XAMPP等等 本文是使用wamp,這邊略過安裝教學。 2. 下載並安裝Composer 至官網下載Composer windows installer,到這一步驟時,選擇PHP版本位置: ...
Thumbnail
Note: 本筆記使用的是Windows 10作業系統 1. 下載並安裝WAMP或XAMPP等等 本文是使用wamp,這邊略過安裝教學。 2. 下載並安裝Composer 至官網下載Composer windows installer,到這一步驟時,選擇PHP版本位置: ...
Thumbnail
這篇文章記錄了將損益表變數套進Sankey Chart的過程。作者使用Threads上大神分享的練習題,逐步實作並加入註解。文章詳細介紹了每個步驟、使用的套件,以及ipynb檔案的結構和執行環境設定(Google Colab, VS Code)。
Thumbnail
這篇文章記錄了將損益表變數套進Sankey Chart的過程。作者使用Threads上大神分享的練習題,逐步實作並加入註解。文章詳細介紹了每個步驟、使用的套件,以及ipynb檔案的結構和執行環境設定(Google Colab, VS Code)。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News