학습 목표
GitHub Actions·GitLab CI의 workflow/pipeline, trigger, job, step 구조를 설명할 수 있다.
cache·container job·service로 빌드 시간을 줄이는 방법을 설명할 수 있다.
Secret·environment로 staging/production 배포 gate를 설정할 수 있다.
이미지 push → kubectl/helm deploy 흐름을 workflow YAML로 작성할 수 있다.
문제 상황
- Jenkinsfile 하나에 모든 스테이지가 섞여 PR 테스트만 돌리기 어렵다
- 매 빌드마다
go mod download·npm ci가 10분
- CI runner에 Docker·kubectl을 수동 설치해 버전이 제각각
- container job·action/image 표준화
- GitHub repo인데 GitLab CI 문법을 그대로 붙여 넣었다
- staging deploy는 자동, prod는 승인인데 workflow에 gate 없음
- environment·manual job·rules
kubectl apply에 kubeconfig를 YAML에 평문으로
앞서 CI/CD 개념·아티팩트·환경 분리를 봤다. 이번 편은 대표 CI 도구로 파이프라인을 코드로 만든다.
1. 공통 모델
| 개념 |
GitHub Actions |
GitLab CI |
| 정의 파일 |
.github/workflows/*.yaml |
.gitlab-ci.yml |
| 실행 단위 |
workflow run |
pipeline |
| 병렬/순서 |
job (needs) |
stage + job |
| 최소 단위 |
step (shell·action) |
script in job |
| 트리거 |
on: push, PR, schedule |
rules·branch·MR |
| 실행 환경 |
runner (hosted/self) |
runner (shared/shell) |
trigger → workflow/pipeline → job(s) → step/script → artifact · deploy
- 선언적 — Git에 커밋하면 버전 관리·리뷰 가능
- job — 독립 VM/container, 병렬 가능
- needs / stage — DAG 순서 (test → build → deploy)
- 앞서 build test scan deploy 단계가 job으로 매핑된다
2. GitHub Actions
trigger
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch: # manual run
| event |
용도 |
| pull_request |
PR에서 test·scan only |
| push main |
build·push·deploy |
| schedule |
cron 백업·drift check |
| workflow_dispatch |
수동 prod deploy |
job · step · action
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: go test ./...
| |
설명 |
| runs-on |
hosted runner OS (ubuntu-latest) |
| uses |
재사용 action (checkout, cache, login) |
| run |
shell 명령 |
| needs |
job 의존 — deploy는 build 성공 후 |
| if |
조건 — main push일 때만 deploy |
- Composite action — 팀 공통 step 묶기
- Reusable workflow — repo·org 간 workflow 공유
cache · artifact
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
| |
cache |
artifact |
| 목적 |
빌드 가속 (deps) |
job 간 파일 전달 |
| 수명 |
key hit/miss |
workflow run |
| 예 |
go mod, Docker layer |
test report, binary |
- cache miss — cold build, 점진적 warm
- immutable image — registry push가 최종 아티팩트 (11편)
container job
jobs:
test:
runs-on: ubuntu-latest
container:
image: golang:1.22
steps:
- uses: actions/checkout@v4
- run: go test ./...
- runner 위 컨테이너에서 step 실행 — 도구 버전 고정
- service — sidecar DB (integration test)
Secret · environment
deploy-staging:
environment: staging
steps:
- env:
KUBECONFIG_DATA: ${{ secrets.KUBECONFIG_STAGING }}
| |
|
| secrets |
repo/org 암호 — log mask |
| environment |
staging/prod 승인자·protection rule |
| vars |
non-secret 설정 |
- prod environment — required reviewers (Delivery gate)
3. GitLab CI
§1 개념 표·비교 다이어그램과 같은 stage + job 모델을 GitLab YAML로 본다.
pipeline · stage
stages:
- test
- build
- deploy
| |
GitLab |
Actions 대응 |
| stage |
순서 열 |
job needs 그룹 |
| job |
stage 안 병렬 |
job |
| rules |
when 실행 |
if |
| needs |
DAG (stage 무시) |
needs |
deploy_staging:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
needs: [build]
- Merge Request pipeline — MR에서 test only
- protected branch — main에만 deploy job
cache · image
cache:
key: go-$CI_COMMIT_REF_SLUG
paths:
- .go/pkg/mod/
build:
image: docker:24
services:
- docker:24-dind
| |
|
| image |
job 컨테이너 (Actions container:) |
| services |
DinD·DB sidecar |
| cache |
key·paths — branch별 |
- Docker-in-Docker — image build/push job
- Kaniko — privileged 없이 build (대안)
variables · environment
variables:
IMAGE: registry.example.com/my/api
deploy_staging:
environment:
name: staging
url: https://staging.example.com
- CI/CD variables — group/project scope
- masked·protected — main·tag만 노출
- environment — deploy history·rollback 링크
4. K8s 배포 연동
CI: build image → push registry (SHA tag)
CD job: kubectl set image / helm upgrade → Deployment rollout
| 방식 |
설명 |
| kubectl set image |
Deployment image만 갱신 |
| kubectl apply |
manifest dir·kustomize overlay |
| helm upgrade |
chart + values-staging.yaml |
| GitOps |
manifest PR → Argo sync (14편) |
# Actions deploy step (요지)
kubectl set image deployment/api \
app=$REGISTRY/$IMAGE:${{ github.sha }} -n staging
kubectl rollout status deployment/api -n staging
- kubeconfig — Secret, base64 또는 OIDC (cloud IAM)
- same digest — staging·prod 동일
$CI_COMMIT_SHA / github.sha
- ConfigMap — env별 overlay, image는 공통 (11편)
- rollout status — readiness 실패 시 job fail
5. Actions vs GitLab — 선택
| |
GitHub Actions |
GitLab CI |
| 적합 |
GitHub 중심 repo |
GitLab self-managed·올인원 |
| 문법 |
job-centric |
stage + job |
| 마켓 |
Actions marketplace |
CI template·include |
| runner |
GitHub-hosted·self |
shared·self·K8s executor |
| K8s deploy |
동일 — kubectl/helm step |
동일 |
- 원리는 동일 — trigger, DAG, cache, secret, container
- 8_IaC 시리즈 — Terraform·GitOps 심화는 별도 트랙
- 팀 표준 하나 정하고 reusable workflow/template로 통일
6. 실무 체크리스트
| 항목 |
권장 |
| PR |
test + scan job only, deploy 제외 |
| main |
build → push SHA tag → staging auto |
| prod |
environment approval 또는 manual job |
| Secret |
kubeconfig·registry token masked |
| cache |
lockfile hash key |
| pin |
action @v4·digest pin (supply chain) |
| 안티패턴 |
|
latest tag push |
prod 추적 불가 |
| long-lived kubeconfig in repo |
유출 |
| 모든 step one job |
캐시·병렬 불가 |
| ` |
|
7. 정리
- workflow/pipeline — trigger → job → step, DAG (
needs/stage)
- cache·container — 속도·재현성
- Secret·environment — deploy gate
- registry + kubectl/helm — K8s CD 최소 패턴
- 다음 — 배포 전략 (rolling, blue-green, canary)
다음에 다룰 것
- 배포 전략
- rolling, blue-green, canary, 롤백·blast radius
해당 내용은 GitHub Actions Documentation (docs.github.com/actions) 및 GitLab CI/CD docs (docs.gitlab.com/ee/ci/) 를 참고했습니다.