콘텐츠로 이동

GitLab Runner (운영 기준)

0. 전제

다음 환경 기준으로 작성:

  • 규모: 프로젝트 5~20개 / 서버 소수
  • 인력: 1~2명 (소수 정예)
  • 멀티 스택 환경: Node.js, Express, Next.js, Nuxt.js, PHP, Laravel, C++ 등
  • 운영 서버: Linux / Windows 혼합 가능
  • Docker 사용 범위: Runner 빌드 환경 및 Release Storage 서버의 AIStor 실행 용도
  • 배포 방식: 운영 서버가 Release Storage에서 빌드 결과물을 직접 가져가는 pull 배포

인프라 전제:

  • GitLab 서버, Runner 서버, Release Storage 서버, 운영 서버는 논리적, 물리적으로 분리 가능한 구성으로 보며, 분리 운영을 전제로 작성함.
  • GitLab 서버는 외부 비공개로 유지하며, 운영 서버는 GitLab 서버에 직접 접근하지 않음.
  • Release Storage 서버는 운영 서버가 접근 가능한 별도 서버로 구성함.

운영 원칙:

  • build -> publish -> operation server pull deploy 구조 유지
  • {YYYYMMDD-HHMMSS}-{declared_version}-{CI_COMMIT_SHORT_SHA} 기반 immutable package version 운영
  • 인증은 목적별 계정 및 Access Key로 분리
  • 빌드: Runner 서버
  • CI 내부 산출물 보관: GitLab Generic Package Registry
  • 운영 배포 기준 저장소: Release Storage (S3-compatible Object Storage)
  • 운영: download, verify, extract, activate, report 수행

금지 사항:

  • 운영 서버에 write 권한 Access Key 배치 금지
  • .env 및 서버 고유 설정 파일을 패키지에 포함 금지
  • 운영 서버에서 배포 파일을 수동 수정한 뒤 재사용 금지
  • Generic Package Registry에 업로드된 package version/file overwrite 금지
  • Release Storage 의 releases 경로 Release Object overwrite 금지
  • Release Storage 의 current/{RELEASE_ENV}.json 외 object overwrite 금지
  • 운영 서버가 GitLab 서버에 직접 접근하도록 구성 금지

위 전제를 기반으로
GitLab Runner를 실제로 사용할 수 있는 상태까지 준비하는 단계를 정의함.


1. 개요

1.1 중요

  • Runner 는 GitLab 서버와 동일 서버 또는 별도 서버에 설치 가능
  • Runner가 별도 서버에 설치되는 구조까지 포함하여 작성하며, 설치 위치에 따라 네트워크 접근 및 권한 설정이 달라질 수 있음

1.2 Runner 구성 및 분리 정책

  • 프로젝트별로 Runner를 신뢰 경계(Trust Boundary) 즉, 실행 코드의 신뢰 수준 기준으로 분리하여 구성.
  • Untrusted Runner (Merge Request)Trusted Runner (Build)는 반드시 분리함

Runner 구성:

구분 Merge Request Runner Build Runner
신뢰 수준 Untrusted Trusted
대상 작업 브랜치 / Merge Request Protected release target branch
실행 Pipeline merge_request_event push / Web(New Pipeline)
Executor Docker Docker
역할 최소 검증 (lint / test / MR route check) build / package / release-state publish
실제 배포 수행
Generic Package Registry 접근 ⭕ (write 가능)
Release Storage 접근 ⭕ (write 가능)
운영 서버 접근
Protected Runner
Protected Branch 실행
민감 정보 접근

운영 기준:

  • 필요 시 동일 서버에 함께 설치할 수 있으나, 운영 환경에서는 별도 서버 분리 구성을 우선 고려함

  • 예를 들어,

    • Merge Request Runner 는 A 서버에 구성
    • Build Runner 는 B 서버에 구성
  • Merge Request Runner: Docker Executor

    • Merge Request 단계에서 실행되는 검증 전용 Runner
    • 최소 검증(lint, test, syntax check 등)만 수행
    • "Pipelines must succeed" 조건 충족을 위한 CI gate 역할
    • 제한 사항:
      • 배포 토큰 사용 금지
      • Registry write 권한 금지
      • build / package / release publish 작업 금지
      • 운영 서버 접근 금지
  • Build Runner: Docker Executor

    • release target branch 의 build / package / release-state publish 작업을 수행함
    • release target branch 는 .ops/ci/release-branch-versions/{branch}.yaml 존재 여부로 결정함
    • push pipeline 에서는 release target branch commit 반영 시 실행됨
    • Web(New Pipeline) pipeline 에서는 release target branch 를 선택하면 수동 release 실행 요청으로 처리됨
    • Build Runner 는 Protected Runner 로 구성함
    • Protected Variable 을 사용하는 구조이므로 release target branch 도 Protected Branch 로 등록해야 함
    • GitLab은 실제 운영 서버 deploy 를 수행하지 않음
    • 운영 서버 접근 권한을 가지지 않음
  • Runner 간 Tag 공유 금지

  • Run untagged jobs 사용 금지
  • 모든 Job은 명시적으로 Runner Tag를 지정해야 함

