Self-Hosted Runner를 사용하는 이유
GitHub-hosted Runner는 편리하지만, 빌드 시간 제한(6시간), 제한된 하드웨어, 프라이빗 네트워크 접근 불가 등의 한계가 있습니다. Self-Hosted Runner는 자체 인프라에서 실행되어 GPU 빌드, 사내 네트워크 접근, 커스텀 환경이 필요할 때 사용합니다.
기본 설치
# 러너 다운로드 및 설정
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.311.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz
tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz
# 러너 등록 (GitHub Settings > Actions > Runners에서 토큰 발급)
./config.sh --url https://github.com/ORG/REPO \
--token AXXXXXXXXXXXXXXX \
--name "build-server-01" \
--labels "linux,x64,gpu" \
--work "_work" \
--runnergroup "default"
# 서비스로 설치 (자동 시작)
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
Docker 기반 격리 실행
# Dockerfile for Runner
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
curl jq git docker.io nodejs npm \
&& rm -rf /var/lib/apt/lists/*
# 비루트 사용자 생성
RUN useradd -m runner && usermod -aG docker runner
USER runner
WORKDIR /home/runner
# 러너 설치
RUN curl -o actions-runner.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz \
&& tar xzf actions-runner.tar.gz \
&& rm actions-runner.tar.gz
COPY entrypoint.sh .
ENTRYPOINT ["./entrypoint.sh"]
# entrypoint.sh
#!/bin/bash
./config.sh --url "$REPO_URL" --token "$RUNNER_TOKEN" \
--labels "$RUNNER_LABELS" --ephemeral --disableupdate
./run.sh
Docker Compose로 멀티 러너
# docker-compose.yml
services:
runner-1:
build: .
environment:
REPO_URL: https://github.com/org/repo
RUNNER_TOKEN: ${RUNNER_TOKEN}
RUNNER_LABELS: "linux,docker"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
runner-2:
build: .
environment:
REPO_URL: https://github.com/org/repo
RUNNER_TOKEN: ${RUNNER_TOKEN}
RUNNER_LABELS: "linux,docker"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
워크플로에서 사용
# .github/workflows/build.yml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: [self-hosted, linux, x64]
steps:
- uses: actions/checkout@v4
- name: Build Docker Image
run: |
docker build -t myapp:${{ github.sha }} .
docker push registry.internal/myapp:${{ github.sha }}
- name: Deploy to Internal Server
run: |
ssh deploy@internal-server "docker pull registry.internal/myapp:${{ github.sha }}"
ssh deploy@internal-server "docker service update --image registry.internal/myapp:${{ github.sha }} myapp"
보안 강화 체크리스트
| 항목 | 위험 | 대응 |
|---|---|---|
| 퍼블릭 레포에서 사용 | 악성 PR이 러너에서 코드 실행 | 퍼블릭 레포에서는 Self-Hosted 금지 |
| 시크릿 노출 | 환경 변수로 시크릿 유출 | --ephemeral 모드 사용 |
| Docker 소켓 마운트 | 컨테이너 탈출 -> 호스트 접근 | rootless Docker 또는 별도 Docker-in-Docker |
| 빌드 아티팩트 잔존 | 이전 빌드 데이터 유출 | --ephemeral 또는 작업 후 정리 |
| 네트워크 접근 | 내부 서비스 무단 접근 | 러너 전용 네트워크 격리 |
# 보안 설정 예시
# 1. Ephemeral 러너: 작업 1개 실행 후 자동 제거
./config.sh --ephemeral ...
# 2. 러너 그룹으로 접근 제어 (Organization 레벨)
# Settings > Actions > Runner groups
# - production-runners: 특정 레포만 접근 허용
# 3. 필수 워크플로 승인
# Settings > Actions > General
# - "Require approval for all outside collaborators"
# 4. 러너 토큰 자동 갱신 스크립트
#!/bin/bash
TOKEN=$(curl -s -X POST \
-H "Authorization: token $PAT" \
"https://api.github.com/orgs/ORG/actions/runners/registration-token" \
| jq -r .token)
./config.sh --url https://github.com/ORG --token "$TOKEN" --replace --ephemeral
- 퍼블릭 레포에서는 절대 Self-Hosted Runner를 사용하지 마세요 — 포크 PR로 임의 코드 실행이 가능합니다
- Ephemeral 모드를 강력히 권장합니다: 각 작업이 깨끗한 환경에서 실행되고 완료 후 폐기됩니다
- 대규모 환경에서는 actions-runner-controller(ARC)로 Kubernetes에서 자동 스케일링을 구성하세요
댓글 0