ARC 03 從Github Action job 到 runner pod

Github Action job 分配到集群

背景

job 是 Github Action 的基本單位,每個 job 單獨分配一個 runner。workflow 由一個或者多個 job 組成。如果用戶觸發runs-on字段為arc-runner-set的 job,那么 Github Action 服務器將 job 分配給 listener pod。

源碼

handleMessage函數主要處理2類處理服務器消息。第一類是狀態為started的 job: job 已經由服務器分配給 runner 執行。HandleJobStarted函數 job 信息局部更新給EphemeralRunner資源。

func (l *Listener) handleMessage(ctx context.Context, handler Handler, msg *actions.RunnerScaleSetMessage) error {parsedMsg, err := l.parseMessage(ctx, msg) // 解析消息l.lastMessageID = msg.MessageIdif err := l.deleteLastMessage(ctx); err != nil { // 請求服務器刪去消息return fmt.Errorf("failed to delete message: %w", err)}for _, jobStarted := range parsedMsg.jobsStarted {if err := handler.HandleJobStarted(ctx, jobStarted); err != nil {return fmt.Errorf("failed to handle job started: %w", err)}l.metrics.PublishJobStarted(jobStarted)}desiredRunners, err := handler.HandleDesiredRunnerCount(ctx, parsedMsg.statistics.TotalAssignedJobs, len(parsedMsg.jobsCompleted))l.metrics.PublishDesiredRunners(desiredRunners)return nil
}

第二類是狀態為AssignedCompleted的 job。前者是還未結束的任務,后者是已經結束的任務。
HandleDesiredRunnerCount函數首先調用setDesiredWorkerState函數計算集群的 runner 數量。

// count = parsedMsg.statistics.TotalAssignedJobs 表示未結束的 job 數量
// jobsCompleted = len(parsedMsg.jobsCompleted) 表示已經運行結束的 job 數量
func (w *Worker) setDesiredWorkerState(count, jobsCompleted int) int {// 根據用戶在 runner scale set chart 的 values.yaml 文件配置的 minRunenrs 和 maxRunners 以及分配的 job 數量綜合確定集群的 runner 數量。targetRunnerCount := min(w.config.MinRunners+count, w.config.MaxRunners)w.patchSeq++ // 批次序號+1desiredPatchID := w.patchSeqif count == 0 && jobsCompleted == 0 { // 本批次既沒有運行的 job,也沒有結束的 jobtargetRunnerCount = max(w.lastPatch, targetRunnerCount)if targetRunnerCount == w.config.MinRunners {// 運行至此,本批次沒有活躍 job,上批次也沒有活躍 job。集群處于空閑狀態desiredPatchID = 0 // 將 desiredPatchID 設為 0 用于觸發縮容}}w.lastPatch = targetRunnerCountreturn desiredPatchID
}

之后HandleDesiredRunnerCount函數將批次序號和 runner 數局部更新給EphemeralRunnerSet資源。