2. Runner 설치 (Runner가 설치될 서버에서 실행)

curl -fsSL -o /tmp/gitlab-runner-repo.sh https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh
cat /tmp/gitlab-runner-repo.sh
sudo bash /tmp/gitlab-runner-repo.sh

sudo dnf install -y gitlab-runner
sudo systemctl enable gitlab-runner
sudo systemctl start gitlab-runner
sudo systemctl status gitlab-runner

3. Docker 설치 (Merge Request Runner / Build Runner 서버에서만 실행)

sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker
sudo usermod -aG docker gitlab-runner
sudo systemctl restart docker
sudo systemctl restart gitlab-runner
sudo -u gitlab-runner docker ps # 에러 없이 명령이 실행됐다는 것 자체가 gitlab-runner 유저가 docker 그룹에 정상 추가됐다는 의미

확인:

sudo docker version
sudo docker run --rm hello-world

4. Token 관리 규칙

Runner, Tag, Token 는 다음 규칙:

구분 명명 규칙 예시
Runner [SERVICE_NAME]_[MergeRequestOrBuild]_runner example.com_mr_runner, example.com_build_runner
Tag [SERVICE_NAME]_[MergeRequestOrBuild]_runner_tag example.com_mr_runner_tag, example.com_build_runner_tag
Token [SERVICE_NAME]_[MergeRequestOrBuild]_RUNNER_TOKEN STREAUM_COM_MR_RUNNER_TOKEN, STREAUM_COM_BUILD_RUNNER_TOKEN

운영 기준:

  • Project 별로 SERVICE_NAME 을 prefix 로 고정
  • 역할 명확히 구분
  • 환경 변수명은 대문자 사용
  • 환경 변수명에서는 . 대신 _를 사용함

5. Runner 생성 (UI)

  • 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.

경로:

Project → Settings → CI/CD → Runners → Create project runner

Tags

  • Tags : [SERVICE_NAME]_[MergeRequestOrBuild]_runner_tag
  • Run untagged jobs : 비활설화

Configuration (optional)

  • Runner description : [SERVICE_NAME] [MergeRequestOrBuild] Runner
  • Paused: 비활설화
  • Protected:
    • Merge Request Runner: ❌ 비활성화
      • any work branch 및 Merge Request pipeline 실행을 위해 필요
      • Protected Branch 외부에서도 실행 가능해야 함
    • Build Runner: ⭕ 활성화
      • Protected Branch / Protected Tag 에서만 Runner 실행 허용
      • release target branch 의 build / package / release-state publish pipeline 용도
      • release target branch 는 .ops/ci/release-branch-versions/{branch}.yaml 존재 여부로 결정함
      • 예: pre-production, production, ko-dev-test
      • Protected Variable 을 사용하는 경우 해당 release target branch 도 Protected Branch 로 등록해야 함
      • release publish 전용 Runner 로 분리하여 실수 실행 범위를 제한하는 안전장치 역할 수행
  • Lock to current projects: 활설화

생성

  • Create runner 클릭
  • 생성 후 Authentication Token 무조건 복사 및 저장

6. Runner 등록 (서버)

  • 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.
  • GitLab UI에서 생성한 Runner 정보를 기준으로 제공하는 sudo gitlab-runner register 명령어를 gitlab-runner 가 설치된 서버에서 그대로 사용함
  • Runner 유형별 executor 및 image 정책을 구분하여 등록함
  • 실행 시 아래 기준에 따라 입력
  • Runner 이름은 중복되도 괜찮음

6.1 Merge Request Runner (Docker)

입력 기준:

  • GitLab instance URL: gitlab.example.com
  • runner name: example.com_mr_runner
  • executor: docker
  • default image:
    • 운영 서버 런타임 기준으로 결정
    • 예: 운영 서버 node -vv22.x 인 경우 node:22

운영 기준:

  • Merge Request Runner 는 any work branch / Merge Request pipeline 전용
  • 최소 검증(lint/test/MR route check) 용도로 사용
  • package 생성 및 release 처리 금지

※ tag, run untagged jobs, protected, lock to current projects 설정은 GitLab UI에서 Runner 생성 시 설정됨

6.2 Build Runner (Docker)

