슬롯 기반 cgroup 지원
슬롯 기반 cgroup 지원은 GitLab Runner를 자동 스케일링과 함께 사용할 때 리소스 격리 및 관리를 개선합니다. 슬롯 기반 cgroup은 슬롯 관리를 위해 taskscaler를 사용하는 자동 스케일링 실행자와 함께 작동합니다:
슬롯 기반 cgroup 지원은 GitLab Runner를 자동 스케일링과 함께 사용할 때 리소스 격리 및 관리를 개선합니다. 슬롯 기반 cgroup은 자동 스케일러가 할당한 슬롯 번호를 기반으로 작업을 특정 컨트롤 그룹(cgroup)에 자동으로 할당합니다.
장점#
- 더 나은 리소스 격리: 동일한 인스턴스에서 동시 작업 간의 리소스 간섭을 방지합니다.
- 더 쉬운 모니터링: 슬롯별 리소스 사용량을 독립적으로 추적할 수 있습니다.
- 향상된 디버깅: cgroup 기반 메트릭으로 리소스를 많이 사용하는 작업을 식별하는 데 도움이 됩니다.
- 세밀한 제어: 예측 가능한 성능을 위해 슬롯별 리소스 제한을 설정합니다.
지원되는 실행자#
슬롯 기반 cgroup은 슬롯 관리를 위해 taskscaler를 사용하는 자동 스케일링 실행자와 함께 작동합니다:
필수 조건#
- cgroup v2 지원이 있는 Linux 호스트
- 초기 cgroup 계층 구조 설정을 위한 루트 액세스
- 자동 스케일러 기능이 있는 GitLab Runner
- 슬롯 할당을 위한 Taskscaler (자동 스케일러에 의해 자동으로 제공됨)
구성#
슬롯 기반 cgroup 지원을 활성화하려면 config.toml에 다음을 추가합니다.
systemd cgroup 드라이버를 사용하는 Docker의 경우#
Docker가 systemd cgroup 드라이버를 사용하는 경우 (가장 일반적), systemd 슬라이스(slice) 형식을 사용합니다:
[[runners]]
name = "my-autoscaler-runner"
executor = "docker-autoscaler"
use_slot_cgroups = true
slot_cgroup_template = "runner-slot-${slot}.slice"
[runners.autoscaler]
capacity_per_instance = 4
cgroupfs 드라이버를 사용하는 Docker의 경우#
Docker가 cgroupfs 드라이버를 사용하는 경우, 원시 cgroup 경로 형식을 사용합니다:
[[runners]]
name = "my-autoscaler-runner"
executor = "docker-autoscaler"
use_slot_cgroups = true
slot_cgroup_template = "gitlab-runner/slot-${slot}"
[runners.autoscaler]
capacity_per_instance = 4
구성 옵션#
| 설정 | 설명 | 기본값 |
|---|---|---|
use_slot_cgroups |
슬롯 기반 cgroup 할당 활성화 | false |
slot_cgroup_template |
cgroup 경로 템플릿. ${slot}을 자리 표시자로 사용합니다. 형식은 Docker의 cgroup 드라이버에 따라 다릅니다 (systemd: runner-slot-${slot}.slice, cgroupfs: gitlab-runner/slot-${slot}) |
"gitlab-runner/slot-${slot}" |
템플릿은 슬롯 번호의 자리 표시자로 ${slot}을 사용하는 bash 스타일 변수 확장을 사용합니다. 예를 들어:
systemd드라이버 사용 시:runner-slot-${slot}.slice는 슬롯 5에서runner-slot-5.slice가 됩니다cgroupfs드라이버 사용 시:gitlab-runner/slot-${slot}은 슬롯 5에서gitlab-runner/slot-5가 됩니다
Docker cgroup 드라이버를 확인하려면: docker info | grep "Cgroup Driver"
Docker 특정 구성#
Docker Autoscaler 실행자를 사용할 때 서비스 컨테이너에 별도의 템플릿을 지정할 수 있습니다:
[[runners]]
executor = "docker-autoscaler"
use_slot_cgroups = true
slot_cgroup_template = "runner-slot-${slot}.slice"
[runners.docker]
service_slot_cgroup_template = "runner-slot-${slot}.slice"
| 설정 | 설명 | 기본값 |
|---|---|---|
service_slot_cgroup_template |
서비스 컨테이너 cgroup 경로 템플릿. Docker의 cgroup 드라이버 형식과 일치해야 합니다 | slot_cgroup_template과 동일 |
환경 설정#
슬롯 기반 cgroup을 활성화하기 전에 러너 호스트에서 cgroup 계층 구조를 준비합니다.
systemd cgroup 드라이버용 설정 스크립트#
Docker가 systemd cgroup 드라이버를 사용하는 경우 (docker info | grep "Cgroup Driver"로 확인), 원시 cgroup 디렉터리 대신 systemd 슬라이스를 생성해야 합니다.
설정 스크립트 (gitlab-runner-systemd-slice-setup.sh)를 생성합니다:
#!/bin/bash
# gitlab-runner-systemd-slice-setup.sh
# GitLab Runner 슬롯 기반 cgroup을 위한 systemd 슬라이스 설정 스크립트
# 이 예시는 8코어 머신에서 4개의 슬롯을 구성하며, 각 슬롯은 2개의 CPU에 고정됩니다
set -e
MAX_SLOTS=4 # capacity_per_instance 구성에 따라 조정하세요
# CPU 고정 구성 (8코어 머신에서 슬롯당 2개의 CPU)
# 형식: systemd AllowedCPUs에 대한 쉼표로 구분된 CPU 목록
declare -a CPU_ASSIGNMENTS=(
"0,1" # 슬롯 0: CPU 0과 1
"2,3" # 슬롯 1: CPU 2와 3
"4,5" # 슬롯 2: CPU 4와 5
"6,7" # 슬롯 3: CPU 6과 7
)
# 루트로 실행 중인지 확인
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root for systemd slice setup"
exit 1
fi
# systemd 사용 가능 여부 확인
if ! command -v systemctl &> /dev/null; then
echo "Error: systemctl not found. This script requires systemd."
exit 1
fi
echo "Setting up systemd slices for GitLab Runner"
echo "Configuration: $MAX_SLOTS slots on an 8-core machine (2 CPUs per slot)"
for ((slot=0; slot "/etc/systemd/system/$slice_name" <
# 새 슬라이스 유닛을 인식하기 위해 systemd 리로드
systemctl daemon-reload
# 모든 슬라이스 시작
for ((slot=0; slot/dev/null || echo "inactive")
echo " $slice_name: $status"
done
echo ""
echo "To verify CPU assignments, check:"
echo " systemctl show runner-slot-0.slice | grep AllowedCPUs"
설정 스크립트를 실행합니다:
chmod +x gitlab-runner-systemd-slice-setup.sh
sudo ./gitlab-runner-systemd-slice-setup.sh
cgroupfs 드라이버용 설정 스크립트 (대안)#
Docker가 systemd 대신 cgroupfs 드라이버를 사용하는 경우, 원시 cgroup 디렉터리를 생성하는 이 대안 스크립트를 사용합니다:
#!/bin/bash
# gitlab-runner-cgroup-setup.sh
# GitLab Runner 슬롯 기반 cgroup을 위한 cgroup v2 계층 구조 설정 스크립트
# 이 예시는 8코어 머신에서 4개의 슬롯을 구성하며, 각 슬롯은 2개의 CPU에 고정됩니다
# Docker가 cgroupfs 드라이버를 사용하는 경우에만 이 스크립트를 사용하세요 (systemd 아닌 경우)
set -e
CGROUP_ROOT="/sys/fs/cgroup"
RUNNER_CGROUP="gitlab-runner"
MAX_SLOTS=4 # capacity_per_instance 구성에 따라 조정하세요
# CPU 고정 구성 (8코어 머신에서 슬롯당 2개의 CPU)
# 형식: "cpu_list" - CPU 토폴로지에 따라 조정하세요
declare -a CPU_ASSIGNMENTS=(
"0-1" # 슬롯 0: CPU 0과 1
"2-3" # 슬롯 1: CPU 2와 3
"4-5" # 슬롯 2: CPU 4와 5
"6-7" # 슬롯 3: CPU 6과 7
)
# 루트로 실행 중인지 확인
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root for cgroup setup"
exit 1
fi
# cgroup v2 사용 가능 여부 확인
if [[ ! -f "$CGROUP_ROOT/cgroup.controllers" ]]; then
echo "Error: cgroup v2 not detected. This script requires cgroup v2."
exit 1
fi
echo "Setting up cgroup v2 hierarchy for GitLab Runner"
echo "Configuration: $MAX_SLOTS slots on an 8-core machine (2 CPUs per slot)"
# 기본 러너 cgroup 생성
mkdir -p "$CGROUP_ROOT/$RUNNER_CGROUP"
# 사용 가능한 경우 컨트롤러 활성화
if [[ -f "$CGROUP_ROOT/cgroup.controllers" ]]; then
echo "+memory +cpu +cpuset" > "$CGROUP_ROOT/cgroup.subtree_control" 2>/dev/null || true
fi
# 슬롯별 cgroup 생성
for ((slot=0; slot "$CGROUP_ROOT/$RUNNER_CGROUP/cgroup.subtree_control" 2>/dev/null || true
fi
# 특정 CPU에 슬롯 고정
echo "${CPU_ASSIGNMENTS[$slot]}" > "$slot_path/cpuset.cpus"
# 메모리 노드 설정 (단일 NUMA 노드 시스템의 경우 일반적으로 0)
echo "0" > "$slot_path/cpuset.mems"
# GitLab Runner 사용자에 대한 권한 설정
chown -R gitlab-runner:gitlab-runner "$slot_path" 2>/dev/null || true
done
echo "Cgroup setup complete!"
# 설정 확인
echo ""
echo "Verifying cgroup setup:"
for ((slot=0; slot
설정 스크립트를 실행합니다:
chmod +x gitlab-runner-cgroup-setup.sh
sudo ./gitlab-runner-cgroup-setup.sh
작동 방식#
Docker Autoscaler 실행자#
Docker Autoscaler 실행자는 --cgroup-parent 플래그를 사용하여 슬롯 기반 cgroup 경로를 Docker 컨테이너에 자동으로 적용합니다. 빌드 컨테이너와 서비스 컨테이너 모두 작업 스크립트를 변경할 필요 없이 슬롯별 cgroup에 할당됩니다.
Instance 실행자#
Instance 실행자는 작업에 GITLAB_RUNNER_SLOT_CGROUP 환경 변수를 제공합니다. 작업 스크립트에서 이 변수를 사용하여 슬롯별 cgroup 아래에서 프로세스를 실행할 수 있습니다.
systemd-run 사용#
job:
script:
- echo "Running in cgroup $GITLAB_RUNNER_SLOT_CGROUP"
- systemd-run --scope --slice=$GITLAB_RUNNER_SLOT_CGROUP ./my-process
cgexec 사용#
job:
script:
- echo "Running in cgroup $GITLAB_RUNNER_SLOT_CGROUP"
- cgexec -g cpu,memory:$GITLAB_RUNNER_SLOT_CGROUP ./my-process
cgroup 제한 설정#
작업 프로세스를 실행하기 전에 cgroup에 리소스 제한을 설정할 수 있습니다:
job:
script:
- echo "Configuring cgroup limits"
- echo "100M" > /sys/fs/cgroup/$GITLAB_RUNNER_SLOT_CGROUP/memory.max
- echo "50000" > /sys/fs/cgroup/$GITLAB_RUNNER_SLOT_CGROUP/cpu.max
- ./my-process
트러블슈팅#
cgroup 오류로 컨테이너 시작 실패#
-
/sys/fs/cgroup/아래에 cgroup 경로가 있는지 확인합니다:ls -la /sys/fs/cgroup/gitlab-runner/ -
GitLab Runner 사용자가 cgroup 디렉터리에 쓰기 액세스 권한이 있는지 확인합니다:
ls -la /sys/fs/cgroup/gitlab-runner/slot-0/ -
slot_cgroup_template이${slot}자리 표시자를 사용하는 올바른 형식을 사용하는지 확인합니다: -
특정 cgroup 생성 오류에 대한 GitLab Runner 로그를 확인합니다:
-
수동으로 테스트합니다:
Docker Autoscaler 실행자의 경우:
docker run --rm --cgroup-parent=gitlab-runner/slot-0 alpine echo "test"Instance 실행자의 경우:
job: script: - echo "Slot cgroup: $GITLAB_RUNNER_SLOT_CGROUP"
작업이 동일한 cgroup을 사용#
로그에서 템플릿에 ${slot} 자리 표시자가 포함되지 않았다는 경고가 표시되는 경우:
level=warning msg="Slot cgroup template does not contain ${slot} placeholder.
All jobs will use the same cgroup, defeating the purpose of slot-based isolation."
이는 slot_cgroup_template에 ${slot} 변수가 누락되었음을 의미합니다. 자리 표시자를 포함하도록 구성을 업데이트하세요:
[[runners]]
slot_cgroup_template = "gitlab-runner/slot-${slot}"
cgroup v2를 사용할 수 없는 경우#
설정 스크립트에서 cgroup v2가 감지되지 않는다고 보고하면 시스템에서 이를 활성화해야 할 수 있습니다. cgroup v2 활성화에 대한 Linux 배포판 문서를 확인하세요. 최신 배포판은 일반적으로 기본적으로 이를 활성화합니다.
