InfoGrab DocsInfoGrab Docs

Google Kubernetes Engine에서 GitLab Runner 플리트 설계 및 구성

요약

- Offering: GitLab.com, GitLab Self-Managed 이 권장 사항을 활용하여 CI/CD 빌드 요구사항을 분석하고, Google Kubernetes Engine(GKE)에 호스팅된 GitLab Runner 플리트를 설계, 구성, 검증하세요.


Google Kubernetes Engine에서 GitLab Runner 플리트 설계 및 구성#

  - 
  Tier: Free, Premium, Ultimate

- Offering: GitLab.com, GitLab Self-Managed

이 권장 사항을 활용하여 CI/CD 빌드 요구사항을 분석하고, Google Kubernetes Engine(GKE)에 호스팅된 GitLab Runner 플리트를 설계, 구성, 검증하세요.

아래 다이어그램은 러너 플리트 구현 여정의 경로를 보여줍니다. 이 가이드는 다음 단계를 따릅니다:

[

](/19.1/topics/runner_fleet_design_guides/img/runner_fleet_steps_diagram_v17_5.png)

이 프레임워크를 사용하여 단일 그룹 또는 전체 조직을 지원하는 GitLab 인스턴스의 러너 배포를 계획할 수 있습니다.

이 프레임워크는 다음 단계로 구성됩니다:

예상 CI/CD 워크로드 평가#

이 단계에서는 지원하는 개발 팀의 CI/CD 빌드 요구사항을 수집합니다. 해당하는 경우, 사용 중인 프로그래밍 언어, 스크립팅 언어, 마크업 언어의 목록을 작성하세요.

여러 개발 팀, 다양한 프로그래밍 언어, 빌드 요구사항을 지원하고 있을 수 있습니다. 심층 분석의 첫 번째 세트를 위해 하나의 팀, 하나의 프로젝트, 하나의 CI/CD 빌드 요구사항 세트부터 시작하세요.

예상 CI/CD 워크로드를 평가하려면:

  • 지원할 것으로 예상되는 CI/CD job 수요를 추정합니다(시간별, 일별, 주별).

  • 특정 프로젝트의 대표적인 CI/CD job 샘플에 대한 CPU 및 RAM 리소스 요구사항을 추정합니다. 이 추정치는 지원할 수 있는 다양한 프로파일을 파악하는 데 도움이 됩니다. 해당 프로파일의 특성은 요구사항을 지원하는 데 필요한 적절한 GKE 클러스터를 식별하는 데 중요합니다. CPU 및 RAM 요구사항을 결정하는 방법에 대한 예시를 참조하세요.

  • 특정 러너에 대한 그룹 또는 프로젝트별 접근 세분화를 요구하는 보안 또는 정책 요구사항이 있는지 확인합니다.

CI/CD job의 CPU 및 RAM 요구사항 추정#

CPU 및 RAM 리소스 요구사항은 프로그래밍 언어 유형이나 CI/CD job 유형(빌드, 통합 테스트, 단위 테스트, 보안 스캔)과 같은 요소에 따라 달라집니다. 다음 섹션에서는 CI/CD job의 CPU 및 리소스 요구사항을 수집하는 방법을 설명합니다. 필요에 따라 이 방법을 채택하고 발전시킬 수 있습니다.

예를 들어, FastAPI 프로젝트 포크인 ra-group/fastapi에 정의된 것과 유사한 CI/CD job을 실행하는 경우를 가정합니다. 이 예시의 job은 Python 이미지를 사용하고, 프로젝트 요구사항을 다운로드한 후 기존 단위 테스트를 실행합니다. 이 job의 .gitlab-ci.yml은 다음과 같습니다:

tests:
  image: python:3.11.10-bookworm
  parallel: 25
  script:
  - pip install -r requirements.txt
  - pytest

필요한 컴퓨팅 및 RAM 리소스를 파악하려면 Docker를 사용하세요:

  • FastAPI 포크와 CI/CD job 스크립트를 진입점(entrypoint)으로 사용하는 특정 이미지를 생성합니다.

  • 빌드된 이미지로 컨테이너를 실행하고 리소스 사용량을 모니터링합니다.

필요한 컴퓨팅 및 RAM 리소스를 파악하기 위해 다음 단계를 완료하세요:

모든 CI 명령어를 포함하는 스크립트 파일을 프로젝트에 생성합니다. 이 스크립트 파일의 이름은 entrypoint.sh입니다.

#!/bin/bash
cd /fastapi || exit
pip install -r requirements.txt
pytest

entrypoint.sh 파일이 CI 스크립트를 실행하는 이미지를 생성하기 위한 Dockerfile을 작성합니다.

FROM python:3.11.10-bookworm
RUN mkdir /fastapi
COPY . /fastapi
RUN chmod +x /fastapi/entrypoint.sh
CMD [ "bash", "/fastapi/entrypoint.sh" ]

이미지를 빌드합니다. 프로세스를 단순화하기 위해 빌드, 저장, 실행과 같은 모든 작업을 로컬에서 수행합니다. 이 방법은 이미지를 가져오고 내보내기 위한 온라인 레지스트리가 필요하지 않습니다.

❯ docker build . -t my-project_dir/fastapi:testing
...
Successfully tagged my-project_dir/fastapi:testing

빌드된 이미지로 컨테이너를 실행하면서 컨테이너 실행 중 리소스 사용량을 동시에 모니터링합니다. 다음 명령어가 포함된 metrics.sh 스크립트를 생성합니다:

#! /bin/bash

container_id=$(docker run -d --rm my-project_dir/fastapi:testing)

while true; do
    echo "Collecting metrics..."
    metrics=$(docker stats --no-trunc --no-stream --format "table {}\t{}\t{}" | grep "$container_id")
    if [ -z "$metrics" ]; then
        exit 0
    fi
    echo "Saving metrics..."
    echo "$metrics" >> metrics.log
    sleep 1
done

이 스크립트는 빌드된 이미지로 분리된(detached) 컨테이너를 실행합니다. 컨테이너 ID를 사용하여 컨테이너가 성공적으로 완료되고 종료될 때까지 CPUMemory 사용량을 수집합니다. 수집된 메트릭은 metrics.log 파일에 저장됩니다.

이 예시에서 CI/CD job은 단기 실행이므로, 컨테이너 폴링 사이의 대기 시간이 1초로 설정되어 있습니다. 필요에 맞게 이 값을 조정하세요.

- metrics.log 파일을 분석하여 테스트 컨테이너의 최대 사용량을 파악합니다.

이 예시에서 최대 CPU 사용량은 107.50%이고 최대 메모리 사용량은 303.1Mi입니다.

223e93dd05c6   94.98%    83.79MiB / 15.58GiB
223e93dd05c6   28.27%    85.4MiB / 15.58GiB
223e93dd05c6   53.92%    121.8MiB / 15.58GiB
223e93dd05c6   70.73%    171.9MiB / 15.58GiB
223e93dd05c6   20.78%    177.2MiB / 15.58GiB
223e93dd05c6   26.19%    180.3MiB / 15.58GiB
223e93dd05c6   77.04%    224.1MiB / 15.58GiB
223e93dd05c6   97.16%    226.5MiB / 15.58GiB
223e93dd05c6   98.52%    259MiB / 15.58GiB
223e93dd05c6   98.78%    303.1MiB / 15.58GiB
223e93dd05c6   100.03%   159.8MiB / 15.58GiB
223e93dd05c6   103.97%   204MiB / 15.58GiB
223e93dd05c6   107.50%   207.8MiB / 15.58GiB
223e93dd05c6   105.96%   215.7MiB / 15.58GiB
223e93dd05c6   101.88%   226.2MiB / 15.58GiB
223e93dd05c6   100.44%   226.7MiB / 15.58GiB
223e93dd05c6   100.20%   226.9MiB / 15.58GiB
223e93dd05c6   100.60%   227.6MiB / 15.58GiB
223e93dd05c6   100.46%   228MiB / 15.58GiB

