Docker Machine Executor autoscale configuration

자세한 사항은 Docker Machine 실행자를 준비합니다.

Runner 글로벌 옵션

매개변수 설명
concurrent 정수 전역적으로 동시에 실행되는 작업 수에 제한을 둡니다. 로컬 및 오토스케일을 사용하는 모든 정의된 러너 및 IdleCount(advanced-configuration.md#the-runnersmachine-section)와 함께 최대 머신 수에 영향을 줍니다.

[[runners]] 옵션

매개변수 설명
executor 문자열 오토스케일 기능을 사용하려면 executordocker+machine으로 설정해야 합니다.
limit 정수 이 특정 토큰에서 동시에 처리할 수 있는 작업 수를 제한합니다. 0은 제한 없음을 의미합니다. 오토스케일의 경우, 이는이 공급자에 의해 생성된 머신의 최대 한도입니다 (concurrentIdleCount와 연계).

[runners.machine] 옵션

구성 매개변수 세부 정보는 GitLab Runner - 고급 구성 - The [runners.machine] section에 나와 있습니다.

[runners.cache] 옵션

구성 매개변수 세부 정보는 GitLab Runner - 고급 구성 - The [runners.cache] 옵션에 있습니다.

추가 구성 정보

IdleCount = 0으로 설정하면 특별한 모드도 있습니다. 이 모드에서는 작업을 시작하기 전에 머신이 항상 요청됩니다 (잉여 상태의 사용 가능한 머신이 없는 경우). 작업을 마치고 나면 오토스케일 알고리즘은 아래에 설명된대로 작동합니다. 머신은 다음 작업을 기다린 다음 실행되지 않으면 IdleTime 기간이 지난 후에 머신이 제거됩니다. 작업이 없으면 Idle 상태에 머신이 없습니다.

IdleCount0보다 큰 값으로 설정하면 백그라운드에서 대기 중인 VM이 생성됩니다. 러너는 새 작업을 요청하기 전에 기존의 대기 중인 VM을 획득합니다.

  • 작업이 러너에 할당되면 해당 작업이 이전에 획득한 VM으로 전송됩니다.
  • 작업이 러너에 할당되지 않으면 대기 중인 VM의 잠금이 해제되고 VM은 풀로 반환됩니다.

Docker Machine executor로 생성되는 VM 수 제한

Docker Machine executor에 의해 생성되는 가상 머신(VM) 수를 제한하려면 config.toml 파일의 [[runners]] 섹션에서 limit 매개변수를 사용하십시오.

concurrent 매개변수는 VM의 수를 제한하지 않습니다.

여기에 자세히 나와 있듯, 한 프로세스는 여러 runner worker를 관리하도록 구성될 수 있습니다.

이 예제는 하나의 runner 프로세스에 config.toml 파일에 설정된 값들을 보여줍니다:

concurrent = 100

[[runners]]
name = "first"
executor = "shell"
limit = 40
(...)

[[runners]]
name = "second"
executor = "docker+machine"
limit = 30
(...)

[[runners]]
name = "third"
executor = "ssh"
limit = 10

[[runners]]
name = "fourth"
executor = "virtualbox"
limit = 20
(...)

이 구성에서:

  • 하나의 runner 프로세스는 다른 실행 환경을 사용하여 네 가지 다른 runner worker를 만들 수 있습니다.
  • concurrent 값은 100으로 설정되어 있으므로 이 runner는 최대 100개의 동시 GitLab CI/CD 작업을 실행할 수 있습니다.
  • 두 번째 runner worker만 Docker Machine executor를 사용하도록 구성되어 있으며 따라서 자동으로 VM을 생성할 수 있습니다.
  • limit 설정이 30이므로 두 번째 runner worker는 언제든지 autoscaled VM에서 최대 30개의 CI/CD 작업을 실행할 수 있습니다.
  • concurrent가 전역 수준에서 전체 [[runners]] worker에 걸친 전체 동시성 제한을 정의하는 반면, limit는 단일 [[runners]] worker에 대한 최대 동시성을 정의합니다.

이 예에서 runner 프로세스는 처리합니다:

  • 모든 [[runners]] worker를 통해 최대 100개의 동시 작업.
  • 첫 번째 worker의 경우, shell executor로 실행되는 최대 40개의 작업.
  • 두 번째 worker의 경우, docker+machine executor로 실행되는 최대 30개의 작업. 추가로, Runner는 [runners.machine]의 autoscaling 구성에 따라 VM을 유지하지만(대기, 사용 중, 생성 중, 제거 중) 최대 30개의 VM만 유지합니다.
  • 세 번째 worker의 경우, ssh executor로 실행되는 최대 10개의 작업.
  • 네 번째 worker의 경우, virtualbox executor로 실행되는 최대 20개의 작업.

2번째 예에서, docker+machine executor를 사용하도록 구성된 두 개의 [[runners]] worker가 있습니다. 이 구성에서 각 runner worker는 limit 매개변수의 값에 따라 제한된 별도의 VM 풀을 관리합니다.

concurrent = 100

[[runners]]
name = "first"
executor = "docker+machine"
limit = 80
(...)

[[runners]]
name = "second"
executor = "docker+machine"
limit = 50
(...)

이 예에서:

  • runner 프로세스는 100개 이상의 작업을 수행하지 않습니다. (concurrent 값)
  • runner 프로세스는 docker+machine executor를 사용하는 두 개의 [[runners]] worker에서 작업을 실행합니다.
  • 첫 번째 runner는 최대 80개의 VM를 생성할 수 있습니다. 따라서이 runner는 언제든지 최대 80개의 작업을 실행할 수 있습니다.
  • 두 번째 runner는 최대 50개의 VM를 생성할 수 있습니다. 따라서이 runner는 언제든지 최대 50개의 작업을 실행할 수 있습니다.

참고: limit 값의 합이 130 (80 + 50 = 130)이지만, 전역 수준에서의 concurrent 값이 100이기 때문에 이 runner 프로세스는 동시에 최대 100개의 작업을 실행할 수 있습니다.

Autoscaling 알고리즘 및 매개변수

자동 스케일링 알고리즘은 다음 매개변수를 기반으로 합니다:

  • IdleCount
  • IdleCountMin
  • IdleScaleFactor
  • IdleTime
  • MaxGrowthRate
  • limit

concurrent, limit, 및 IdleCount가 실행 중인 머신의 상한선을 생성하는 방법

limitconcurrent를 설정할 때 마법같은 공식은 존재하지 않습니다. 필요에 따라 행동하십시오. Idle 상태의 IdleCount는 가속 기능입니다. 인스턴스가 생성되기까지 10초/20초/30초를 기다릴 필요가 없습니다. 하지만 사용자로서, 지불해야 하는 모든 머신이 작동 중이 아니라 Idle 상태에 머물지 않도록해야 합니다. 따라서 concurrentlimit를 지불할 의사가 있는 최대 개수의 머신을 실행할 수 있는 값을 설정해야 합니다. 그리고 IdleCount는 작업 대기열이 비었을 때 미사용 머신을 생성하는 값을 설정해야 합니다.

다음 예를 가정해 봅시다.

concurrent=20

[[runners]]
  limit = 40
  [runners.machine]
    IdleCount = 10

위의 시나리오에서 가능한 머신의 총 수는 30입니다. 총 머신의 limit (작동 및 Idle)은 40일 수 있습니다. 10 대기 중인 머신이 있지만 concurrent 작업은 20입니다. 따라서 총 20개의 동시 머신이 작동 중이고 10개의 Idle 머신이있을 수 있으므로 합계는 30입니다.

그러나 limit가 생성될 수 있는 총 머신 수보다 적으면 어떻게 될까요? 아래 예제에서 해당 사례에 대해 설명합니다.

concurrent=20

[[runners]]
  limit = 25
  [runners.machine]
    IdleCount = 10

이 예에서, 최대 20개의 동시 작업 및 25개의 머신을 가질 수 있습니다. 최악의 경우, limit가 25이기 때문에 10개의 Idle 머신이 아니라 5개의 Idle 머신만 가질 수 있습니다.

IdleScaleFactor 전략

IdleCount 매개변수는 Runner가 유지해야 하는 Idle 머신의 정적 개수를 정의합니다. 할당하는 값은 사용 사례에 따라 달라집니다.

먼저 Idle 상태의 상당히 작은 수의 머신을 할당하고 현재 사용 상태에 따라 해당 수를 자동으로 더 크게 조정할 수 있습니다. 이를 위해 실험적인 IdleScaleFactor 설정을 사용하십시오.

경고: 내부적으로 IdleScaleFactorfloat64 값이며 float 형식을 사용해야합니다. 예: 0.0, 1.0, 1.5 등. 정수 형식이 사용되면 (예: IdleScaleFactor = 1), Runner의 프로세스는 오류 FATAL: Service run failed error=toml: cannot load TOML value of type int64 into a Go float가 발생합니다.

이 설정을 사용하면 GitLab Runner는 Idle 상태의 정의된 머신 수를 유지하려고 시도합니다. 그러나 이 수는 더 이상 정적이 아닙니다. IdleCount 대신에 GitLab Runner는 현재 사용중인 머신 수를 확인하고 해당 수의 요구되는 Idle 용량을 그 수의 요소로 정의합니다.

물론 현재 사용중인 머신이 없는 경우 IdleScaleFactorIdle 머신을 유지하지 않습니다. 자동 조정 알고리즘의 작동 방식 때문에, IdleCount0보다 큰 경우에만 (IdleScaleFactor가 적용될 때만) Runner는 처리할 작업을 요청하지 않을 것입니다. 새로운 작업이 없으면 사용중인 머신의 수는 증가하지 않으므로 IdleScaleFactor는 계속해서0으로 평가됩니다. 이로 인해 Runner는 사용할 수 없는 상태에 빠질 것입니다.

그러므로 우리는 두 번째 설정 IdleCountMin을 도입했습니다. 이는 IdleScaleFactor에 상관없이 유지해야 하는 최소한의 Idle 머신 수를 정의합니다. IdleScaleFactor가 사용 중이면 1보다 작은 값으로 설정할 수 없습니다. 이렇게 하면 Runner가 자동적으로 1로 설정됩니다.

또한 IdleCountMin을 사용하여 항상 사용 가능해야 하는 최소한의 Idle 머신 수를 정의할 수 있습니다. 할당하는 값은 사용 사례에 따라 달라집니다.

예를 들어:

concurrent=200

[[runners]]
  limit = 200
  [runners.machine]
    IdleCount = 100
    IdleCountMin = 10
    IdleScaleFactor = 1.1

이 경우 Runner가 결정점에 다가갈 때, Runner는 현재 사용중인 머신 수를 확인합니다. 예를 들어 현재 5개의 Idle 머신과 10개의 사용 중인 머신이 있다고 가정해 보겠습니다. IdleScaleFactor를 곱하여 Runner는 11개의 Idle 머신이 있어야한다고 결정하고 6개를 추가로 생성합니다.

90개의 Idle 머신과 100개의 사용 중인 머신이 있다면, IdleScaleFactor를 기반으로 GitLab Runner는 100 * 1.1 = 110Idle 머신을 가져야한다고 보고 다시 새로운 머신을 생성합니다. 그러나 IdleCount로 정의된 상한인 100개의 Idle 머신에 도달하면 추가 Idle 머신이 더 이상 생성되지 않는 것을 인식합니다.

100개의 사용 중인 Idle 머신이 20개로 줄어든 경우, 원하는 Idle 머신의 수는 20 * 1.1 = 22이며 GitLab Runner는 천천히 머신을 종료합니다. 앞에서 설명한대로 사용되지 않은 머신은 IdleTime 후에 제거됩니다. 따라서 너무 많은 Idle VM 제거는 지나치게 공격적으로 이루어지지 않을 것입니다.

Idle 머신의 수가 0이라면, 원하는 Idle 머신 수는 0 * 1.1 = 0입니다. 그러나 이는 정의된 IdleCountMin 설정보다 적으므로 Runner는 천천히 Idle VM을 제거하기 시작할 것이고, 10개가 남을 때까지 작동을 중단합니다.

자동 스케일링 기간 구성

자동 스케일링은 시간대에 따라 다른 값으로 구성될 수 있습니다. 기관은 정기적으로 작업이 발생하는 시간대와 작업이 거의 없는 시간대가 있을 수 있습니다. 예를 들어 대부분의 상업 회사는 월요일부터 금요일까지 10am에서 6pm과 같이 고정된 시간에 근무합니다. 이후의 밤과 주말, 그리고 주말에는 파이프라인이 시작되지 않습니다.

이러한 기간은 [[runners.machine.autoscaling]] 섹션을 사용하여 구성할 수 있습니다. 각각의 섹션은 Periods 세트를 기반으로 IdleCountIdleTime 설정을 지원합니다.

자동 스케일링 기간 작동 방식

[runners.machine] 설정에서 여러 [[runners.machine.autoscaling]] 섹션을 추가할 수 있습니다. 각각의 섹션은 해당하는 IdleCount, IdleTime, Periods, Timezone 속성을 가지고 있습니다. 가장 일반적인 시나리오에서 가장 구체적인 시나리오 순으로 각 구성에 대한 섹션을 정의해야 합니다.

모든 섹션은 구문 분석됩니다. 현재 시간에 일치하는 마지막 섹션이 활성화됩니다. 일치하는 것이 없으면 [runners.machine]의 루트에서 값이 사용됩니다.

예를 들어:

[runners.machine]
  MachineName = "auto-scale-%s"
  MachineDriver = "google"
  IdleCount = 10
  IdleTime = 1800
  [[runners.machine.autoscaling]]
    Periods = ["* * 9-17 * * mon-fri *"]
    IdleCount = 50
    IdleTime = 3600
    Timezone = "UTC"
  [[runners.machine.autoscaling]]
    Periods = ["* * * * * sat,sun *"]
    IdleCount = 5
    IdleTime = 60
    Timezone = "UTC"

이 구성에서 UTC 기준으로 주중마다 9시부터 16시 59분 사이에는 머신이 과다 구성되어 운영 시간 동안의 대규모 트래픽을 처리합니다. 주말에는 트래픽 감소를 고려하여 IdleCount가 5로 줄어듭니다. 나머지 시간에는 기본값으로부터 값을 가져옵니다 - IdleCount = 10IdleTime = 1800.

참고: 지정한 기간의 마지막분의 59초는 해당 기간의 일부로 고려되지 않습니다. 더 많은 정보는 issue #2170을 참조하세요.

특정 기간의 Timezone을 지정할 수 있으며, 예를 들면 "Australia/Sydney"입니다. 이를 지정하지 않으면 모든 러너의 호스트 머신의 시스템 설정이 사용됩니다. 기본값은 명시적으로 Timezone = "Local"로 명시할 수 있습니다.

[[runner.machine.autoscaling]] 섹션의 구문에 대한 자세한 정보는 GitLab Runner - 고급 구성 - [runners.machine] 섹션에서 찾을 수 있습니다.

후단 시간 모드 구성 (제거됨)

이 기능은 GitLab 14.0에서 제거되었습니다. 대신 자동 스케일링 기간을 사용하세요.

분산 러너 캐싱

참고: 분산 캐시를 사용하는 방법을 읽어보세요.

작업을 가속화하기 위해 GitLab Runner는 캐시 메커니즘을 제공합니다. 선택한 디렉터리와/또는 파일들이 저장되어 후속 작업 사이에 공유됩니다.

같은 호스트에서 작업을 실행할 때는 잘 작동하나, GitLab Runner 자동 스케일링 기능을 사용하면 대부분의 작업이 새로운 (또는 거의 새로운) 호스트에서 실행되어 각 작업을 새 Docker 컨테이너에서 실행합니다. 이 경우에는 캐시 기능을 활용할 수 없습니다.

분산 러너 캐시 기능은 이 문제를 극복하기 위해 도입되었습니다.

이 기능은 구성된 객체 저장 서버를 사용하여 사용된 Docker 호스트 간에 캐시를 공유합니다. GitLab Runner는 서버를 쿼리하고 캐시를 복원하기 위해 아카이브를 다운로드하거나 캐시를 아카이브하기 위해 업로드합니다.

분산 캐싱을 활성화하려면 config.toml에서 [runners.cache] 지시문을 정의해야 합니다:

[[runners]]
  limit = 10
  executor = "docker+machine"
  [runners.cache]
    Type = "s3"
    Path = "path/to/prefix"
    Shared = false
    [runners.cache.s3]
      ServerAddress = "s3.example.com"
      AccessKey = "access-key"
      SecretKey = "secret-key"
      BucketName = "runner"
      Insecure = false

위의 예에서 S3 URL은 다음 구조를 따릅니다. http(s)://<ServerAddress>/<BucketName>/<Path>/runner/<runner-id>/project/<id>/<cache-key>.

두 개 이상의 러너 간에 캐시를 공유하려면 Shared 플래그를 true로 설정하세요. 이 플래그는 URL에서 러너 토큰 (runner/<runner-id>)을 제거하고 모든 구성된 러너가 동일한 캐시를 공유합니다. 또한 캐시 공유가 활성화된 경우 Path를 설정하여 러너 간에 별도 캐시를 설정할 수 있습니다.

분산 컨테이너 레지스트리 미러링

도커 컨테이너 내부에서 실행되는 작업을 가속화하기 위해 도커 레지스트리 미러링 서비스를 사용할 수 있습니다. 이 서비스는 도커 머신과 모든 사용 중인 레지스트리 간의 프록시를 제공합니다. 이미지는 레지스트리 미러에 의해 한 번 다운로드됩니다. 각 새로운 호스트에서 또는 이미지를 사용할 수 없는 기존 호스트에서는 구성된 레지스트리 미러에서 이미지가 다운로드됩니다.

도커 머신 LAN에 미러가 있는 경우 각 호스트에서 이미지 다운로드 단계가 훨씬 빨라질 것으로 예상됩니다.

도커 레지스트리 미러링을 구성하려면 config.tomlMachineOptions를 추가해야 합니다:

[[runners]]
  limit = 10
  executor = "docker+machine"
  [runners.machine]
    (...)
    MachineOptions = [
      (...)
      "engine-registry-mirror=http://10.11.12.13:12345"
    ]

여기서 10.11.12.13:12345는 레지스트리 미러가 도커 서비스로부터의 연결을 수신하기 위해 대기 중인 IP 주소와 포트입니다. Docker Machine에 의해 생성된 각 호스트에서 접근 가능해야 합니다.

컨테이너용으로 프록시를 사용하는 방법에 대해 자세히 알아보려면 여기를 확인하세요.

config.toml의 완전한 예시

아래의 config.tomlgoogle Docker Machine driver를 사용합니다.

concurrent = 50   # 등록된 모든 러너가 최대 50개의 동시 작업을 실행할 수 있습니다.

[[runners]]
  url = "https://gitlab.com"
  token = "RUNNER_TOKEN"             # 이는 `gitlab-runner`를 등록할 때 사용하는 등록 토큰과는 다릅니다
  name = "autoscale-runner"
  executor = "docker+machine"        # 이 러너는 'docker+machine' 실행자를 사용합니다
  limit = 10                         # 이 러너는 최대 10개의 작업(생성된 머신)을 실행할 수 있습니다
  [runners.docker]
    image = "ruby:2.7"               # 작업에 사용되는 기본 이미지는 'ruby:2.7'입니다
  [runners.machine]
    IdleCount = 5                    # 무단 이용 시간 모드가 꺼진 경우 5대의 머신이 유휴 상태여야 합니다
    IdleTime = 600                   # 각 머신은 최대 600초 동안 유휴 상태일 수 있습니다(이후에 제거됩니다) - 무단 이용 시간 모드가 꺼진 경우
    MaxBuilds = 100                  # 각 머신은 최대 100개의 작업을 연속으로 처리할 수 있습니다(이후에 제거됩니다)
    MachineName = "auto-scale-%s"    # 각 머신은 고유한 이름을 가져야 합니다('%s'가 필요합니다)
    MachineDriver = "google" # 머신이 Google Compute Engine에 호스팅되도록 하는 도커 머신용 Google 드라이버 참조: https://docs.docker.com/machine/drivers/gce/#credentials
    MachineOptions = [
      "google-project=GOOGLE-PROJECT-ID",
      "google-zone=GOOGLE-ZONE", # 예: 'us-central-1'
      "google-machine-type=GOOGLE-MACHINE-TYPE", # 예: 'n1-standard-8'
      "google-machine-image=ubuntu-os-cloud/global/images/family/ubuntu-1804-lts",
      "google-username=root",
      "google-use-internal-ip",
      "engine-registry-mirror=https://mirror.gcr.io"
    ]
    [[runners.machine.autoscaling]]  # 다양한 설정으로 기간을 정의합니다
      Periods = ["* * 9-17 * * mon-fri *"] # 매주 월-금 9시부터 17시까지의 근무시간
      IdleCount = 50
      IdleCountMin = 5
      IdleScaleFactor = 1.5 # 현재 유휴 상태의 머신 수를 현재 사용 중인 머신 수의 1.5배로 설정, 최대 50(IdleCount의 값) 이하, 최소 5(IdleCountMin의 값) 이상
      IdleTime = 3600
      Timezone = "UTC"
    [[runners.machine.autoscaling]]
      Periods = ["* * * * * sat,sun *"] # 주말 동안
      IdleCount = 5
      IdleTime = 60
      Timezone = "UTC"
  [runners.cache]
    Type = "s3"
    [runners.cache.s3]
      ServerAddress = "s3.eu-west-1.amazonaws.com"
      AccessKey = "AMAZON_S3_ACCESS_KEY"
      SecretKey = "AMAZON_S3_SECRET_KEY"
      BucketName = "runner"
      Insecure = false

MachineOptions 매개변수에는 도커 머신에서 호스팅된 머신을 생성하기 위해 사용되는 google 드라이버를 위한 옵션과 도커 머신 자체를 위한 하나의 옵션이 포함되어 있음에 유의하십시오(engine-registry-mirror).