patch, err := json.Marshal(&v1alpha1.EphemeralRunnerSet{Spec: v1alpha1.EphemeralRunnerSetSpec{Replicas: w.lastPatch, // targetRunnerCountPatchID:  patchID, // desiredPatchID},},)

EphemeralRunnerSet控制器根據批次序號和 runner 數更改 runner 資源。主要邏輯如下:

    // total 是集群中運行的 runner pod 的數量,與 Github Action 服務器無關total := ephemeralRunnerState.scaleTotal()if ephemeralRunnerSet.Spec.PatchID == 0 || ephemeralRunnerSet.Spec.PatchID != ephemeralRunnerState.latestPatchID {defer func() {// 主動刪除已經結束的`EphemeralRunner`資源if err := r.cleanupFinishedEphemeralRunners(ctx, ephemeralRunnerState.finished, log); err != nil {log.Error(err, "failed to cleanup finished ephemeral runners")}}()log.Info("Scaling comparison", "current", total, "desired", ephemeralRunnerSet.Spec.Replicas)switch {// 集群中 runner 數量小于 job 數量,擴容case total < ephemeralRunnerSet.Spec.Replicas: // Handle scale upcount := ephemeralRunnerSet.Spec.Replicas - totallog.Info("Creating new ephemeral runners (scale up)", "count", count)if err := r.createEphemeralRunners(ctx, ephemeralRunnerSet, count, log); err != nil {log.Error(err, "failed to make ephemeral runner")return ctrl.Result{}, err}// 集群中 runner 數量大于 job 數量,說明 Github Action 服務器已經認為某些 job 結束,但是 job 對應的 runner pod 還未到結束狀態。等待 runner pod 自行結束。case ephemeralRunnerSet.Spec.PatchID > 0 && total >= ephemeralRunnerSet.Spec.Replicas:// PatchID == 0 是 setDesiredWorkerState 函數的縮容標記,避免集群空閑時仍然有 runner pod 在運行case ephemeralRunnerSet.Spec.PatchID == 0 && total > ephemeralRunnerSet.Spec.Replicas:count := total - ephemeralRunnerSet.Spec.Replicasif err := r.deleteIdleEphemeralRunners(ctx,ephemeralRunnerSet,ephemeralRunnerState.pending,ephemeralRunnerState.running,count,log,); err != nil {log.Error(err, "failed to delete idle runners")return ctrl.Result{}, err}}}

createEphemeralRunners函數創建EphemeralRunner資源。資源結構如下:

return &v1alpha1.EphemeralRunner{TypeMeta: metav1.TypeMeta{},ObjectMeta: metav1.ObjectMeta{GenerateName: ephemeralRunnerSet.Name + "-runner-", // k8s 自動為EphemeralRunner 資源名稱創建隨機后綴,因為一個 EphemeralRunnerSet 對應多個 EphemeralRunner 資源Namespace:    ephemeralRunnerSet.Namespace,Labels:       labels,Annotations:  annotations,OwnerReferences: []metav1.OwnerReference{{APIVersion:         ephemeralRunnerSet.GetObjectKind().GroupVersionKind().GroupVersion().String(),Kind:               ephemeralRunnerSet.GetObjectKind().GroupVersionKind().Kind,UID:                ephemeralRunnerSet.GetUID(),Name:               ephemeralRunnerSet.GetName(),Controller:         boolPtr(true),BlockOwnerDeletion: boolPtr(true),},},},Spec: ephemeralRunnerSet.Spec.EphemeralRunnerSpec,}

EphemeralRunner控制器根據EphemeralRunner資源創建 runner pod。步驟如下:

  1. 添加 finalizer 字段。finalizer表示在集群中注銷本資源。runner-registration-finalizer表示在 Github Action 服務器注銷本資源。
const (ephemeralRunnerFinalizerName        = "ephemeralrunner.actions.github.com/finalizer"ephemeralRunnerActionsFinalizerName = "ephemeralrunner.actions.github.com/runner-registration-finalizer"
)
  1. 向 Github Action 服務器注冊自身。返回 RunnerId 表示注冊成功。
type RunnerScaleSetJitRunnerSetting struct {Name       string `json:"name"`WorkFolder string `json:"workFolder"`
}
// jit(Just-in-Time) config:服務器返回的注冊信息
// jitSettings 的類型是 RunnerScaleSetJitRunnerSetting。包含 runner 名稱以及工作目錄。
// RunnerScaleSetId: runner 所屬 runner scale set 的注冊Id
jitConfig, err := actionsClient.GenerateJitRunnerConfig(ctx, jitSettings, ephemeralRunner.Spec.RunnerScaleSetId)// 更新 EphemeralRunner 資源
err = patchSubResource(ctx, r.Status(), ephemeralRunner, func(obj *v1alpha1.EphemeralRunner) {obj.Status.RunnerId = jitConfig.Runner.Id // runner idobj.Status.RunnerName = jitConfig.Runner.Name // runner 名稱obj.Status.RunnerJITConfig = jitConfig.EncodedJITConfig // 配置 secret})
  1. 將 RunnerJITConfig 注冊為 secret, runner pod 將通過 config 與 Github Action 服務器連接。
    return &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name:      ephemeralRunner.Name,Namespace: ephemeralRunner.Namespace,},Data: map[string][]byte{jitTokenKey: []byte(ephemeralRunner.Status.RunnerJITConfig),},}
  1. 創建 runner pod。runner pod 的鏡像是ghcr.io/actions/actions-runner。它將與 Github Action 服務器建立連接。服務器分配 job 給 runner pod,服務器將 job 的任務內容交給 runner pod 執行。執行完成后,runner pod 結束。
c.Env = append(c.Env,corev1.EnvVar{Name: EnvVarRunnerJITConfig,ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: secret.Name,},Key: jitTokenKey, // 將 RunnerJITConfig secret 掛載給 runner container。},},},
)
  1. 監控 runner container 的狀態。

總結

本文講了 Github Action job 到 runner pod 的執行流程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89299.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89299.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89299.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ubuntu 22.04 anaconda comfyui安裝

背景&#xff1a; 戴爾R740服務器&#xff0c;安裝了proxmox操作系統&#xff0c;配置了顯卡直通。創建了一個ubuntu 22.04 VM虛擬機實例&#xff0c;并安裝了顯卡驅動與cuda等相關配置&#xff1a; 接下來準備搭建一套comfyui的環境&#xff0c;前段時間B站&#xff0c;抖音各…

每日面試題04:volatile字段的原理

在之前面試題02ConcurrentHashMap的底層原理中提到了volatile修飾符&#xff0c;在多線程編程的世界里&#xff0c;數據同步是一道繞不開的坎。當多個線程同時操作共享變量時&#xff0c;“看不見對方的修改”或“代碼順序錯亂”往往會導致程序行為異常。而 volatile作為 Java …

【云原生網絡】Istio基礎篇

文章目錄概述基礎知識技術架構概述數據平面核心組件網絡代理Envoy控制平面核心組件xDS協議Pilot組件其他概述參考博客&#x1f60a;點此到文末驚喜?? 概述 基礎知識 背景知識 服務網格&#xff08;Service Mesh&#xff09;&#xff1a;獨立于應用程序的基礎設施層&#x…

PySpark Standalone 集群

一、PySpark Standalone 集群概述PySpark Standalone 集群是 Apache Spark 的一種部署模式&#xff0c;它不依賴于其他資源管理系統&#xff08;如 YARN 或 Mesos&#xff09;&#xff0c;而是使用 Spark 自身的集群管理器。這種模式適合快速部署和測試&#xff0c;尤其在開發和…

圖像質量評價(Image Quality Assessment,IQA)

文章目錄圖像質量評價&#xff08;Image Quality Assessment&#xff0c;IQA&#xff09;一、評估方式&#xff1a;主觀評估 客觀評估1.1、主觀評估方式1.2、客觀評估方式&#xff1a;全參考 半參考 無參考&#xff08;1&#xff09;全參考的方法對比&#xff08;Full-Refer…

【跟我學YOLO】(2)YOLO12 環境配置與基本應用

歡迎關注『跟我學 YOLO』系列 【跟我學YOLO】&#xff08;1&#xff09;YOLO12&#xff1a;以注意力為中心的物體檢測 【跟我學YOLO】&#xff08;2&#xff09;YOLO12 環境配置與基本應用 【跟我學YOLO】&#xff08;3&#xff09;YOLO12 用于診斷視網膜病變 【跟我學YOLO】&a…

Python爬蟲實戰:研究openpyxl庫相關技術

1. 引言 在當今數字化時代,互聯網上蘊含著海量有價值的數據。如何高效地獲取這些數據并進行分析處理,成為數據科學領域的重要研究方向。網絡爬蟲作為一種自動化的數據采集工具,可以幫助我們從網頁中提取所需的信息。而 openpyxl 作為 Python 中處理 Excel 文件的優秀庫,能…

Redis學習其一

文章目錄1.NoSQL概述1.1概述1.2Nosql的四大分類2.Redis入門2.1概述2.2基礎知識2.2.1基礎命令/語法2.2.2Redis為什么單線程還這么快2.3性能測試3.五大數據類型3.1Redis-key3.2String(字符串)3.3List(列表)3.4Set(集合)3.5Hash&#xff08;哈希&#xff09;3.6Zset&#xff08;有…

高性能架構模式——高性能緩存架構

目錄 一、引入前提二、緩存架構的設計要點2.1、緩存穿透2.1.1、緩存穿透第一種情況:存儲數據不存在2.1.2、緩存穿透第二種情況:緩存數據生成耗費大量時間或者資源2.2、緩存雪崩2.2.1、解決緩存雪崩的第一種方法:更新鎖機制2.2.2、解決緩存雪崩的第二種方法:后臺更新機制2.3…

ubuntu+windows雙系統恢復

文章目錄前言一、恢復windows1.直接在grub命令行輸入exit退出2.手動查找windows引導文件先ls列出所有磁盤和分區查找各個分區是否包含引導文件設置引導分區以及引導文件路徑啟動windows二、在windows系統下刪除Ubuntu殘留引導文件三、準備ubuntu系統引導盤四、安裝ubuntu系統五…

使用Dify構建HR智能助理,深度集成大模型應用,賦能HR招聘管理全流程,dify相關工作流全開源。

HR智能助理系統 &#x1f4cb; 項目概述 HR智能助理系統是一個基于AI技術的人力資源管理平臺&#xff0c;旨在通過智能化工具提升招聘效率&#xff0c;優化候選人評估流程&#xff0c;并提供專業的面試方案生成服務。 &#x1f3af; 核心價值 提升招聘效率60%&#xff1a;自動化…

PowerBI實現僅在需要圖表時顯示圖表

PowerBI實現僅在需要圖表時顯示圖表實現效果點擊維度前&#xff1a;點擊維度后&#xff1a;實現步驟第一步&#xff0c;先創建一個矩陣表和一個柱形圖第二步&#xff0c;添加一個新卡片圖第三步&#xff0c;創建文本度量值Text "? 選擇一個地區"第四步&#xff0c;創…

信息收集知識總結

信息收集 在信息收集中&#xff0c;需要收集的信息&#xff1a;目標主機的DNS信息、目標IP地址、子域名、旁站和C段、CMS類型、敏感目錄、端口信息、操作系統版本、網站架構、漏洞信息、服務器與中間件信息、郵箱、人員、地址等。 域名信息收集 拿到公司名或者一個域名&…

工作第一步建立連接——ssh

照本宣科 SSH&#xff08;Secure Shell&#xff0c;安全外殼協議&#xff09;是一種用于在不安全網絡上進行安全遠程登錄和實現其他安全網絡服務的協議.功能主要是遠程登陸和文件傳輸&#xff08;使用scp&#xff09; 為了建立 SSH 遠程連接&#xff0c;需要兩個組件&#xf…

Markdown變身Word,解鎖格式轉換新姿勢

目錄一、引言二、在線轉換工具使用法2.1 工具推薦2.2 操作步驟2.3 優缺點分析三、文本編輯器的內置功能或插件3.1 適用編輯器列舉3.2 以 Visual Studio Code 為例的操作流程3.3 優勢說明四、使用專門的轉換軟件4.1 Pandoc 軟件介紹4.2 安裝步驟4.3 命令行轉換操作五、編程腳本實…

MR 處于 WIP 狀態的WIP是什么

WIP是什么 在MR&#xff08;Merge Request 或代碼合并請求&#xff09;中&#xff0c;WIP 是"Work In Progress" 的縮寫&#xff0c;意思是“正在進行中”或“在制品”。當一個MR 被標記為WIP&#xff0c;通常表示它尚未準備好被合并&#xff0c;可能還在開發中&…

機器學習-線性回歸模型和梯度算法

1. 線性回歸模型1.1 線性回歸模型線性回歸模型&#xff1a;將數據擬合成一條直線。作用&#xff1a;預測數字作為輸出。例子&#xff1a;房子的大小與房價的估計&#xff08;圖表&#xff09;&#xff08;數據表&#xff09;1.2 訓練集訓練集&#xff1a;用于訓練模型的數據集訓…

時序預測 | Matlab代碼實現VMD-TCN-GRU-MATT變分模態分解時間卷積門控循環單元多頭注意力多變量時序預測

預測效果代碼功能 代碼主要功能 該代碼實現了一個變分模態分解時間卷積門控循環單元多頭注意力多變量時間序列預測模型&#xff0c;核心功能為&#xff1a; 使用VMD&#xff08;變分模態分解&#xff09;將原始信號分解為多個IMF分量對每個IMF分量構建TCN-GRU-MATT混合神經網絡…

HTML5 離線存儲

HTML5 離線存儲&#xff08;通常指 Application Cache&#xff09;是早期用于實現 Web 應用離線訪問的技術&#xff0c;但由于其設計缺陷已被廢棄。現代 Web 開發中&#xff0c;取而代之的是更強大的 Service Worker Cache API 方案&#xff08;屬于 Progressive Web Apps 技術…

JavaScript 性能優化實戰:深入性能瓶頸,精煉優化技巧與最佳實踐

前言 現代前端開發&#xff0c;不僅要“能跑”&#xff0c;更要“跑得快”。在用戶體驗為王的時代&#xff0c;JavaScript 性能優化已經成為前端工程師的必修課。 為什么要關注 JavaScript 性能 加載緩慢 → 用戶流失卡頓滯后 → 交互體驗崩潰資源浪費 → 設備電量與內存被吞…