수집된 메트릭 분석#

수집된 메트릭을 기반으로, 이 job 프로파일에 대해 쿠버네티스 executor job을 1 CPU~304 Mi의 메모리로 제한할 수 있습니다. 이 결론이 정확하더라도 모든 사용 사례에 실용적이지 않을 수 있습니다.

3개의 e2-standard-4 노드 풀이 있는 클러스터를 사용하여 job을 실행하면, 1 CPU 제한으로 12개의 job만 동시에 실행할 수 있습니다(e2-standard-4 노드는 4 vCPU와 16 GB 메모리를 가집니다). 추가 job은 실행 중인 job이 완료되어 리소스를 해제할 때까지 기다려야 합니다.

메모리 요청량은 중요합니다. 쿠버네티스는 설정된 제한 또는 클러스터에서 사용 가능한 메모리보다 더 많은 메모리를 사용하는 Pod를 Out of Memory(OOM) 종료 프로세스를 사용하여 자동으로 종료하기 때문입니다. 반면 CPU 제한은 더 유연하지만 job 실행 시간에 영향을 미칩니다. CPU 제한을 낮게 설정할수록 job 완료에 걸리는 시간이 늘어납니다. 이전 예시에서 CPU 제한을 1 대신 250m(또는 0.25)로 설정하면 job 실행 시간이 4배 증가했습니다(약 2분에서 8~10분으로).

메트릭 수집 방법이 폴링 메커니즘을 사용하므로, 파악된 최대 사용량을 올림하는 것이 좋습니다. 예를 들어, 메모리 사용량의 경우 303 Mi 대신 400 Mi로 올림하세요.

이전 예시에 대한 중요 고려사항:

  • 메트릭은 Google Kubernetes Engine 클러스터와 동일한 CPU 구성을 가지지 않는 로컬 머신에서 수집되었습니다. 그러나 이 메트릭은 e2-standard-4 노드가 있는 쿠버네티스 클러스터에서 모니터링하여 검증되었습니다.

  • 해당 메트릭의 정확한 표현을 얻으려면 평가 단계에서 설명한 테스트를 Google Compute Engine VM에서 실행하세요.

러너 플리트 구성 계획#

계획 단계에서는 조직에 적합한 러너 플리트 구성을 설계합니다. 러너 범위(인스턴스, 그룹, 프로젝트)와 다음을 기반으로 한 쿠버네티스 클러스터 구성을 고려하세요:

  • CI/CD job 리소스 수요에 대한 평가 결과

  • CI/CD job 유형 목록

러너 범위#

러너 범위를 계획하려면 다음 질문을 고려하세요:

프로젝트 Owner와 그룹 Owner가 자체 러너를 생성하고 관리하도록 할 것인가요?

기본적으로 프로젝트 및 그룹 Owner는 GitLab에서 러너 구성을 생성하고 프로젝트 또는 그룹에 러너를 등록할 수 있습니다.

  • 이 설계는 개발자가 빌드 환경을 신속하게 만들 수 있도록 합니다. 이 방법은 GitLab CI/CD를 시작할 때 개발자의 마찰을 줄여줍니다. 그러나 대규모 조직에서는 이 방법으로 인해 환경 전반에 걸쳐 활용도가 낮거나 사용되지 않는 러너가 많이 생길 수 있습니다.

조직에 특정 유형의 러너에 대한 접근을 특정 그룹이나 프로젝트로 세분화하도록 요구하는 보안 또는 기타 정책이 있나요?

GitLab Self-Managed 환경에서 러너를 배포하는 가장 간단한 방법은 인스턴스용으로 생성하는 것입니다. 인스턴스 범위의 러너는 기본적으로 모든 그룹과 프로젝트에서 사용할 수 있습니다.

조직의 모든 요구사항을 인스턴스 러너로 충족할 수 있다면, 이 배포 패턴이 가장 효율적인 패턴입니다. 이 패턴을 사용하면 CI/CD 빌드 플리트를 대규모로 효율적이고 비용 효과적으로 운영할 수 있습니다.

특정 러너에 대한 접근을 특정 그룹이나 프로젝트로 세분화해야 하는 요구사항이 있다면, 계획 프로세스에 이를 포함시키세요.

러너 플리트 구성 예시 - 인스턴스 러너#

아래 표의 구성은 조직을 위한 러너 플리트를 구성할 때 사용 가능한 유연성을 보여줍니다. 이 예시는 서로 다른 인스턴스 크기와 서로 다른 job 태그를 가진 여러 러너를 사용합니다. 이 러너들을 통해 각각 특정 CPU 및 RAM 리소스 요구사항을 가진 다양한 유형의 CI/CD job을 지원할 수 있습니다. 그러나 쿠버네티스를 사용할 때 가장 효율적인 패턴이 아닐 수 있습니다.

러너 유형 러너 태그 범위 제공할 러너 유형 수 러너 Worker 사양 러너 호스트 환경 환경 구성
Instance ci-runner-small 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 5 2 vCPU, 8 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-2
Instance ci-runner-medium 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 2 4 vCPU, 16 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-4
Instance ci-runner-large 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 1 8 vCPU, 32 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-8

러너 플리트 구성 예시에는 총 세 가지 러너 구성과 CI/CD job을 활발하게 실행하는 여덟 개의 러너가 있습니다.

쿠버네티스 executor를 사용하면 쿠버네티스 스케줄러를 활용하고 컨테이너 리소스를 덮어쓸 수 있습니다. 이론적으로 충분한 리소스를 갖춘 쿠버네티스 클러스터에 단일 GitLab Runner를 배포할 수 있습니다. 그런 다음 컨테이너 리소스를 덮어써서 각 CI/CD job에 적합한 컴퓨팅 유형을 선택할 수 있습니다. 이 패턴을 구현하면 배포하고 운영해야 하는 별도 러너 구성의 수를 줄일 수 있습니다.

모범 사례#

  • 항상 러너 매니저를 위한 전용 노드 풀을 만드세요.

로그 처리 및 캐시 또는 아티팩트 관리는 CPU를 많이 사용할 수 있습니다.

  • 항상 config.toml 파일에서 기본 제한(빌드/Helper/서비스 컨테이너의 CPU/메모리)을 설정하세요.

  • 항상 config.toml 파일에서 리소스의 최대 덮어쓰기를 허용하세요.

  • job 정의(.gitlab-ci.yml)에서 job에 필요한 올바른 제한을 지정하세요.

지정하지 않으면 config.toml 파일에 설정된 기본값이 사용됩니다.

  • 컨테이너가 메모리 제한을 초과하면, 시스템이 Out of Memory(OOM) 종료 프로세스를 사용하여 자동으로 종료합니다.

  • 피처 플래그 FF_RETRIEVE_POD_WARNING_EVENTSFF_PRINT_POD_EVENTS를 사용하세요. 자세한 내용은 피처 플래그 문서를 참조하세요.

GKE에 러너 배포#

Google Kubernetes 클러스터에 GitLab Runner를 설치할 준비가 되면 여러 가지 옵션이 있습니다. GKE에 클러스터를 생성한 경우, GitLab Runner Helm Chart 또는 Operator를 사용하여 클러스터에 러너를 설치할 수 있습니다.

GKE에 클러스터를 아직 설정하지 않은 경우, GitLab은 GitLab Runner Infrastructure Toolkit(GRIT)을 제공합니다. GRIT은 동시에 다음을 수행합니다:

  • 다중 노드 풀 GKE 클러스터 생성: Standard 에디션 및 standard 모드.

  • GitLab Runner 쿠버네티스 operator를 사용하여 클러스터에 GitLab Runner 설치.

다음 예시에서는 GRIT을 사용하여 Google Kubernetes 클러스터와 GitLab Runner Manager를 배포합니다.

클러스터와 GitLab Runner를 잘 구성하려면 다음 정보를 고려하세요:

  • 커버해야 할 job 유형의 수는 몇 가지인가요?

