在上一篇的內容中,初步完成了可以 Autoscaling 的 GitLab Runner 串接,不過還有很多的細節設定以及可能的優化可以討論,這一篇的內容會繼續針對這些細節說明。關於 Docker Autoscaler executor,其實是到了 GitLab 17.1 之後才正式釋出
runners.autoscaler
區段的設定plugin
:使用的 fleeting plugin 名稱,目前官方提供 azure
、googlecloud
及 aws
三種,另外還有非官方的 VMware vSphere。capacity_per_instance
:每個 Instance 的容量(可以同時可以接多少工作)max_use_count
:每個 Instance 的使用次數max_instances
:同時最多開多少台 Instance當 capacity_per_instance
與 max_use_count
都設定為 1 代表每一個 Instance,在開啟後,只執行一個工作,工作完成後,就會直接刪除。這樣的型態,可以確保工作與工作之間彼此不會因為執行環境因素而互相干擾,造成執行結果差異。如果可以確認工作與工作間不會因為同時執行或在同一個主機執行而造成干擾,則可以考慮調整這兩個參數。
另外,要注意在 /etc/gitlab-runner/config.toml
設定檔的裡頭concurrent
的這個參數,指的是該主機的「總」工作數。假如 config.toml
裡頭設定了兩個 [[runners]]
則是這兩個 runner 的「加總」不會超過 concurrent
的設定。所以在單一主機有多個 runner 的環境 concurrent
參數需要稍微計算及思考過。可以搭配 [runners.autoscaler]
裡頭的 max_instances
一同規劃配置。
當有設定 [runners.autoscaler.plugin_config]
中的 credentials_file
後,可以不用再設定 [runners.autoscaler.connector_config]
,因為會直接使用 credentials_file 進行連線。
在開始使用 Docker Autoscaler executor 形式的 Runner 之後,可能會發現在 Runner 開始工作後,多了一小段協調 GCP 服務開啟 Instance 的時間,這部分可以搭配 idle_count
與 idle_time
並評估 GCP 花費,取得一個費用與效率最適合的平衡點。
那如果還要讓 Job 可以更快執行完畢,可能還可以考慮哪些事情呢?
使用過程中會發現,因為工作都放到 GCP 上執行,所以無法吃到對應的 cache,因此需要搭配 Google Cloud Storage 建立 Bucket,並讓原本的 Service Account 可以連接到這個 Bucket,來完成 Cache 的工作。相關細節設定可以參考:Advanced configuration - The [runners.cache] section | GitLab Docs
要讓 GitLab Job 執行加速還有一個原則是,下載的時間越短,整體的時間也會越快。當工作執行的環境使用的 Docker Image 都來自私人的 docker registry 或離主機較遠的 registry 時,自然也會增加 Pull Image 的時間,尤其是較大的 Image,差異會更大。因此,可以考慮在建立 Docker Image 時,也可以推送一份到 GCP 上的 Artifact Registry 上,這樣,同樣都在 Google 的環境上,自然下載的速度也會增加,縮短工作完成的時間。
Artifact Registry 說明文件 | Artifact Registry documentation | Google Cloud
GitLab 在 Runner 上的 Docker Autoscaler executor 是我近年實務上納入使用後,非常有感的一個架構。初期在讀懂及實驗相關設定上花了不少時間,但是在確認可行性,正式上線後,讓團隊非常有感的架構,無論是運算的效能上,不會再發生 commit 尖峰時期,效能不彰的問題,且,因為使用 spot 主機,產生的額外費用更讓人敢大力使用。我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。