GitLab Runner是基於Go語言的開源應用。是運行來自GitLab的CI/CD作業的代理。CI任務作為典型的時間周期型算力使用情境,完美契合Container Compute Service (ACS)按需使用和快速彈性的特性。這不僅可以簡化業務的容量規劃難度,還能降低整體資源持有成本。同時,藉助雲的彈效能力,可以顯著提升CI作業的並發度。本文介紹如何使用GitLab Runner結合ACS算力特性的生產實踐和推薦配置。
背景資訊
GitLab Runner是一個開源的、用於執行GitLab CI/CD流水線作業的專案,作為一個可外置的任務執行架構,它提供了多樣的執行器如Shell、Kubernetes等,讓您可以在私人環境或雲上執行具體的CI作業,並將結果反饋回GitLab中。
Gitlab Runner的核心配置分為兩部分,一部分是Manager Pod的配置和初始化設定,另一部分是Kubernetes Executor的配置。更多資訊,請參見Configure GitLab Runner。
實踐路徑
本文的全部流程如下:
前提條件
已使用kubectl串連Kubernetes叢集。具體操作,請參見擷取叢集kubeconfig並通過kubectl工具串連叢集。
安裝步驟
本文將基於17.3.1版本的gitlab-runner進行,對應Chart版本為0.68.1。關於常規gitlab-runner安裝步驟,請參見GitLab Runner Helm chart。
擷取GitLab Chart包。
添加GitLab Helm倉庫。
helm repo add gitlab https://charts.gitlab.io更新Chart。
helm repo update gitlab擷取GitLab。
helm pull gitlab/gitlab-runner --version 0.68.1 && tar zvxf gitlab-runner-0.68.1.tgz
註冊Runner。
您需要在GitLab控制台Registering runners,並記錄Token資訊。
初始化設定values.yaml。
配置項
配置描述
gitlabUrl
註冊Runner的極狐GitLab伺服器的完整URL。例如,
https://gitlab.example.com。runnerToken
上一步中註冊Runner時產生的Token。此Token是每一個Runner的身份標識,Manager通過此Token資訊關聯由其建立的Pod、Secret等資訊。
rbac
是否啟用RBAC支援。啟用後會自動建立相關ServiceAccount。
rbac: create: trueconcurrent
配置作業的並發度,預設值是10。Manager Pod本身在管理作業時會有一定的記憶體開銷,如果您的並發度較高,需要適當調大Manager Pod的資源規格。
unregisterRunners
在Manager Pod退出時執行
unregister,此配置一般用於使用runnerRegistrationToken進行註冊的情境,避免每次重建token導致的作業失聯問題。詳細資料,請參見FAQ。runners.config
Runner回合組態,以多行字串形式作為runner運行模板,您可以按需調整執行器的相關配置。
安裝GitLab Runner到ACS叢集。
helm install --namespace default gitlab-runner -f values.yaml --version 0.68.1 gitlab/gitlab-runner執行以下命令,確認GitLab Runner的運行狀態。
kubectl get pod | grep gitlab預期輸出:
gitlab-runner-7c5b4xxxxx-xxxxx 1/1 Running 0 5m17s出現此輸出表明安裝已經完成。
鏡像構建
本節我們將結合ACS的部分特性,分別以Docker-in-Docker和使用Kaniko的方式進行鏡像構建。使用到的樣本工程,請參見Java demo。
使用Docker-in-Docker模式進行鏡像構建
在values.yaml中重新定義Runner配置。
您也可以通過修改同命名空間下名為gitlab-runner的ConfigMap來調整Runner的配置,但是推薦的方式是使用
helm upgrade的方式來更新Runner配置。... runners: config: | [[runners]] [runners.kubernetes] namespace = "{{.Release.Namespace}}" image = "registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind" privileged = true cpu_limit = 2 cpu_request = 2 memory_limit = "4Gi" memory_request = "4Gi" ephemeral_storage_request = "30Gi" ephemeral_storage_limit = "30Gi" [[runners.kubernetes.volumes.empty_dir]] name = "docker-certs" mount_path = "/certs/client" medium = "Memory" [[runners.feature_flags]] FF_USE_POD_ACTIVE_DEADLINE_SECONDS = true ...配置說明如下。
配置項
配置描述
image
Docker-In-Docker模式的構建容器所使用的鏡像。這裡採用Docker社區提供的dind鏡像。
privileged
配置Runner Pod是否開啟特權模式,設定為true。
說明本操作需要為ACS Pod開啟特權模式,請提交工單開啟。
cpu_request
cpu_limit
用於設定構建容器的CPU規格。預設ACS提供最小0.25vCPU,您可以根據需要進行調整。
memory_request
memory_limit
用於設定構建容器的記憶體規格。預設情況下ACS提供最小0.5GiB,您可以根據需要進行調整。
ephemeral_storage_request
ephemeral_storage_limit
用於設定臨時儲存空間。預設情況下ACS會提供免費30Gi的儲存空間,並且在建立ACS Pod時會使用此空間自動做鏡像緩衝,加速下一次作業啟動。如果您需求更大的儲存空間,您可以通過此配置進行調整。
FF_USE_POD_ACTIVE_DEADLINE_SECONDS
是否啟用
activeDeadlineSecondsfeatureGate。當開啟時Pod的activeDeadlineSeconds會被設定為Job的逾時時間,避免因未知原因作業Pod失聯而殘留在叢集中。更多配置項,請參見Kubernetes executor。
建立gitlab-ci檔案,配置構建過程。
本樣本沒有採用通過service容器聲明dind容器的方式,而是直接在構建容器中拉起dockerd進程。
image: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind stages: - build variables: # When using dind service, you must instruct Docker to talk with # the daemon started inside of the service. The daemon is available # with a network connection instead of the default # /var/run/docker.sock socket. DOCKER_HOST: tcp://localhost:2376 # # The 'docker' hostname is the alias of the service container as described at # https://docs.gitlab.com/ee/ci/services/#accessing-the-services. # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier, # the variable must be set to tcp://localhost:2376 because of how the # Kubernetes executor connects services to the job container # DOCKER_HOST: tcp://localhost:2376 # # Specify to Docker where to create the certificates. Docker # creates them automatically on boot, and creates # `/certs/client` to share between the service and job # container, thanks to volume mount from config.toml DOCKER_TLS_CERTDIR: "/certs" # These are usually specified by the entrypoint, however the # Kubernetes executor doesn't run entrypoints # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125 DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" before_script: - echo "before task" - sh /usr/local/bin/dockerd-entrypoint.sh & - sleep 10s build_image: stage: build tags: - demo script: - docker info - sleep 1d - docker build --network host -t demo:v1.0.0 -f Dockerfile . - docker push demo:v1.0.0步驟說明如下。
步驟
說明
before_scrip
進行dockerd進程的拉起,並等待一段時間完成其初始化。
build_image
配置鏡像構建的實際步驟。
重要此步驟需要使用host網路模式進行構建,以複用容器網路和外部網路進行通訊。
使用Kaniko以非特權模式進行鏡像構建
Kaniko是一個開源的工具,它能夠在沒有Docker的環境中運行,並且不需要開啟特權,適合當系統限制了對Docker的訪問或需要在Kubernetes中構建鏡像時使用。
配置values.yaml。
... runners: config: | [[runners]] [runners.kubernetes] namespace = "{{.Release.Namespace}}" ephemeral_storage_request = "30Gi" ephemeral_storage_limit = "30Gi" [[runners.feature_flags]] FF_USE_POD_ACTIVE_DEADLINE_SECONDS = true ...建立gitlab-ci檔案,配置構建過程。
重要GitLab CI需要依賴Shell執行器進行命令執行,即使用的基礎鏡像必須可以執行sh命令,因此此處選擇使用kaniko executor的debug版本。
stages: - build variables: KUBERNETES_POD_LABELS_1: "alibabacloud.com/compute-class=general-purpose" KUBERNETES_POD_LABELS_2: "alibabacloud.com/compute-qos=best-effort" build_image: stage: build image: name: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/kaniko-executor:v1.21.0-amd64-debug entrypoint: [""] tags: - demo script: - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
結合ACS的彈性策略降低CI成本
您可以通過以下幾種方式使用ACS提供的best-effort執行個體,進一步降低CI/CD流程中的作業成本。
配置全域或工程維度使用best-effort執行個體。
建議您全域預設採用best-effort類型,部分特殊情境按需覆蓋配置使用其他執行個體類型。
通過runners配置進行全域配置。
... runners: config: | [[runners]] [runners.kubernetes] ... pod_labels_overwrite_allowed = ".*" #允許工程內通過variable覆蓋Labels [[runners.kubernetes.pod_labels]] "app" = "acs-gitlab-runner" "alibabacloud.com/compute-class" = "general-purpose" "alibabacloud.com/compute-qos" = "best-effort" #聲明使用best-effort型 ...您也可以在每個倉庫下通過gitlab-ci.yml進行按需配置,例如使用Kaniko以非特權模式進行鏡像構建中的
variables配置。
配置ResourcePolicy,提高彈性確定性。
ResourcePolicy可以提供自訂的調度策略,您可以使用其提供的成本優先策略,對CI作業優先使用best-effort執行個體。當地區內此執行個體類型售罄時,可以自動降級至default型執行個體,確保CI作業的連續可用。
apiVersion: scheduling.alibabacloud.com/v1alpha1 kind: ResourcePolicy metadata: name: rp-demo namespace: default spec: selector: # 在selector中標記Pod,表示帶有app=stress標籤的Pod將遵循此調度策略 app: acs-gitlab-runner units: # 在units中定義調度順序 - resource: acs # 優先申請best-effort類型的資源 podLabels: alibabacloud.com/compute-class: general-purpose alibabacloud.com/compute-qos: best-effort - resource: acs # 前者庫存不足時,申請default類型的資源 podLabels: alibabacloud.com/compute-class: general-purpose alibabacloud.com/compute-qos: default
FAQ
當Manager Pod重建或重啟時,如何處理叢集內出現Pod殘留?
問題原因
一種可能的情況是,重啟或重建Manager Pod後使用了和之前不同的一個RunnerToken進行啟動,RunnerToken作為唯一的身份標識資訊,當產生變化後,無法繼續接管原有的作業Pod。
解決辦法
您可以在GitLab控制台重新建立Runner並將RunnerToken持久化到安裝的設定檔中。
如果是通過
registrationToken在啟動期間進行的Runner註冊,建議掛載一個Secret,並將首次註冊產生的Token資訊持久化到Secret中,確保每次重啟時優先進行讀取操作。建議開啟featureGate
FF_USE_POD_ACTIVE_DEADLINE_SECONDS,為每個worker增加TTL,作為備用的資源回收策略。