Docker Executor 사용 시 Build Runner 는 Job 실행 환경이 되는 기본 이미지를 지정해야 함. Build Runner의 기본 이미지는 단순 최신 버전이 아니라, 운영 서버와 런타임 및 시스템 라이브러리 호환성을 기준으로 선택함. 즉, Build 환경과 운영 서버의 런타임 및 시스템 라이브러리가 호환되어야 함 특히 Alpine(musl) 기반 이미지와 일반 Linux(glibc) 기반 운영 서버 간 차이는 사전 검토가 필요함. Runner 등록 시 입력하는 default image 는 기본값이며, Runner의 default image보다 .gitlab-ci.ymlimage: 설정으로 우선 결정할 수 있음.

이미지 선정 전 운영 서버 확인 (필수)

runner 등록 전 반드시 운영 서버에서 아래를 확인한 후 이미지를 결정함.

# 런타임 버전 확인
node -v        # Node.js 계열
php -v         # PHP / Laravel 계열
gcc --version  # C 계열
g++ --version  # C++ 계열 (gcc와 별도 패키지로 설치되는 경우 있음)

# OS 확인
cat /etc/os-release

확인 결과를 기준으로 이미지 버전을 결정함:

확인 항목 예시 결과 선택 이미지
node -v v22.x node:22
node -v v23.x node:23
php -v 8.2.x php:8.2

운영 기준:

  • major 버전 일치를 기본으로 함
  • 네이티브 모듈 또는 C++ 바인딩이 포함된 경우 minor 버전까지 일치시킴
  • 순수 JS/PHP 스택은 major 버전 일치로 충분함
  • 프로젝트별 운영 서버 버전이 다르면 .gitlab-ci.yml 에서 image: 를 각각 명시함

예:

# 프로젝트별 .gitlab-ci.yml 에서 이미지 오버라이드
# runner 등록 시 default image는 fallback 용도임

# example.com (Next.js, 운영 서버 node v22)
image: node:22

# backend.example.com (Express, 운영 서버 node v23)
image: node:23

기본 원칙:

  • 프로젝트 스택에 맞는 공식 이미지를 사용함
  • Docker Official Image 또는 공식 이미지를 우선 사용함
  • latest 태그 사용 금지 (재현성 문제)
  • 버전은 가능한 명시적으로 고정 (<major>.<minor> 이상 권장)
  • Docker Hub의 공식 이미지 목록에서 선택함
  • 프로젝트 런타임 버전과 일치하도록 설정

스택별 예시:

스택 예시 이미지 비고
Node.js / Express / Next.js / Nuxt.js node:<version> npm, yarn, pnpm
PHP / Laravel php:<version> composer 필요 시 별도 구성
C++ gcc:<version> 또는 ubuntu:<version> 빌드 도구 포함 여부 확인
멀티 스택 custom image 도구 조합 고정

공식 이미지 확인 경로:

  • Docker Official Images:
    https://hub.docker.com/search?q=&type=image&image_filter=official

  • Node.js 이미지:
    https://hub.docker.com/_/node

  • PHP 이미지:
    https://hub.docker.com/_/php

  • GCC 이미지:
    https://hub.docker.com/_/gcc

운영 기준:

  • 빌드 결과물이 운영 서버에서 그대로 실행되어야 하므로, Build 환경과 운영 환경의 런타임 및 시스템 라이브러리가 호환되어야 함
  • 가능하면 운영 서버와 동일한 major 버전의 런타임을 사용함
  • 네이티브 모듈 또는 바이너리 빌드가 포함되는 경우, OS 계열 및 libc(glibc / musl) 차이까지 검토함
  • 이미지 변경 시 CI / 로컬 / 운영 환경 호환성 함께 검증
  • 필요 시 custom image를 별도로 관리하여 빌드 시간 단축 및 안정성 확보

입력 기준:

  • GitLab instance URL: gitlab.example.com
    • GitLab이 설치된 서버의 기본 접근 URL 입력
    • Runner가 통신할 대상 GitLab 서버의 URL이며, 실제 운영 URL 기준으로 입력
    • AWS 등 Cloud 인프라 환경에서는 Runner와 GitLab 간 통신을 Private IP 또는 Private DNS로 구성하여 외부 트래픽 비용 발생을 방지함
  • runner name: example.com_build_runner
  • executor: docker
  • default image:
    • 운영 서버 런타임 기준으로 결정
    • 예: 운영 서버 node -vv22.x 인 경우 node:22

※ tag, run untagged jobs, protected, lock to current projects 설정은 GitLab UI에서 Runner 생성 시 설정됨


7. Runner 상태 확인

  • 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.

7.1 서버 확인

sudo systemctl status gitlab-runner
sudo gitlab-runner verify

운영 기준:

  • gitlab-runner 서비스가 active (running) 상태
  • verify 실행 시 등록된 Runner가 조회됨

7.2 GitLab UI 확인

경로:

Project → Settings → CI/CD → Runners → Assigned project runners

확인 항목:

  • example.com_mr_runner 표시 확인
  • example.com_build_runner 표시 확인
  • 상태가 online 인지 확인