이 정보는 평가 단계에서 가져옵니다. 평가 단계에서는 조직의 제약사항을 고려하여 메트릭을 집계하고 결과 그룹의 수를 파악합니다. "job 유형"은 접근 단계에서 파악된 분류된 job의 집합입니다. 이 분류는 job에 필요한 최대 리소스를 기반으로 합니다.

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

이 정보는 계획 단계에서 가져옵니다. 조직이 프로젝트를 별도로 관리하는 경우, 각 프로젝트에 이 프레임워크를 개별적으로 적용하세요. 이 접근 방법은 여러 job 프로파일이 파악되고(전체 조직 또는 특정 프로젝트에 대해), 개인 또는 GitLab Runner 플리트가 모두 처리하는 경우에만 관련이 있습니다. 기본 구성은 일반적으로 GKE 클러스터당 하나의 GitLab Runner Manager를 사용합니다.

  • 예상 최대 동시 CI/CD job 수는 얼마인가요?

이 정보는 임의의 시점에 실행되는 최대 동시 CI/CD job 수에 대한 추정치를 나타냅니다. 이 정보는 Prepare Stage 동안 GitLab Runner Manager가 얼마나 오래 기다리는지 설정하여 GitLab Runner Manager를 구성할 때 필요합니다: 제한된 가용 리소스를 가진 노드에서의 job Pod 스케줄링.

FastAPI 포크에 대한 실제 적용 예시#

FastAPI 포크에 대해 다음 정보를 고려하세요:

  • 커버해야 할 job 프로파일의 수는 몇 가지인가요?

다음 특성을 가진 하나의 job 프로파일이 있습니다: 1 CPU303 Mi의 메모리. 수집된 메트릭 분석 섹션에서 설명한 대로, 이 원시 값은 다음과 같이 변경됩니다:

메모리 제한으로 인한 job 실패를 방지하기 위해 메모리 제한을 303 Mi 대신 400 Mi로 설정합니다.

  • CPU는 1 CPU 대신 0.20으로 설정합니다. 이 예시에서는 작업 완료 시 속도보다 정확성과 품질을 우선합니다.

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

테스트를 위해 하나의 GitLab Runner Manager면 충분합니다.

  • 예상 워크로드는 어느 정도인가요?

언제든지 최대 20개의 job을 동시에 실행하려고 합니다.

이러한 입력값을 기반으로, 다음 최소 특성을 갖춘 모든 GKE 클러스터면 충분합니다:

  • 최소 CPU: (0.20 + helper CPU 사용량) * 동시 job 수. 이 예시에서 helper 컨테이너 제한을 0.15 CPU로 설정하면 7 vCPU가 됩니다.

  • 최소 메모리: (400Mi + helper 메모리 사용량) * 동시 job 수. 이 예시에서 helper 제한을 100 Mi로 설정하면 최소 10 Gi가 됩니다.

필요한 최소 스토리지와 같은 기타 특성도 고려해야 합니다. 그러나 이 예시에서는 이를 고려하지 않습니다.

GKE 클러스터에 가능한 구성은 다음과 같습니다(두 구성 모두 20개 이상의 job을 동시에 실행할 수 있습니다):

  • 3개의 e2-standard-4 노드로 이루어진 노드 풀이 있는 GKE 클러스터: 총 12 vCPU48 GiB의 메모리

  • e2-standard-8 노드만으로 이루어진 노드 풀이 있는 GKE 클러스터: 총 8 vCPU32 GiB의 메모리

이 예시에서는 첫 번째 구성을 사용합니다. GitLab Runner Manager 로그 처리가 전체 로그 처리에 영향을 미치지 않도록 GitLab Runner가 설치된 전용 노드 풀을 사용하세요.

GKE GRIT 구성#

GRIT에 대한 결과 GKE 구성은 다음과 유사합니다:

google_project     = "GCLOUD_PROJECT"
google_region      = "GCLOUD_REGION"
google_zone        = "GCLOUD_ZONE"
name               = "my-grit-gke-cluster"
node_pools = {
  "runner-manager" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-standard-2",
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 50,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner",
      }
    },
  },
  "worker-pool" = {
    node_count = 3,
    node_config = {
      machine_type = "e2-standard-4",    #4 vCPU, 16 GB each
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
}

이전 구성에서:

  • runner-manager 블록은 GitLab Runner가 설치된 노드 풀을 나타냅니다. 이 예시에서는 e2-standard-2로 충분합니다.

  • runner-manager 블록의 labels 섹션은 GitLab에 GitLab Runner를 설치할 때 유용합니다. operator 구성을 통해 노드 선택기가 구성되어 GitLab Runner가 이 노드 풀의 노드에 설치되도록 합니다.

  • worker-pool 블록은 CI/CD job Pod가 생성되는 노드 풀을 나타냅니다. 제공된 구성은 job Pod를 호스팅하기 위해 "app" = "gitlab-runner-job" 레이블이 지정된 3개의 e2-standard-4 노드로 이루어진 노드 풀을 생성합니다.

  • image_type 파라미터를 사용하여 노드에서 사용하는 이미지를 설정할 수 있습니다. 워크로드가 주로 Windows 이미지에 의존하는 경우 windows_ltsc_containerd로 설정할 수 있습니다.

이 구성에 대한 예시 그림입니다:

[

](/19.1/topics/runner_fleet_design_guides/img/nodepool_illustration_example_v17_5.png)

GitLab Runner GRIT 구성#

GRIT에 대한 결과 GitLab Runner 구성은 다음과 유사합니다:

gitlab_pat         = "glpat-REDACTED"
gitlab_project_id  = GITLAB_PROJECT_ID
runner_description = "my-grit-gitlab-runner"
runner_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-ocp:amd64-v17.3.1"
helper_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v17.3.1"
concurrent     = 20
check_interval = 1
runner_tags    = ["my-custom-tag"]
config_template    = <

이전 구성에서:

  • pod_spec 파라미터를 통해 GitLab Runner를 실행하는 Pod에 노드 선택기를 설정할 수 있습니다. 구성에서 노드 선택기는 GitLab Runner가 runner-manager 노드 풀에 설치되도록 "app" = "gitlab-runner"로 설정됩니다.

  • config_template 파라미터는 GitLab Runner Manager가 실행하는 모든 job에 대한 기본 제한을 제공합니다. 또한 설정된 값이 기본값을 초과하지 않는 한 해당 제한의 덮어쓰기를 허용합니다.

  • 피처 플래그 FF_RETRIEVE_POD_WARNING_EVENTSFF_PRINT_POD_EVENTS도 job 실패 시 디버깅을 용이하게 하기 위해 설정됩니다. 자세한 내용은 피처 플래그 문서를 참조하세요.

가상의 사용 사례에 대한 실제 적용 예시#

다음 정보를 고려하세요:

  • 커버해야 할 job 프로파일의 수는 몇 가지인가요?

두 가지 프로파일(제공된 사양은 helper 제한을 포함합니다):

중간 규모 job: 300m CPU200 MiB

  • CPU 집약적인 job: 1 CPU1 GiB

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

하나.

  • 예상 워크로드는 어느 정도인가요?

동시에 최대 50개의 중간 규모 job

  • 동시에 최대 25개의 CPU 집약적인 job

GKE 구성#

  • 중간 규모 job에 필요한 리소스:

CPU: 300m * 50 = 5 CPU (근사치)

  • 메모리: 200 MiB * 50 = 10 GiB

  • CPU 집약적인 job에 필요한 리소스:

CPU: 1 * 25 = 25

  • 메모리: 1 GiB * 25 = 25 GiB

GKE 클러스터는 다음을 갖춰야 합니다:

  • GitLab Runner Manager용 노드 풀(로그 처리 부담이 크지 않다고 가정): e2-standard-2 노드 1개

  • 중간 규모 job용 노드 풀: e2-standard-4 노드 3개

  • CPU 집약적인 job용 노드 풀: e2-highcpu-32 노드 1개 (32 vCPU32 GiB 메모리)

google_project     = "GCLOUD_PROJECT"
google_region      = "GCLOUD_REGION"
google_zone        = "GCLOUD_ZONE"
name               = "my-grit-gke-cluster"
node_pools = {
  "runner-manager" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-standard-2",
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 50,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner",
      }
    },
  },
  "medium-pool" = {
    node_count = 3,
    node_config = {
      machine_type = "e2-standard-4",    #4 vCPU, 16 GB each
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
  "cpu-intensive-pool" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-highcpu-32", #32 vCPU, 32 GB each
      image_type   = "cos_containerd",
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
}

GitLab Runner 구성#

현재 GRIT 구현은 한 번에 두 개 이상의 러너 설치를 지원하지 않습니다. 제공된 config_template은 이전 예시에서와 같이 node_selection 및 기타 제한과 같은 구성을 설정하지 않습니다. 간단한 구성으로 CPU 집약적인 job에 대해 최대 허용 덮어쓰기 값을 허용하고 .gitlab-ci.yml 파일에서 올바른 값을 설정합니다. 결과 GitLab Runner 구성은 다음과 유사합니다:

gitlab_pat         = "glpat-REDACTED"
gitlab_project_id  = GITLAB_PROJECT_ID
runner_description = "my-grit-gitlab-runner"
runner_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-ocp:amd64-v17.3.1"
helper_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v17.3.1"
concurrent     = 100
check_interval = 1
runner_tags    = ["my-custom-tag"]
config_template    = <

.gitlab-ci.yml 파일은 다음과 유사합니다:

중간 규모 job의 경우:

variables:
  KUBERNETES_CPU_LIMIT: "200m"
  KUBERNETES_MEMORY_LIMIT: "100Mi"
  KUBERNETES_HELPER_CPU_LIMIT: "100m"
  KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"

tests:
  image: some-image:latest
  script:
  - command_1
  - command_2
  # ...
  - command_n
  tags:
    - my-custom-tag

CPU 집약적인 job의 경우:

variables:
  KUBERNETES_CPU_LIMIT: "0.75"
  KUBERNETES_MEMORY_LIMIT: "900Mi"
  KUBERNETES_HELPER_CPU_LIMIT: "150m"
  KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"

tests:
  image: custom-cpu-intensive-image:latest
  script:
  - cpu_intensive_command_1
  - cpu_intensive_command_2
  # ...
  - cpu_intensive_command_n
  tags:
    - my-custom-tag
더 쉬운 구성을 위해 job 프로파일당 클러스터 하나에 하나의 GitLab Runner를 사용하세요. 이 접근 방법은 GitLab이 동일한 클러스터에 여러 GitLab Runner를 설치하거나 `config.toml` 템플릿에서 여러 `[[runners]]` 섹션을 지원할 때까지 권장됩니다.

모니터링 및 관찰 가능성 설정#

배포 단계의 마지막 단계로, 러너 호스트 환경과 GitLab Runner를 모니터링하기 위한 솔루션을 구축해야 합니다. 인프라 수준, 러너 및 CI/CD job 메트릭은 CI/CD 빌드 인프라의 효율성과 신뢰성에 대한 인사이트를 제공합니다. 또한 쿠버네티스 클러스터, GitLab Runner 및 CI/CD job 구성을 조정하고 최적화하는 데 필요한 인사이트를 제공합니다.

모니터링 모범 사례#

  • job 수준 메트릭 모니터링: job 실행 시간, job 성공 및 실패율.

job 수준 메트릭을 분석하여 가장 자주 실행되고 전체적으로 가장 많은 컴퓨팅 및 RAM 리소스를 소비하는 CI/CD job을 파악하세요. 이 job 프로파일은 최적화 기회를 평가하는 좋은 시작점입니다.

  • 쿠버네티스 클러스터 리소스 활용률 모니터링:

CPU 활용률

  • 메모리 활용률

  • 네트워크 활용률

  • 디스크 활용률

진행 방법에 대한 자세한 내용은 GitLab Runner 전용 모니터링 페이지를 참조하세요.

최적화#

CI/CD 빌드 환경을 최적화하는 것은 지속적인 프로세스입니다. CI/CD job의 유형과 양은 계속 변화하므로 적극적인 관여가 필요합니다.

CI/CD 및 CI/CD 빌드 인프라에 대한 특정 조직 목표가 있을 것입니다. 따라서 첫 번째 단계는 최적화 요구사항과 정량화 가능한 목표를 정의하는 것입니다.

다음은 고객 기반 전반에 걸친 최적화 요구사항의 예시 세트입니다:

  • CI/CD job 시작 시간

  • CI/CD job 실행 시간

  • CI/CD job 안정성

  • CI/CD 컴퓨팅 비용 최적화

다음 단계는 쿠버네티스 클러스터의 인프라 메트릭과 함께 CI/CD 메트릭 분석을 시작하는 것입니다. 분석해야 할 핵심 상관관계는 다음과 같습니다:

  • 쿠버네티스 네임스페이스별 CPU 활용률

  • 쿠버네티스 네임스페이스별 메모리 활용률

  • 노드별 CPU 활용률

  • 노드별 메모리 활용률

  • CI/CD job 실패율

일반적으로 쿠버네티스에서 높은 CI/CD job 실패율(불안정한 테스트로 인한 실패와 무관하게)은 쿠버네티스 클러스터의 리소스 제약으로 인한 것입니다. 이 메트릭을 분석하여 쿠버네티스 클러스터 구성에서 CI/CD job 시작 시간, job 실행 시간, job 안정성 및 인프라 리소스 활용 간의 최적 균형을 달성하세요.

모범 사례#

  • 조직 전반에 걸쳐 CI/CD job을 job 유형별로 분류하는 프로세스를 수립하세요.

  • 쿠버네티스에서 GitLab CI/CD 빌드 인프라와 CI/CD job 유형의 모니터링 구성 및 최적화 접근 방법을 단순화하기 위한 job 유형 분류 프레임워크를 수립하세요.

  • 클러스터의 각 job 유형에 자체 노드를 할당하면 CI/CD job 성능, job 안정성 및 인프라 활용 간의 최적 균형을 달성할 수 있습니다.

CI/CD 빌드 환경의 인프라 스택으로 쿠버네티스를 사용하면 상당한 이점이 있습니다. 그러나 쿠버네티스 인프라의 지속적인 모니터링과 최적화가 필요합니다. 관찰 가능성과 최적화 프레임워크를 수립한 후에는 매월 수백만 개의 CI/CD job을 지원할 수 있습니다. 리소스 경합을 제거하고, 결정적인 CI/CD job 실행과 최적의 리소스 사용을 달성할 수 있습니다. 이러한 개선은 운영 효율성과 비용 최적화로 이어집니다.

다음 단계#

더 나은 사용자 경험을 제공하기 위한 다음 단계를 수행하세요:

  • 동일한 클러스터에 여러 GitLab Runner를 설치 지원. 이를 통해 여러 job 프로파일을 처리해야 하는 시나리오를 더 잘 관리할 수 있습니다(GitLab Runner를 적절히 구성하여 리소스 남용을 방지할 수 있습니다).

  • GKE 노드 자동 확장 지원. 이를 통해 GKE가 워크로드에 따라 확장 및 축소할 수 있어 비용을 절감할 수 있습니다.

  • job 메트릭 모니터링 활성화. 이를 통해 관리자가 실제 사용량을 기반으로 클러스터와 GitLab Runner를 더 잘 최적화할 수 있습니다.

Google Kubernetes Engine에서 GitLab Runner 플리트 설계 및 구성

GitLab v19.1
원문 보기
요약

- Offering: GitLab.com, GitLab Self-Managed 이 권장 사항을 활용하여 CI/CD 빌드 요구사항을 분석하고, Google Kubernetes Engine(GKE)에 호스팅된 GitLab Runner 플리트를 설계, 구성, 검증하세요.


Google Kubernetes Engine에서 GitLab Runner 플리트 설계 및 구성#

  - 
  Tier: Free, Premium, Ultimate

- Offering: GitLab.com, GitLab Self-Managed

이 권장 사항을 활용하여 CI/CD 빌드 요구사항을 분석하고, Google Kubernetes Engine(GKE)에 호스팅된 GitLab Runner 플리트를 설계, 구성, 검증하세요.

아래 다이어그램은 러너 플리트 구현 여정의 경로를 보여줍니다. 이 가이드는 다음 단계를 따릅니다:

[

](/19.1/topics/runner_fleet_design_guides/img/runner_fleet_steps_diagram_v17_5.png)

이 프레임워크를 사용하여 단일 그룹 또는 전체 조직을 지원하는 GitLab 인스턴스의 러너 배포를 계획할 수 있습니다.

이 프레임워크는 다음 단계로 구성됩니다:

예상 CI/CD 워크로드 평가#

이 단계에서는 지원하는 개발 팀의 CI/CD 빌드 요구사항을 수집합니다. 해당하는 경우, 사용 중인 프로그래밍 언어, 스크립팅 언어, 마크업 언어의 목록을 작성하세요.

여러 개발 팀, 다양한 프로그래밍 언어, 빌드 요구사항을 지원하고 있을 수 있습니다. 심층 분석의 첫 번째 세트를 위해 하나의 팀, 하나의 프로젝트, 하나의 CI/CD 빌드 요구사항 세트부터 시작하세요.

예상 CI/CD 워크로드를 평가하려면:

  • 지원할 것으로 예상되는 CI/CD job 수요를 추정합니다(시간별, 일별, 주별).

  • 특정 프로젝트의 대표적인 CI/CD job 샘플에 대한 CPU 및 RAM 리소스 요구사항을 추정합니다. 이 추정치는 지원할 수 있는 다양한 프로파일을 파악하는 데 도움이 됩니다. 해당 프로파일의 특성은 요구사항을 지원하는 데 필요한 적절한 GKE 클러스터를 식별하는 데 중요합니다. CPU 및 RAM 요구사항을 결정하는 방법에 대한 예시를 참조하세요.

  • 특정 러너에 대한 그룹 또는 프로젝트별 접근 세분화를 요구하는 보안 또는 정책 요구사항이 있는지 확인합니다.

CI/CD job의 CPU 및 RAM 요구사항 추정#

CPU 및 RAM 리소스 요구사항은 프로그래밍 언어 유형이나 CI/CD job 유형(빌드, 통합 테스트, 단위 테스트, 보안 스캔)과 같은 요소에 따라 달라집니다. 다음 섹션에서는 CI/CD job의 CPU 및 리소스 요구사항을 수집하는 방법을 설명합니다. 필요에 따라 이 방법을 채택하고 발전시킬 수 있습니다.

예를 들어, FastAPI 프로젝트 포크인 ra-group/fastapi에 정의된 것과 유사한 CI/CD job을 실행하는 경우를 가정합니다. 이 예시의 job은 Python 이미지를 사용하고, 프로젝트 요구사항을 다운로드한 후 기존 단위 테스트를 실행합니다. 이 job의 .gitlab-ci.yml은 다음과 같습니다:

tests:
  image: python:3.11.10-bookworm
  parallel: 25
  script:
  - pip install -r requirements.txt
  - pytest

필요한 컴퓨팅 및 RAM 리소스를 파악하려면 Docker를 사용하세요:

  • FastAPI 포크와 CI/CD job 스크립트를 진입점(entrypoint)으로 사용하는 특정 이미지를 생성합니다.

  • 빌드된 이미지로 컨테이너를 실행하고 리소스 사용량을 모니터링합니다.

필요한 컴퓨팅 및 RAM 리소스를 파악하기 위해 다음 단계를 완료하세요:

모든 CI 명령어를 포함하는 스크립트 파일을 프로젝트에 생성합니다. 이 스크립트 파일의 이름은 entrypoint.sh입니다.

#!/bin/bash
cd /fastapi || exit
pip install -r requirements.txt
pytest

entrypoint.sh 파일이 CI 스크립트를 실행하는 이미지를 생성하기 위한 Dockerfile을 작성합니다.

FROM python:3.11.10-bookworm
RUN mkdir /fastapi
COPY . /fastapi
RUN chmod +x /fastapi/entrypoint.sh
CMD [ "bash", "/fastapi/entrypoint.sh" ]

이미지를 빌드합니다. 프로세스를 단순화하기 위해 빌드, 저장, 실행과 같은 모든 작업을 로컬에서 수행합니다. 이 방법은 이미지를 가져오고 내보내기 위한 온라인 레지스트리가 필요하지 않습니다.

❯ docker build . -t my-project_dir/fastapi:testing
...
Successfully tagged my-project_dir/fastapi:testing

빌드된 이미지로 컨테이너를 실행하면서 컨테이너 실행 중 리소스 사용량을 동시에 모니터링합니다. 다음 명령어가 포함된 metrics.sh 스크립트를 생성합니다:

#! /bin/bash

container_id=$(docker run -d --rm my-project_dir/fastapi:testing)

while true; do
    echo "Collecting metrics..."
    metrics=$(docker stats --no-trunc --no-stream --format "table {}\t{}\t{}" | grep "$container_id")
    if [ -z "$metrics" ]; then
        exit 0
    fi
    echo "Saving metrics..."
    echo "$metrics" >> metrics.log
    sleep 1
done

이 스크립트는 빌드된 이미지로 분리된(detached) 컨테이너를 실행합니다. 컨테이너 ID를 사용하여 컨테이너가 성공적으로 완료되고 종료될 때까지 CPUMemory 사용량을 수집합니다. 수집된 메트릭은 metrics.log 파일에 저장됩니다.

이 예시에서 CI/CD job은 단기 실행이므로, 컨테이너 폴링 사이의 대기 시간이 1초로 설정되어 있습니다. 필요에 맞게 이 값을 조정하세요.

- metrics.log 파일을 분석하여 테스트 컨테이너의 최대 사용량을 파악합니다.

이 예시에서 최대 CPU 사용량은 107.50%이고 최대 메모리 사용량은 303.1Mi입니다.

223e93dd05c6   94.98%    83.79MiB / 15.58GiB
223e93dd05c6   28.27%    85.4MiB / 15.58GiB
223e93dd05c6   53.92%    121.8MiB / 15.58GiB
223e93dd05c6   70.73%    171.9MiB / 15.58GiB
223e93dd05c6   20.78%    177.2MiB / 15.58GiB
223e93dd05c6   26.19%    180.3MiB / 15.58GiB
223e93dd05c6   77.04%    224.1MiB / 15.58GiB
223e93dd05c6   97.16%    226.5MiB / 15.58GiB
223e93dd05c6   98.52%    259MiB / 15.58GiB
223e93dd05c6   98.78%    303.1MiB / 15.58GiB
223e93dd05c6   100.03%   159.8MiB / 15.58GiB
223e93dd05c6   103.97%   204MiB / 15.58GiB
223e93dd05c6   107.50%   207.8MiB / 15.58GiB
223e93dd05c6   105.96%   215.7MiB / 15.58GiB
223e93dd05c6   101.88%   226.2MiB / 15.58GiB
223e93dd05c6   100.44%   226.7MiB / 15.58GiB
223e93dd05c6   100.20%   226.9MiB / 15.58GiB
223e93dd05c6   100.60%   227.6MiB / 15.58GiB
223e93dd05c6   100.46%   228MiB / 15.58GiB

수집된 메트릭 분석#

수집된 메트릭을 기반으로, 이 job 프로파일에 대해 쿠버네티스 executor job을 1 CPU~304 Mi의 메모리로 제한할 수 있습니다. 이 결론이 정확하더라도 모든 사용 사례에 실용적이지 않을 수 있습니다.

3개의 e2-standard-4 노드 풀이 있는 클러스터를 사용하여 job을 실행하면, 1 CPU 제한으로 12개의 job만 동시에 실행할 수 있습니다(e2-standard-4 노드는 4 vCPU와 16 GB 메모리를 가집니다). 추가 job은 실행 중인 job이 완료되어 리소스를 해제할 때까지 기다려야 합니다.

메모리 요청량은 중요합니다. 쿠버네티스는 설정된 제한 또는 클러스터에서 사용 가능한 메모리보다 더 많은 메모리를 사용하는 Pod를 Out of Memory(OOM) 종료 프로세스를 사용하여 자동으로 종료하기 때문입니다. 반면 CPU 제한은 더 유연하지만 job 실행 시간에 영향을 미칩니다. CPU 제한을 낮게 설정할수록 job 완료에 걸리는 시간이 늘어납니다. 이전 예시에서 CPU 제한을 1 대신 250m(또는 0.25)로 설정하면 job 실행 시간이 4배 증가했습니다(약 2분에서 8~10분으로).

메트릭 수집 방법이 폴링 메커니즘을 사용하므로, 파악된 최대 사용량을 올림하는 것이 좋습니다. 예를 들어, 메모리 사용량의 경우 303 Mi 대신 400 Mi로 올림하세요.

이전 예시에 대한 중요 고려사항:

  • 메트릭은 Google Kubernetes Engine 클러스터와 동일한 CPU 구성을 가지지 않는 로컬 머신에서 수집되었습니다. 그러나 이 메트릭은 e2-standard-4 노드가 있는 쿠버네티스 클러스터에서 모니터링하여 검증되었습니다.

  • 해당 메트릭의 정확한 표현을 얻으려면 평가 단계에서 설명한 테스트를 Google Compute Engine VM에서 실행하세요.

러너 플리트 구성 계획#

계획 단계에서는 조직에 적합한 러너 플리트 구성을 설계합니다. 러너 범위(인스턴스, 그룹, 프로젝트)와 다음을 기반으로 한 쿠버네티스 클러스터 구성을 고려하세요:

  • CI/CD job 리소스 수요에 대한 평가 결과

  • CI/CD job 유형 목록

러너 범위#

러너 범위를 계획하려면 다음 질문을 고려하세요:

프로젝트 Owner와 그룹 Owner가 자체 러너를 생성하고 관리하도록 할 것인가요?

기본적으로 프로젝트 및 그룹 Owner는 GitLab에서 러너 구성을 생성하고 프로젝트 또는 그룹에 러너를 등록할 수 있습니다.

  • 이 설계는 개발자가 빌드 환경을 신속하게 만들 수 있도록 합니다. 이 방법은 GitLab CI/CD를 시작할 때 개발자의 마찰을 줄여줍니다. 그러나 대규모 조직에서는 이 방법으로 인해 환경 전반에 걸쳐 활용도가 낮거나 사용되지 않는 러너가 많이 생길 수 있습니다.

조직에 특정 유형의 러너에 대한 접근을 특정 그룹이나 프로젝트로 세분화하도록 요구하는 보안 또는 기타 정책이 있나요?

GitLab Self-Managed 환경에서 러너를 배포하는 가장 간단한 방법은 인스턴스용으로 생성하는 것입니다. 인스턴스 범위의 러너는 기본적으로 모든 그룹과 프로젝트에서 사용할 수 있습니다.

조직의 모든 요구사항을 인스턴스 러너로 충족할 수 있다면, 이 배포 패턴이 가장 효율적인 패턴입니다. 이 패턴을 사용하면 CI/CD 빌드 플리트를 대규모로 효율적이고 비용 효과적으로 운영할 수 있습니다.

특정 러너에 대한 접근을 특정 그룹이나 프로젝트로 세분화해야 하는 요구사항이 있다면, 계획 프로세스에 이를 포함시키세요.

러너 플리트 구성 예시 - 인스턴스 러너#

아래 표의 구성은 조직을 위한 러너 플리트를 구성할 때 사용 가능한 유연성을 보여줍니다. 이 예시는 서로 다른 인스턴스 크기와 서로 다른 job 태그를 가진 여러 러너를 사용합니다. 이 러너들을 통해 각각 특정 CPU 및 RAM 리소스 요구사항을 가진 다양한 유형의 CI/CD job을 지원할 수 있습니다. 그러나 쿠버네티스를 사용할 때 가장 효율적인 패턴이 아닐 수 있습니다.

러너 유형 러너 태그 범위 제공할 러너 유형 수 러너 Worker 사양 러너 호스트 환경 환경 구성
Instance ci-runner-small 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 5 2 vCPU, 8 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-2
Instance ci-runner-medium 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 2 4 vCPU, 16 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-4
Instance ci-runner-large 기본적으로 모든 그룹과 프로젝트의 CI/CD job 실행에 사용 가능. 1 8 vCPU, 32 GB RAM 쿠버네티스 → 노드 3개 → Runner worker 컴퓨팅 노드 = e2-standard-8

러너 플리트 구성 예시에는 총 세 가지 러너 구성과 CI/CD job을 활발하게 실행하는 여덟 개의 러너가 있습니다.

쿠버네티스 executor를 사용하면 쿠버네티스 스케줄러를 활용하고 컨테이너 리소스를 덮어쓸 수 있습니다. 이론적으로 충분한 리소스를 갖춘 쿠버네티스 클러스터에 단일 GitLab Runner를 배포할 수 있습니다. 그런 다음 컨테이너 리소스를 덮어써서 각 CI/CD job에 적합한 컴퓨팅 유형을 선택할 수 있습니다. 이 패턴을 구현하면 배포하고 운영해야 하는 별도 러너 구성의 수를 줄일 수 있습니다.

모범 사례#

  • 항상 러너 매니저를 위한 전용 노드 풀을 만드세요.

로그 처리 및 캐시 또는 아티팩트 관리는 CPU를 많이 사용할 수 있습니다.

  • 항상 config.toml 파일에서 기본 제한(빌드/Helper/서비스 컨테이너의 CPU/메모리)을 설정하세요.

  • 항상 config.toml 파일에서 리소스의 최대 덮어쓰기를 허용하세요.

  • job 정의(.gitlab-ci.yml)에서 job에 필요한 올바른 제한을 지정하세요.

지정하지 않으면 config.toml 파일에 설정된 기본값이 사용됩니다.

  • 컨테이너가 메모리 제한을 초과하면, 시스템이 Out of Memory(OOM) 종료 프로세스를 사용하여 자동으로 종료합니다.

  • 피처 플래그 FF_RETRIEVE_POD_WARNING_EVENTSFF_PRINT_POD_EVENTS를 사용하세요. 자세한 내용은 피처 플래그 문서를 참조하세요.

GKE에 러너 배포#

Google Kubernetes 클러스터에 GitLab Runner를 설치할 준비가 되면 여러 가지 옵션이 있습니다. GKE에 클러스터를 생성한 경우, GitLab Runner Helm Chart 또는 Operator를 사용하여 클러스터에 러너를 설치할 수 있습니다.

GKE에 클러스터를 아직 설정하지 않은 경우, GitLab은 GitLab Runner Infrastructure Toolkit(GRIT)을 제공합니다. GRIT은 동시에 다음을 수행합니다:

  • 다중 노드 풀 GKE 클러스터 생성: Standard 에디션 및 standard 모드.

  • GitLab Runner 쿠버네티스 operator를 사용하여 클러스터에 GitLab Runner 설치.

다음 예시에서는 GRIT을 사용하여 Google Kubernetes 클러스터와 GitLab Runner Manager를 배포합니다.

클러스터와 GitLab Runner를 잘 구성하려면 다음 정보를 고려하세요:

  • 커버해야 할 job 유형의 수는 몇 가지인가요?

이 정보는 평가 단계에서 가져옵니다. 평가 단계에서는 조직의 제약사항을 고려하여 메트릭을 집계하고 결과 그룹의 수를 파악합니다. "job 유형"은 접근 단계에서 파악된 분류된 job의 집합입니다. 이 분류는 job에 필요한 최대 리소스를 기반으로 합니다.

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

이 정보는 계획 단계에서 가져옵니다. 조직이 프로젝트를 별도로 관리하는 경우, 각 프로젝트에 이 프레임워크를 개별적으로 적용하세요. 이 접근 방법은 여러 job 프로파일이 파악되고(전체 조직 또는 특정 프로젝트에 대해), 개인 또는 GitLab Runner 플리트가 모두 처리하는 경우에만 관련이 있습니다. 기본 구성은 일반적으로 GKE 클러스터당 하나의 GitLab Runner Manager를 사용합니다.

  • 예상 최대 동시 CI/CD job 수는 얼마인가요?

이 정보는 임의의 시점에 실행되는 최대 동시 CI/CD job 수에 대한 추정치를 나타냅니다. 이 정보는 Prepare Stage 동안 GitLab Runner Manager가 얼마나 오래 기다리는지 설정하여 GitLab Runner Manager를 구성할 때 필요합니다: 제한된 가용 리소스를 가진 노드에서의 job Pod 스케줄링.

FastAPI 포크에 대한 실제 적용 예시#

FastAPI 포크에 대해 다음 정보를 고려하세요:

  • 커버해야 할 job 프로파일의 수는 몇 가지인가요?

다음 특성을 가진 하나의 job 프로파일이 있습니다: 1 CPU303 Mi의 메모리. 수집된 메트릭 분석 섹션에서 설명한 대로, 이 원시 값은 다음과 같이 변경됩니다:

메모리 제한으로 인한 job 실패를 방지하기 위해 메모리 제한을 303 Mi 대신 400 Mi로 설정합니다.

  • CPU는 1 CPU 대신 0.20으로 설정합니다. 이 예시에서는 작업 완료 시 속도보다 정확성과 품질을 우선합니다.

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

테스트를 위해 하나의 GitLab Runner Manager면 충분합니다.

  • 예상 워크로드는 어느 정도인가요?

언제든지 최대 20개의 job을 동시에 실행하려고 합니다.

이러한 입력값을 기반으로, 다음 최소 특성을 갖춘 모든 GKE 클러스터면 충분합니다:

  • 최소 CPU: (0.20 + helper CPU 사용량) * 동시 job 수. 이 예시에서 helper 컨테이너 제한을 0.15 CPU로 설정하면 7 vCPU가 됩니다.

  • 최소 메모리: (400Mi + helper 메모리 사용량) * 동시 job 수. 이 예시에서 helper 제한을 100 Mi로 설정하면 최소 10 Gi가 됩니다.

필요한 최소 스토리지와 같은 기타 특성도 고려해야 합니다. 그러나 이 예시에서는 이를 고려하지 않습니다.

GKE 클러스터에 가능한 구성은 다음과 같습니다(두 구성 모두 20개 이상의 job을 동시에 실행할 수 있습니다):

  • 3개의 e2-standard-4 노드로 이루어진 노드 풀이 있는 GKE 클러스터: 총 12 vCPU48 GiB의 메모리

  • e2-standard-8 노드만으로 이루어진 노드 풀이 있는 GKE 클러스터: 총 8 vCPU32 GiB의 메모리

이 예시에서는 첫 번째 구성을 사용합니다. GitLab Runner Manager 로그 처리가 전체 로그 처리에 영향을 미치지 않도록 GitLab Runner가 설치된 전용 노드 풀을 사용하세요.

GKE GRIT 구성#

GRIT에 대한 결과 GKE 구성은 다음과 유사합니다:

google_project     = "GCLOUD_PROJECT"
google_region      = "GCLOUD_REGION"
google_zone        = "GCLOUD_ZONE"
name               = "my-grit-gke-cluster"
node_pools = {
  "runner-manager" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-standard-2",
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 50,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner",
      }
    },
  },
  "worker-pool" = {
    node_count = 3,
    node_config = {
      machine_type = "e2-standard-4",    #4 vCPU, 16 GB each
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
}

이전 구성에서:

  • runner-manager 블록은 GitLab Runner가 설치된 노드 풀을 나타냅니다. 이 예시에서는 e2-standard-2로 충분합니다.

  • runner-manager 블록의 labels 섹션은 GitLab에 GitLab Runner를 설치할 때 유용합니다. operator 구성을 통해 노드 선택기가 구성되어 GitLab Runner가 이 노드 풀의 노드에 설치되도록 합니다.

  • worker-pool 블록은 CI/CD job Pod가 생성되는 노드 풀을 나타냅니다. 제공된 구성은 job Pod를 호스팅하기 위해 "app" = "gitlab-runner-job" 레이블이 지정된 3개의 e2-standard-4 노드로 이루어진 노드 풀을 생성합니다.

  • image_type 파라미터를 사용하여 노드에서 사용하는 이미지를 설정할 수 있습니다. 워크로드가 주로 Windows 이미지에 의존하는 경우 windows_ltsc_containerd로 설정할 수 있습니다.

이 구성에 대한 예시 그림입니다:

[

](/19.1/topics/runner_fleet_design_guides/img/nodepool_illustration_example_v17_5.png)

GitLab Runner GRIT 구성#

GRIT에 대한 결과 GitLab Runner 구성은 다음과 유사합니다:

gitlab_pat         = "glpat-REDACTED"
gitlab_project_id  = GITLAB_PROJECT_ID
runner_description = "my-grit-gitlab-runner"
runner_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-ocp:amd64-v17.3.1"
helper_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v17.3.1"
concurrent     = 20
check_interval = 1
runner_tags    = ["my-custom-tag"]
config_template    = <

이전 구성에서:

  • pod_spec 파라미터를 통해 GitLab Runner를 실행하는 Pod에 노드 선택기를 설정할 수 있습니다. 구성에서 노드 선택기는 GitLab Runner가 runner-manager 노드 풀에 설치되도록 "app" = "gitlab-runner"로 설정됩니다.

  • config_template 파라미터는 GitLab Runner Manager가 실행하는 모든 job에 대한 기본 제한을 제공합니다. 또한 설정된 값이 기본값을 초과하지 않는 한 해당 제한의 덮어쓰기를 허용합니다.

  • 피처 플래그 FF_RETRIEVE_POD_WARNING_EVENTSFF_PRINT_POD_EVENTS도 job 실패 시 디버깅을 용이하게 하기 위해 설정됩니다. 자세한 내용은 피처 플래그 문서를 참조하세요.

가상의 사용 사례에 대한 실제 적용 예시#

다음 정보를 고려하세요:

  • 커버해야 할 job 프로파일의 수는 몇 가지인가요?

두 가지 프로파일(제공된 사양은 helper 제한을 포함합니다):

중간 규모 job: 300m CPU200 MiB

  • CPU 집약적인 job: 1 CPU1 GiB

  • 실행해야 할 GitLab Runner Manager의 수는 몇 개인가요?

하나.

  • 예상 워크로드는 어느 정도인가요?

동시에 최대 50개의 중간 규모 job

  • 동시에 최대 25개의 CPU 집약적인 job

GKE 구성#

  • 중간 규모 job에 필요한 리소스:

CPU: 300m * 50 = 5 CPU (근사치)

  • 메모리: 200 MiB * 50 = 10 GiB

  • CPU 집약적인 job에 필요한 리소스:

CPU: 1 * 25 = 25

  • 메모리: 1 GiB * 25 = 25 GiB

GKE 클러스터는 다음을 갖춰야 합니다:

  • GitLab Runner Manager용 노드 풀(로그 처리 부담이 크지 않다고 가정): e2-standard-2 노드 1개

  • 중간 규모 job용 노드 풀: e2-standard-4 노드 3개

  • CPU 집약적인 job용 노드 풀: e2-highcpu-32 노드 1개 (32 vCPU32 GiB 메모리)

google_project     = "GCLOUD_PROJECT"
google_region      = "GCLOUD_REGION"
google_zone        = "GCLOUD_ZONE"
name               = "my-grit-gke-cluster"
node_pools = {
  "runner-manager" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-standard-2",
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 50,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner",
      }
    },
  },
  "medium-pool" = {
    node_count = 3,
    node_config = {
      machine_type = "e2-standard-4",    #4 vCPU, 16 GB each
      image_type   = "cos_containerd",   #Linux OS container only. Change to windows_ltsc_containerd for Windows OS container
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
  "cpu-intensive-pool" = {
    node_count = 1,
    node_config = {
      machine_type = "e2-highcpu-32", #32 vCPU, 32 GB each
      image_type   = "cos_containerd",
      disk_size_gb = 150,
      disk_type    = "pd-balanced",
      labels = {
        "app" = "gitlab-runner-job"
      }
    },
  },
}

GitLab Runner 구성#

현재 GRIT 구현은 한 번에 두 개 이상의 러너 설치를 지원하지 않습니다. 제공된 config_template은 이전 예시에서와 같이 node_selection 및 기타 제한과 같은 구성을 설정하지 않습니다. 간단한 구성으로 CPU 집약적인 job에 대해 최대 허용 덮어쓰기 값을 허용하고 .gitlab-ci.yml 파일에서 올바른 값을 설정합니다. 결과 GitLab Runner 구성은 다음과 유사합니다:

gitlab_pat         = "glpat-REDACTED"
gitlab_project_id  = GITLAB_PROJECT_ID
runner_description = "my-grit-gitlab-runner"
runner_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-ocp:amd64-v17.3.1"
helper_image       = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v17.3.1"
concurrent     = 100
check_interval = 1
runner_tags    = ["my-custom-tag"]
config_template    = <

.gitlab-ci.yml 파일은 다음과 유사합니다:

중간 규모 job의 경우:

variables:
  KUBERNETES_CPU_LIMIT: "200m"
  KUBERNETES_MEMORY_LIMIT: "100Mi"
  KUBERNETES_HELPER_CPU_LIMIT: "100m"
  KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"

tests:
  image: some-image:latest
  script:
  - command_1
  - command_2
  # ...
  - command_n
  tags:
    - my-custom-tag

CPU 집약적인 job의 경우:

variables:
  KUBERNETES_CPU_LIMIT: "0.75"
  KUBERNETES_MEMORY_LIMIT: "900Mi"
  KUBERNETES_HELPER_CPU_LIMIT: "150m"
  KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"

tests:
  image: custom-cpu-intensive-image:latest
  script:
  - cpu_intensive_command_1
  - cpu_intensive_command_2
  # ...
  - cpu_intensive_command_n
  tags:
    - my-custom-tag
더 쉬운 구성을 위해 job 프로파일당 클러스터 하나에 하나의 GitLab Runner를 사용하세요. 이 접근 방법은 GitLab이 동일한 클러스터에 여러 GitLab Runner를 설치하거나 `config.toml` 템플릿에서 여러 `[[runners]]` 섹션을 지원할 때까지 권장됩니다.

모니터링 및 관찰 가능성 설정#

배포 단계의 마지막 단계로, 러너 호스트 환경과 GitLab Runner를 모니터링하기 위한 솔루션을 구축해야 합니다. 인프라 수준, 러너 및 CI/CD job 메트릭은 CI/CD 빌드 인프라의 효율성과 신뢰성에 대한 인사이트를 제공합니다. 또한 쿠버네티스 클러스터, GitLab Runner 및 CI/CD job 구성을 조정하고 최적화하는 데 필요한 인사이트를 제공합니다.

모니터링 모범 사례#

  • job 수준 메트릭 모니터링: job 실행 시간, job 성공 및 실패율.

job 수준 메트릭을 분석하여 가장 자주 실행되고 전체적으로 가장 많은 컴퓨팅 및 RAM 리소스를 소비하는 CI/CD job을 파악하세요. 이 job 프로파일은 최적화 기회를 평가하는 좋은 시작점입니다.

  • 쿠버네티스 클러스터 리소스 활용률 모니터링:

CPU 활용률

  • 메모리 활용률

  • 네트워크 활용률

  • 디스크 활용률

진행 방법에 대한 자세한 내용은 GitLab Runner 전용 모니터링 페이지를 참조하세요.

최적화#

CI/CD 빌드 환경을 최적화하는 것은 지속적인 프로세스입니다. CI/CD job의 유형과 양은 계속 변화하므로 적극적인 관여가 필요합니다.

CI/CD 및 CI/CD 빌드 인프라에 대한 특정 조직 목표가 있을 것입니다. 따라서 첫 번째 단계는 최적화 요구사항과 정량화 가능한 목표를 정의하는 것입니다.

다음은 고객 기반 전반에 걸친 최적화 요구사항의 예시 세트입니다:

  • CI/CD job 시작 시간

  • CI/CD job 실행 시간

  • CI/CD job 안정성

  • CI/CD 컴퓨팅 비용 최적화

다음 단계는 쿠버네티스 클러스터의 인프라 메트릭과 함께 CI/CD 메트릭 분석을 시작하는 것입니다. 분석해야 할 핵심 상관관계는 다음과 같습니다:

  • 쿠버네티스 네임스페이스별 CPU 활용률

  • 쿠버네티스 네임스페이스별 메모리 활용률

  • 노드별 CPU 활용률

  • 노드별 메모리 활용률

  • CI/CD job 실패율

일반적으로 쿠버네티스에서 높은 CI/CD job 실패율(불안정한 테스트로 인한 실패와 무관하게)은 쿠버네티스 클러스터의 리소스 제약으로 인한 것입니다. 이 메트릭을 분석하여 쿠버네티스 클러스터 구성에서 CI/CD job 시작 시간, job 실행 시간, job 안정성 및 인프라 리소스 활용 간의 최적 균형을 달성하세요.

모범 사례#

  • 조직 전반에 걸쳐 CI/CD job을 job 유형별로 분류하는 프로세스를 수립하세요.

  • 쿠버네티스에서 GitLab CI/CD 빌드 인프라와 CI/CD job 유형의 모니터링 구성 및 최적화 접근 방법을 단순화하기 위한 job 유형 분류 프레임워크를 수립하세요.

  • 클러스터의 각 job 유형에 자체 노드를 할당하면 CI/CD job 성능, job 안정성 및 인프라 활용 간의 최적 균형을 달성할 수 있습니다.

CI/CD 빌드 환경의 인프라 스택으로 쿠버네티스를 사용하면 상당한 이점이 있습니다. 그러나 쿠버네티스 인프라의 지속적인 모니터링과 최적화가 필요합니다. 관찰 가능성과 최적화 프레임워크를 수립한 후에는 매월 수백만 개의 CI/CD job을 지원할 수 있습니다. 리소스 경합을 제거하고, 결정적인 CI/CD job 실행과 최적의 리소스 사용을 달성할 수 있습니다. 이러한 개선은 운영 효율성과 비용 최적화로 이어집니다.

다음 단계#

더 나은 사용자 경험을 제공하기 위한 다음 단계를 수행하세요:

  • 동일한 클러스터에 여러 GitLab Runner를 설치 지원. 이를 통해 여러 job 프로파일을 처리해야 하는 시나리오를 더 잘 관리할 수 있습니다(GitLab Runner를 적절히 구성하여 리소스 남용을 방지할 수 있습니다).

  • GKE 노드 자동 확장 지원. 이를 통해 GKE가 워크로드에 따라 확장 및 축소할 수 있어 비용을 절감할 수 있습니다.

  • job 메트릭 모니터링 활성화. 이를 통해 관리자가 실제 사용량을 기반으로 클러스터와 GitLab Runner를 더 잘 최적화할 수 있습니다.