CI/CD 스터디 02: Runner와 Executor 구조

CI/CD runner, hosted/self-hosted runner, shell/Docker/Kubernetes executor의 차이와 운영 점검 명령을 정리합니다.

Runner는 파이프라인 명령을 실제로 실행하는 작업자입니다. 같은 YAML이라도 runner가 shell인지, Docker인지, Kubernetes executor인지에 따라 보안 경계와 장애 양상이 달라집니다.

컴포넌트 역할

CI/CD 서버는 작업을 예약하고 상태를 기록하지만, 실제 빌드는 runner에서 일어납니다. runner는 소스 checkout, dependency 설치, 테스트, 이미지 빌드, artifact 업로드, 배포 명령 실행을 담당합니다.

  • hosted runner: 플랫폼이 제공하는 일회성 runner입니다. 관리 부담이 작지만 내부망 접근과 커스텀 도구 설치에 제한이 있습니다.
  • self-hosted runner: 직접 운영하는 runner입니다. 내부망, 사내 registry, 특수 장비 접근이 가능하지만 격리와 패치 책임이 생깁니다.
  • shell executor: 호스트에서 직접 명령을 실행합니다. 빠르지만 workspace 오염과 권한 경계가 약합니다.
  • Docker executor: job마다 컨테이너를 사용합니다. 재현성이 좋고 의존성 충돌이 적습니다.
  • Kubernetes executor: job을 Pod로 실행합니다. 대규모 병렬 처리와 리소스 격리가 좋지만 클러스터 운영 지식이 필요합니다.

Runner가 병목이 되는 지점

파이프라인이 느리다고 YAML만 고치는 경우가 많지만, 실제 병목은 runner의 CPU, 디스크 I/O, 네트워크, registry latency, dependency cache 위치인 경우가 많습니다. 특히 Docker image build, npm/maven dependency download, 대용량 test artifact 업로드는 runner 성능의 영향을 크게 받습니다.

# Linux self-hosted runner 기본 상태 점검
hostname
uptime
nproc
free -h
df -h
df -ih
ip route
ss -tan state established | wc -l

# 컨테이너 빌드 runner라면 Docker/BuildKit 상태 확인
docker version
docker buildx ls
docker system df

GitHub Actions runner 예시

GitHub Actions에서 job은 runner 위에서 실행되고, step은 같은 runner workspace를 공유합니다. 따라서 한 step에서 만든 파일을 뒤 step에서 사용할 수 있지만, job이 달라지면 artifact나 cache로 넘겨야 합니다.

name: runner-study

on:
  pull_request:
  push:
    branches: [ main ]

jobs:
  inspect-runner:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Inspect runner
        run: |
          uname -a
          nproc
          df -h
          printenv | sort | sed -n '1,80p'

GitLab Runner 예시

GitLab CI/CD에서는 job마다 image를 지정할 수 있고, runner executor가 해당 image를 어떻게 실행할지 결정합니다. Docker executor를 쓰면 빌드 환경을 YAML에서 명시하기 쉽습니다.

stages:
  - inspect

inspect-runner:
  stage: inspect
  image: alpine:3.20
  script:
    - uname -a
    - nproc || true
    - df -h
    - env | sort | sed -n '1,80p'
  tags:
    - docker

Self-hosted runner 운영 기준

  1. 공용 runner와 운영 배포 runner를 분리합니다.
  2. fork PR, 외부 contributor, 운영 배포가 같은 runner를 공유하지 않게 합니다.
  3. runner workspace cleanup을 주기적으로 수행합니다.
  4. Docker socket을 노출하는 runner는 사실상 host 권한과 같다고 보고 격리합니다.
  5. runner 장애를 파이프라인 실패와 구분하기 위해 runner heartbeat와 queue 대기 시간을 모니터링합니다.
# GitLab Runner 운영자가 확인할 명령 예시
sudo gitlab-runner status
sudo gitlab-runner verify
sudo journalctl -u gitlab-runner -n 120 --no-pager

# GitHub self-hosted runner service 상태 예시
sudo ./svc.sh status
sudo journalctl -u actions.runner.* -n 120 --no-pager

참고 문서

BGM EVER