8. 실행 정책

  • Merge Request 검증 Job → example.com_mr_runner_tag Tag 사용
  • release 감지 / build / package / release-state publish Job → example.com_build_runner_tag Tag 사용
  • 모든 Job은 Tag 필수
  • Run untagged jobs 비활성 유지

Pipeline source 기준:

Pipeline source Runner 동작
merge_request_event Merge Request Runner branch 승격 경로 검증만 수행
push Build Runner release target branch 이면 build / package / release-state publish 수행
Web(New Pipeline) Build Runner release target branch 이면 수동 release publish 수행

release target 기준:

.ops/ci/release-branch-versions/{CI_COMMIT_BRANCH}.yaml

운영 기준:

  • develop, feature/* 는 release job 실행 대상에서 제외함
  • release target branch 는 Protected Branch 로 등록함
  • Build Runner 는 Protected Runner 로 구성함
  • GitLab은 release package 와 release state publish 까지만 수행함
  • 운영 서버 deploy 는 수행하지 않음

예:

mr_sanity_check:
  tags:
    - example.com_mr_runner_tag

detect_release_targets:
  tags:
    - example.com_build_runner_tag

build_target:
  tags:
    - example.com_build_runner_tag

package_target:
  tags:
    - example.com_build_runner_tag

set_release_state:
  tags:
    - example.com_build_runner_tag

9. Runner 서버 운영 관리

9.1 Docker Runner 디스크 정리

Merge Request Runner 와 Build Runner 는 Docker Executor 를 사용하므로 사용하지 않는 이미지, 컨테이너, 볼륨이 누적될 수 있음.

1. 수동 정리 (테스트 실행)

sudo docker system prune -af --volumes

설명:

  • -a: 사용하지 않는 모든 이미지 제거
  • -f: 확인 없이 강제 실행
  • --volumes: 사용하지 않는 볼륨까지 제거

주의:

  • 이 명령어는 실제로 리소스를 삭제함
  • 반드시 Runner 서버에서 실행해야 함
  • 운영 서버에서는 실행 금지

2. 현재 디스크 사용량 확인

sudo docker system df

출력 예:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

운영 기준:

  • RECLAIMABLE 수치가 높을 경우 정리 필요
  • 디스크 사용량 증가 추세 지속 시 자동화 필요

3. 자동 정리 (crontab 등록)

sudo tee /etc/cron.d/docker-prune >/dev/null <<'EOF'
# GitLab Runner Docker cleanup
# 매일 03:00 에 사용하지 않는 Docker 리소스 정리
0 3 * * * root /usr/bin/docker system prune -af --volumes
EOF

확인:

cat /etc/cron.d/docker-prune

4. 운영 기준

  • Runner 서버 디스크 사용량을 주기적으로 확인함
  • 기본적으로 --volumes 포함하여 항시 깨끗한 상태 유지
  • Build cache가 필요한 경우에만 --volumes 사용 여부 재검토
  • 디스크 부족 장애 발생 시:
    • prune 주기 단축
    • Runner 서버 디스크 증설
    • 캐시 전략 분리 검토

9.2 config.toml 기본 확인

Runner 등록 후 /etc/gitlab-runner/config.toml을 확인함.

sudo cat /etc/gitlab-runner/config.toml

운영 기준:

  • Runner별 name, executor, url 확인
  • Docker Runner 는 image 확인 및 pull_policy 설정 검토
  • 서버 사양에 맞게 concurrentlimit 설정 검토

기본 설정 예시

[[runners]]
  name = "example.com_mr_runner"
  limit = 1
  executor = "docker"

  [runners.docker]
    image = "node:22"
    pull_policy = "if-not-present" # 선택 설정 (성능 최적화)
    volumes = ["/cache"]

pull_policy

  • always (기본값): 매 job마다 이미지 pull (안정성 높음, 느림)
  • if-not-present: 로컬에 없을 때만 pull (빠름, 운영 안정화 이후 권장)
  • never: 로컬 이미지만 사용 (특수한 경우만 사용)

운영 기준:

  • 초기 구축 단계에서는 기본값(always) 사용
  • CI 안정화 이후 if-not-present 적용 검토

적용 후 반영

sudo systemctl restart gitlab-runner
sudo gitlab-runner verify

주의

  • 단순 파일 빌드(npm build 등): 보안을 위해 /var/run/docker.sock 바인딩을 금지함.
  • Docker 이미지 빌드가 필요한 경우에만 Build Runner에 한해 아래 설정을 적용함:
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
  • docker.sock 바인딩은 Runner 서버의 root 권한 탈취 가능성이 있으므로 필요한 경우에만 제한적으로 사용함
  • Job 내부에서 docker build, docker push 등이 필요한 경우에만 별도 검토 후 적용함.