GitHub Actions에서의 이주

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

만약 GitHub Actions에서 GitLab CI/CD로 이주한다면, GitHub Actions의 워크플로우를 복제하고 향상시킬 수 있는 CI/CD 파이프라인을 생성할 수 있습니다.

주요 유사성과 차이점

GitHub Actions과 GitLab CI/CD는 모두 코드를 빌드, 테스트, 배포하는 파이프라인을 자동화하는 데 사용됩니다. 두 가지는 다음과 같은 유사성을 공유합니다.

  • CI/CD 기능은 프로젝트 저장소에 저장된 코드에 직접 액세스할 수 있습니다.
  • 프로젝트 저장소에 YAML로 작성된 파이프라인 구성이 저장됩니다.
  • 파이프라인은 구성 가능하며 여러 단계에서 실행할 수 있습니다.
  • 작업은 각기 다른 컨테이너 이미지를 사용할 수 있습니다.

또한, 두 가지 사이에 중요한 차이점이 있습니다.

  • GitHub은 3rd-party 액션을 다운로드할 수 있는 마켓플레이스가 있으며, 추가 지원이나 라이선스가 필요할 수 있습니다.
  • Self-managed GitLab 인스턴스는 수평 및 수직 스케일링을 모두 지원하는 반면, GitHub Enterprise Server는 수직 스케일링만 지원합니다.
  • GitLab은 모든 기능을 사내에서 유지 및 지원하며, 일부 3rd-party 통합은 템플릿을 통해 접근할 수 있습니다.
  • GitLab은 내장된 컨테이너 레지스트리를 제공합니다.
  • GitLab은 네이티브 Kubernetes 배포 지원을 제공합니다.
  • GitLab은 세밀한 보안 정책을 제공합니다.

기능 및 개념 비교

GitHub의 기능 및 개념 중 많은 부분은 같은 기능을 제공하는 GitLab의 동등한 항목이 있습니다.

구성 파일

GitHub Actions는 workflow YAML 파일로 구성될 수 있습니다. GitLab CI/CD는 기본적으로 .gitlab-ci.yml YAML 파일을 사용합니다.

예를 들어, GitHub Actions의 workflow 파일에서:

on: [push]
jobs:
  hello:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Hello World"

해당하는 GitLab CI/CD의 .gitlab-ci.yml 파일은:

stages:
  - hello

hello:
  stage: hello
  script:
    - echo "Hello World"

… (중략)



##### 병렬

GitHub와 GitLab 모두 기본적으로 작업을 병렬로 실행합니다.

예를 들어, GitHub Actions의 `workflow` 파일에서:

