スロットベースのcgroupのサポート
スロットベースのcgroupのサポートにより、オートスケール構成でGitLab Runnerを利用する際のリソース分離と管理が向上します。スロットベースのcgroupは、オートスケーラーによって割り当てられたスロット番号に基づき、ジョブを特定のコントロールグループ(cgroup)に自動的に割り当てます。
メリット
- リソース分離の改善: 同一インスタンス上で同時実行するジョブ同士のリソースの干渉を防ぎます。
- モニタリングの簡素化: スロットごとのリソース使用量を個別に追跡できます。
- デバッグの向上: cgroupベースのメトリクスにより、リソースを大量に消費するジョブを特定しやすくなります。
- きめ細かな制御: スロット単位でリソース制限を設定し、予測可能なパフォーマンスを実現します。
サポートされているexecutor
スロットベースのcgroupは、スロット管理にtaskscalerを使用するオートスケールexecutorで動作します:
前提条件
- cgroup v2をサポートするLinuxホスト
- cgroup階層の初期セットアップのためのルートアクセス
- オートスケーラー機能を備えたGitLab Runner
- スロットの割り当てのためのtaskscaler(オートスケーラーが自動的に提供)
設定
スロットベースのcgroupサポートを有効にするには、次の内容をconfig.tomlに追加します。
systemd cgroupドライバーを使用するDockerの場合
Dockerがsystemd cgroupドライバー(最も一般的)を使用している場合は、systemdスライス形式を使用します:
[[runners]]
name = "my-autoscaler-runner"
executor = "docker-autoscaler"
use_slot_cgroups = true
slot_cgroup_template = "runner-slot-${slot}.slice"
[runners.autoscaler]
capacity_per_instance = 4cgroupfsドライバーを使用するDockerの場合
Dockerがcgroupfsドライバーを使用している場合は、raw 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}" |
テンプレートはbashスタイルの変数展開を使用し、スロット番号のプレースホルダーとして${slot}を使用します。例:
systemdドライバーの場合: スロット5ではrunner-slot-${slot}.sliceはrunner-slot-5.sliceになりますcgroupfsドライバーの場合: スロット5ではgitlab-runner/slot-${slot}はgitlab-runner/slot-5になります
Docker cgroupドライバーは、次のコマンドで確認できます: docker info | grep "Cgroup Driver"
Docker固有の設定
Docker Autoscaler executorを使用している場合は、サービスコンテナ用に別のテンプレートを指定できます:
[[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と同じ |
環境設定
スロットベースのcgroupsを有効にする前に、Runnerホストでcgroup階層を準備します。
systemd cgroupドライバー用のセットアップスクリプト
Dockerがsystemd cgroupドライバーを使用している場合(docker info | grep "Cgroup Driver"で確認)、raw cgroupディレクトリではなくsystemdスライスを作成する必要があります。
セットアップスクリプトを作成します(gitlab-runner-systemd-slice-setup.sh):
#!/bin/bash
# gitlab-runner-systemd-slice-setup.sh
# Script to set up systemd slices for GitLab Runner slot-based cgroups
# This example configures 4 slots on an 8-core machine, with each slot pinned to 2 CPUs
set -e
MAX_SLOTS=4 # Adjust based on your capacity_per_instance configuration
# CPU pinning configuration (2 CPUs per slot on an 8-core machine)
# Format: comma-separated CPU list for systemd AllowedCPUs
declare -a CPU_ASSIGNMENTS=(
"0,1" # Slot 0: CPUs 0 and 1
"2,3" # Slot 1: CPUs 2 and 3
"4,5" # Slot 2: CPUs 4 and 5
"6,7" # Slot 3: CPUs 6 and 7
)
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root for systemd slice setup"
exit 1
fi
# Verify systemd is available
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<MAX_SLOTS; slot++)); do
slice_name="runner-slot-${slot}.slice"
echo "Creating systemd slice: $slice_name (CPUs: ${CPU_ASSIGNMENTS[$slot]})"
# Create systemd slice configuration
cat > "/etc/systemd/system/$slice_name" <<EOF
[Unit]
Description=GitLab Runner Slot $slot
Before=slices.target
[Slice]
CPUAccounting=true
MemoryAccounting=true
AllowedCPUs=${CPU_ASSIGNMENTS[$slot]}
EOF
done
# Reload systemd to pick up new slice units
systemctl daemon-reload
# Start all slices
for ((slot=0; slot<MAX_SLOTS; slot++)); do
slice_name="runner-slot-${slot}.slice"
systemctl start "$slice_name"
done
echo ""
echo "Systemd slices created successfully!"
echo ""
echo "Verifying slices:"
for ((slot=0; slot<MAX_SLOTS; slot++)); do
slice_name="runner-slot-${slot}.slice"
status=$(systemctl is-active "$slice_name" 2>/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.shcgroupfsドライバー用のセットアップスクリプト(代替)
Dockerがsystemdではなくcgroupfsドライバーを使用している場合は、raw cgroupディレクトリを作成する次の代替スクリプトを使用します:
#!/bin/bash
# gitlab-runner-cgroup-setup.sh
# Script to set up cgroup v2 hierarchy for GitLab Runner slot-based cgroups
# This example configures 4 slots on an 8-core machine, with each slot pinned to 2 CPUs
# Use this script only if Docker is using the cgroupfs driver (not systemd)
set -e
CGROUP_ROOT="/sys/fs/cgroup"
RUNNER_CGROUP="gitlab-runner"
MAX_SLOTS=4 # Adjust based on your capacity_per_instance configuration
# CPU pinning configuration (2 CPUs per slot on an 8-core machine)
# Format: "cpu_list" - adjust based on your CPU topology
declare -a CPU_ASSIGNMENTS=(
"0-1" # Slot 0: CPUs 0 and 1
"2-3" # Slot 1: CPUs 2 and 3
"4-5" # Slot 2: CPUs 4 and 5
"6-7" # Slot 3: CPUs 6 and 7
)
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root for cgroup setup"
exit 1
fi
# Verify cgroup v2 is available
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)"
# Create base runner cgroup
mkdir -p "$CGROUP_ROOT/$RUNNER_CGROUP"
# Enable controllers if available
if [[ -f "$CGROUP_ROOT/cgroup.controllers" ]]; then
echo "+memory +cpu +cpuset" > "$CGROUP_ROOT/cgroup.subtree_control" 2>/dev/null || true
fi
# Create slot-specific cgroups
for ((slot=0; slot<MAX_SLOTS; slot++)); do
slot_path="$CGROUP_ROOT/$RUNNER_CGROUP/slot-$slot"
echo "Creating cgroup for slot $slot (CPUs: ${CPU_ASSIGNMENTS[$slot]})"
mkdir -p "$slot_path"
# Enable controllers for this slot
if [[ -f "$CGROUP_ROOT/$RUNNER_CGROUP/cgroup.controllers" ]]; then
echo "+memory +cpu +cpuset" > "$CGROUP_ROOT/$RUNNER_CGROUP/cgroup.subtree_control" 2>/dev/null || true
fi
# Pin slot to specific CPUs
echo "${CPU_ASSIGNMENTS[$slot]}" > "$slot_path/cpuset.cpus"
# Set memory nodes (usually 0 for single NUMA node systems)
echo "0" > "$slot_path/cpuset.mems"
# Set permissions for GitLab Runner user
chown -R gitlab-runner:gitlab-runner "$slot_path" 2>/dev/null || true
done
echo "Cgroup setup complete!"
# Verify setup
echo ""
echo "Verifying cgroup setup:"
for ((slot=0; slot<MAX_SLOTS; slot++)); do
slot_path="$CGROUP_ROOT/$RUNNER_CGROUP/slot-$slot"
cpus=$(cat "$slot_path/cpuset.cpus")
echo " Slot $slot: CPUs $cpus"
doneセットアップスクリプトを実行します:
chmod +x gitlab-runner-cgroup-setup.sh
sudo ./gitlab-runner-cgroup-setup.sh仕組み
Docker Autoscaler executor
Docker Autoscaler executorは、--cgroup-parentフラグを使用して、スロットベースのcgroupパスをDockerコンテナに自動的に適用します。ビルドコンテナとサービスコンテナの両方が、ジョブスクリプトを変更しなくてもスロット固有のcgroupに割り当てられます。
インスタンスexecutor
インスタンスexecutorは、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-processcgexecを使用する
job:
script:
- echo "Running in cgroup $GITLAB_RUNNER_SLOT_CGROUP"
- cgexec -g cpu,memory:$GITLAB_RUNNER_SLOT_CGROUP ./my-processcgroup制限を設定する
ジョブプロセスを実行する前に、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}プレースホルダーを含む正しい形式を使用していることを確認します:GitLab Runnerログで、cgroup作成に関する具体的なエラーを確認します:
手動でテストします:
Docker Autoscaler executorの場合:
docker run --rm --cgroup-parent=gitlab-runner/slot-0 alpine echo "test"インスタンスexecutorの場合:
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ディストリビューションのドキュメントを確認してください。最新のディストリビューションでは通常、デフォルトで有効になっています。