```yaml
on: [push]
jobs:
  python-version:
    runs-on: ubuntu-latest
    container: python:latest
    steps:
      - run: python --version
  java-version:
    if: contains( github.ref, 'staging')
    runs-on: ubuntu-latest
    container: openjdk:latest
    steps:
      - run: java -version

이 예에서는 서로 다른 컨테이너 이미지를 사용하여 Python 작업과 Java 작업을 병렬로 실행합니다. Java 작업은 ‘staging’ 브랜치가 변경될 때만 실행됩니다.

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같습니다:

python-version:
  image: python:latest
  script:
    - python --version

java-version:
  image: openjdk:latest
  rules:
    - if: $CI_COMMIT_BRANCH == 'staging'
  script:
    - java -version

이 경우, 작업을 병렬로 실행하려면 추가 구성이 필요하지 않습니다. 기본적으로 각 작업은 별도의 실행기에서 병렬로 실행되며, 충분한 실행기가 있는 경우에만 실행됩니다. Java 작업은 ‘staging’ 브랜치가 변경될 때만 실행되도록 설정되어 있습니다.

행렬

GitLab 및 GitHub 모두 하나의 파이프라인에서 작업을 여러 번 병렬로 실행하고 해당 작업의 각 인스턴스에 대해 다른 변수 값을 사용하기 위해 행렬을 사용할 수 있습니다.

예를 들어, GitHub Actions의 workflow 파일에서:

on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building $PLATFORM for $ARCH"
    strategy:
      matrix:
        platform: [linux, mac, windows]
        arch: [x64, x86]
  test:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Testing $PLATFORM for $ARCH"
    strategy:
      matrix:
        platform: [linux, mac, windows]
        arch: [x64, x86]
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying $PLATFORM for $ARCH"
    strategy:
      matrix:
        platform: [linux, mac, windows]
        arch: [x64, x86]

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같습니다:

stages:
  - build
  - test
  - deploy

.parallel-hidden-job:
  parallel:
    matrix:
      - PLATFORM: [linux, mac, windows]
        ARCH: [x64, x86]

build-job:
  extends: .parallel-hidden-job
  stage: build
  script:
    - echo "Building $PLATFORM for $ARCH"

test-job:
  extends: .parallel-hidden-job
  stage: test
  script:
    - echo "Testing $PLATFORM for $ARCH"

deploy-job:
  extends: .parallel-hidden-job
  stage: deploy
  script:
    - echo "Deploying $PLATFORM for $ARCH"

트리거

GitHub Actions에서는 워크플로우에 대해 트리거를 추가해야 합니다. GitLab은 Git과 긴밀하게 통합되어 있으므로 트리거의 SCM 폴링 옵션은 필요하지 않지만, 필요한 경우 작업별로 구성할 수 있습니다.

GitHub Actions 구성 예시:

on:
  push:
    branches:
      - main

동등한 GitLab CI/CD 구성은 다음과 같습니다:

rules:
  - if: '$CI_COMMIT_BRANCH == main'

파이프라인은 또한 크론 구문을 사용하여 예약될 수 있습니다.

컨테이너 이미지

GitLab을 사용하면 image 키워드를 사용하여 별도로 격리된 Docker 컨테이너에서 CI/CD 작업을 실행할 수 있습니다.

예를 들어, GitHub Actions의 workflow 파일에서:

jobs:
  update:
    runs-on: ubuntu-latest
    container: alpine:latest
    steps:
      - run: apk update

이 예에서, apk update 명령어가 alpine:latest 컨테이너에서 실행됩니다.

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같습니다:

update-job:
  image: alpine:latest
  script:
    - apk update

GitLab은 모든 프로젝트에 대해 컨테이너 레지스트리를 제공하여 컨테이너 이미지를 호스팅합니다. 컨테이너 이미지는 GitLab CI/CD 파이프라인에서 직접 빌드하고 저장할 수 있습니다.

예를 들어:

stages:
  - build

build-image:
  stage: build
  variables:
    IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE .
    - docker push $IMAGE

Variables

GitLab에서는 런타임 시 CI/CD 변수를 정의하는 데 variables 키워드를 사용합니다. 파이프라인에서 구성 데이터를 재사용해야 할 때 변수를 사용합니다. 변수는 전역적으로 또는 작업별로 정의할 수 있습니다.

예를 들어, GitHub Actions workflow 파일에서:

env:
  NAME: "fern"

jobs:
  english:
    runs-on: ubuntu-latest
    env:
      Greeting: "hello"
    steps:
      - run: echo "$GREETING $NAME"
  spanish:
    runs-on: ubuntu-latest
    env:
      Greeting: "hola"
    steps:
      - run: echo "$GREETING $NAME"

이 예에서 변수는 작업별로 다른 출력을 제공합니다.

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같을 것입니다:

default:
  image: ubuntu-latest

variables:
  NAME: "fern"

english:
  variables:
    GREETING: "hello"
  script:
    - echo "$GREETING $NAME"

spanish:
  variables:
    GREETING: "hola"
  script:
    - echo "$GREETING $NAME"

변수는 GitLab UI를 통해 설정할 수도 있으며, 여기서 변수를 보호하거나 마스킹할 수 있습니다. 마스크된 변수는 작업 로그에 숨겨지며, 보호된 변수는 보호된 브랜치나 태그에 대한 파이프라인에서만 액세스할 수 있습니다.

예를 들어, GitHub Actions workflow 파일에서:

jobs:
  login:
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
    steps:
      - run: my-login-script.sh "$AWS_ACCESS_KEY"

AWS_ACCESS_KEY 변수가 GitLab 프로젝트 설정에 정의된 경우, 동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같을 것입니다:

login:
  script:
    - my-login-script.sh $AWS_ACCESS_KEY

게다가, GitHub ActionsGitLab CI/CD은 파이프라인 및 저장소에 대한 관련 데이터를 포함하는 내장 변수를 제공합니다.

Conditionals

새 파이프라인이 시작되면 GitLab은 파이프라인 구성을 확인하여 해당 파이프라인에서 실행해야 하는 작업을 결정합니다. rules 키워드를 사용하여 변수의 상태나 파이프라인 유형과 같은 조건에 따라 작업을 구성할 수 있습니다.

예를 들어, GitHub Actions workflow 파일에서:

jobs:
  deploy_staging:
    if: contains( github.ref, 'staging')
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploy to staging server"

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같을 것입니다:

deploy_staging:
  stage: deploy
  script:
    - echo "Deploy to staging server"
  rules:
    - if: '$CI_COMMIT_BRANCH == staging'

Runners

Runners는 작업을 실행하는 서비스입니다. GitLab.com을 사용하고 있다면, 자체 관리형 Runner를 프로비저닝하지 않고도 인스턴스 Runner 플리트를 사용하여 작업을 실행할 수 있습니다.

Runner에 대한 중요한 세부 정보는 다음과 같습니다:

  • Runner는 인스턴스 전체, 그룹 또는 단일 프로젝트에 대해 공유되도록 구성할 수 있습니다.
  • 더 세밀한 제어를 위해 tags 키워드를 사용할 수 있으며, 특정 작업과 Runner를 연결할 수 있습니다. 예를 들어 전용, 더 강력한 또는 특정 하드웨어가 필요한 작업에 대해 태그를 사용할 수 있습니다.
  • GitLab은 Runner에 대한 자동 스케일링을 제공합니다. 필요할 때만 Runner를 프로비저닝하고 필요 없을 때는 축소합니다.

예를 들어, GitHub Actions workflow 파일에서:

linux_job:
  runs-on: ubuntu-latest
  steps:
    - run: echo "Hello, $USER"

windows_job:
  runs-on: windows-latest
  steps:
    - run: echo "Hello, %USERNAME%"

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같을 것입니다:

linux_job:
  stage: build
  tags:
    - linux-runners
  script:
    - echo "Hello, $USER"

windows_job:
  stage: build
  tags:
    - windows-runners
  script:
    - echo "Hello, %USERNAME%"

Artifacts

GitLab에서는 모든 작업에서 artifacts 키워드를 사용하여 작업이 완료될 때 저장할 파일 세트를 정의할 수 있습니다. Artifacts는 이후 작업에서 사용할 수 있는 파일입니다.

예를 들어, GitHub Actions workflow 파일에서:

on: [push]
jobs:
  generate_cat:
    steps:
      - run: touch cat.txt
      - run: echo "meow" > cat.txt
      - uses: actions/upload-artifact@v3
        with:
          name: cat
          path: cat.txt
          retention-days: 7
  use_cat:
    needs: [generate_cat]
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: cat
      - run: cat cat.txt

동등한 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같을 것입니다:

stage:
  - generate
  - use

generate_cat:
  stage: generate
  script:
    - touch cat.txt
    - echo "meow" > cat.txt
  artifacts:
    paths:
      - cat.txt
    expire_in: 1 week

use_cat:
  stage: use
  script:
    - cat cat.txt

캐싱

잡이 하나 이상의 파일을 다운로드하고 나중에 빠르게 액세스하기 위해 저장할 때 캐시가 만들어집니다. 동일한 캐시를 사용하는 후속 작업은 파일을 다시 다운로드할 필요가 없으므로 더 빨리 실행됩니다. 캐시는 러너에 저장되어 있으며 분산 캐시가 활성화된 경우 S3에 업로드됩니다.

예를 들어, GitHub Actions workflow 파일에서:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - run: echo "This job uses a cache."
    - uses: actions/cache@v3
      with:
        path: binaries/
        key: binaries-cache-$CI_COMMIT_REF_SLUG

해당하는 GitLab CI/CD .gitlab-ci.yml 파일은 다음과 같습니다.

cache-job:
  script:
    - echo "This job uses a cache."
  cache:
    key: binaries-cache-$CI_COMMIT_REF_SLUG
  paths:
    - binaries/

템플릿

GitHub에서 동일한 복잡한 작업 집합을 자주 반복해야 할 때 이를 재정의하지 않고 재사용할 수 있도록 저장해 놓은 것을 액션으로 정의합니다. GitLab에서 이와 해당하는 것은 include 키워드로, GitLab에 내장된 템플릿 파일을 포함하여 다른 파일에서 CI/CD 파이프라인을 추가할 수 있습니다.

GitHub Actions 설정 예시:

- uses: hashicorp/setup-terraform@v2.0.3

해당하는 GitLab CI/CD 설정은 다음과 같습니다.

include:
  - template: Terraform.gitlab-ci.yml

이러한 예에서 setup-terraform GitHub 액션과 Terraform.gitlab-ci.yml GitLab 템플릿은 정확한 일치가 아닙니다. 이 두 예시는 복잡한 구성이 재사용될 수 있는 방법을 보여주기 위한 것입니다.

보안 스캔 기능

GitLab은 애플리케이션 보안의 모든 부분에서 취약점을 감지하기 위한 다양한 보안 스캐너를 기본으로 제공합니다. 이러한 기능을 GitLab CI/CD 파이프라인에 추가하기 위해 템플릿을 사용할 수 있습니다.

예를 들어 SAST 스캐닝을 파이프라인에 추가하려면 다음을 .gitlab-ci.yml에 추가합니다.

include:
  - template: Jobs/SAST.gitlab-ci.yml

사용 가능한 CI/CD 변수를 활용하여 보안 스캐너의 동작을 사용자화할 수 있습니다.

비밀 관리

“비밀” 또는 민감한 정보는 CI/CD 워크플로우에서 필요한 민감한 정보나 자격 증명입니다. 이러한 비밀은 보호된 리소스를 잠금 해제하거나 도구, 응용 프로그램, 컨테이너 및 클라우드 네이티브 환경에서 민감한 정보를 사용하는 데 사용될 수 있습니다.

GitLab에서 비밀 관리를 위해 프로젝트 외부 서비스의 지원되는 통합 중 하나를 사용할 수 있습니다. 이러한 서비스는 GitLab 프로젝트 외부에 비밀을 안전하게 저장합니다. 그러나 해당 서비스의 구독이 있어야 합니다.

또한 GitLab은 OIDC(OpenID Connect)를 지원하여 OIDC을 지원하는 제3자 서비스에 대한 OIDC 인증도 지원합니다.

또한 CI/CD 변수에 자격 증명을 저장함으로써 작업에서 자격 증명을 사용할 수 있습니다. 그러나 평문으로 저장된 비밀은 우연한 노출을 유발할 수 있습니다. 민감한 정보는 항상 마스킹보호된 변수에 저장해야 합니다.

또한 공개 저장소인 경우 .gitlab-ci.yml 파일에 비밀을 저장하면 안 되며 이와 같은 민감한 정보는 프로젝트, 그룹 또는 인스턴스 설정에서만 해야 합니다.

CI/CD 변수의 안전성을 높이기 위한 보안 지침을 확인하세요.

마이그레이션 계획 수립 및 수행

유관기관들의 신속한 마이그레이션을 관찰한 후 추천된 단계 목록을 만들었습니다.

마이그레이션 계획 작성

마이그레이션을 시작하기 전에 마이그레이션을 위한 마이그레이션 계획을 작성해야 합니다.

사전 요구 사항

마이그레이션 작업을 시작하기 전에 먼저 다음을 해야 합니다:

  1. GitLab에 익숙해집니다.
  2. GitLab을 설정하고 구성하세요.
  3. GitLab 인스턴스를 테스트하세요.
    • 러너가 사용 가능한지 확인하고, 공유된 GitLab.com 러너를 사용하거나 새 러너를 설치하세요.

이주 단계

  1. GitHub에서 GitLab로 프로젝트를 이주합니다:
  2. 각 프로젝트에 .gitlab-ci.yml을 생성합니다.
  3. GitHub Actions 작업을 GitLab CI/CD 작업으로 이주하고, 병합 요청에서 결과를 직접 표시하도록 구성합니다.
  4. 클라우드 배포 템플릿, 환경, 및 GitLab Kubernetes용 에이전트를 사용하여 배포 작업을 이주합니다.
  5. 다양한 프로젝트 간에 재사용될 수 있는 CI/CD 구성이 있는지 확인한 후, CI/CD 템플릿을 생성하고 공유합니다.
  6. GitLab CI/CD 파이프라인을 더 빠르고 효율적으로 만드는 방법에 대해 알아보기 위해 파이프라인 효율성 문서를 확인하세요.

추가 자원

여기서 답변되지 않은 질문이 있다면, GitLab 커뮤니티 포럼이 좋은 자원이 될 수 있습니다.