파이프라인 아키텍처

Tier: Free, Premium, Ultimate

Offering: GitLab.com, Self-managed, GitLab Dedicated

파이프라인은 GitLab에서 CI/CD의 기본 컴포넌트입니다. 이 페이지에서는 파이프라인과 관련된 중요한 개념 몇 가지를 문서화했습니다.

다양한 방법으로 파이프라인을 구성할 수 있으며, 각각에는 고유한 장점이 있습니다. 이러한 방법은 필요에 따라 혼합하여 사용할 수 있습니다:

  • 기본: 모든 구성이 한 곳에 있는 간단한 프로젝트에 적합합니다.
  • 유향 비순환 그래프: 효율적인 실행이 필요한 크고 복잡한 프로젝트에 적합합니다.
  • 상위-하위 파이프라인: 모노 레포 및 독립적으로 정의된 컴포넌트가 많은 프로젝트에 적합합니다.

    개요는 Parent-Child 파이프라인 기능 데모에서 확인할 수 있습니다.

  • 다중 프로젝트 파이프라인: 교차 프로젝트 의존성이 필요한 대규모 제품에 적합합니다. 예를 들어, 여러 개의 GitLab 프로젝트에서 웹 애플리케이션을 배포할 수 있습니다. 다중 프로젝트 파이프라인을 사용하면 각 프로젝트에서 파이프라인을 트리거할 수 있으며, 각각에는 자체 빌드, 테스트 및 배포 프로세스가 있습니다. 연결된 파이프라인을 모두 시각화하여 교차 프로젝트 의존성을 포함하여 한 곳에서 확인할 수 있습니다.

    개요는 다중 프로젝트 파이프라인 데모에서 확인할 수 있습니다.

기본 파이프라인

기본 파이프라인은 GitLab에서 가장 간단한 파이프라인입니다. 빌드 단계의 모든 작업을 동시에 실행하고, 그 완료 후 테스트 및 후속 단계의 모든 작업을 동일한 방식으로 실행합니다. 가장 효율적이지는 않고, 단계가 많은 경우 꽤 복잡해질 수 있지만 유지보수가 더 쉽습니다.

graph LR subgraph deploy stage deploy --> deploy_a deploy --> deploy_b end subgraph test stage test --> test_a test --> test_b end subgraph build stage build --> build_a build --> build_b end build_a -.-> test build_b -.-> test test_a -.-> deploy test_b -.-> deploy

다이어그램에 해당하는 기본 .gitlab-ci.yml 파이프라인 구성 예시:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "이 작업은 무엇인가를 빌드합니다."

build_b:
  stage: build
  script:
    - echo "이 작업은 다른 것을 빌드합니다."

test_a:
  stage: test
  script:
    - echo "이 작업은 무엇인가를 테스트합니다. 모든 빌드 단계 작업이 완료되면 실행됩니다."

test_b:
  stage: test
  script:
    - echo "이 작업은 다른 것을 테스트합니다. 빌드 단계의 모든 작업이 완료되면 실행됩니다. test_a와 거의 동시에 시작됩니다."

deploy_a:
  stage: deploy
  script:
    - echo "이 작업은 무엇인가를 배포합니다. 모든 테스트 단계 작업이 완료되면 실행됩니다."
  environment: production

deploy_b:
  stage: deploy
  script:
    - echo "이 작업은 다른 것을 배포합니다. 모든 테스트 단계 작업이 완료되면 실행됩니다. deploy_a와 거의 동시에 시작됩니다."
  environment: production

유향 비순환 그래프 파이프라인

효율성이 중요하고 가능한 빨리 모든 것을 실행하고 싶다면 유향 비순환 그래프(DAG)를 사용할 수 있습니다. 작업 간의 의존성 관계를 정의하기 위해 needs 키워드를 사용합니다. GitLab이 작업 간의 관계를 알고 있으면 가능한 한 빨리 모든 것을 실행하고, 가능한 경우 후속 단계로 건너뛸 수도 있습니다.

아래 예시에서, build_atest_abuild_btest_b보다 빠를 경우, GitLab은 build_b가 실행 중일 때에도 deploy_a를 시작합니다.

graph LR subgraph DAG를 사용한 파이프라인 build_a --> test_a --> deploy_a build_b --> test_b --> deploy_b end

다이어그램에 해당하는 DAG .gitlab-ci.yml 구성 예시:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "이 작업은 빠르게 무언가를 빌드합니다."

build_b:
  stage: build
  script:
    - echo "이 작업은 다른 것을 느리게 빌드합니다."

test_a:
  stage: test
  needs: [build_a]
  script:
    - echo "이 테스트 작업은 build_a가 끝나자마자 시작합니다."
    - echo "build_b나 다른 빌드 단계 작업이 끝나기를 기다리지 않습니다."

test_b:
  stage: test
  needs: [build_b]
  script:
    - echo "이 테스트 작업은 build_b가 끝나자마자 시작합니다."
    - echo "빌드 단계의 다른 작업이 끝나기를 기다리지 않습니다."

deploy_a:
  stage: deploy
  needs: [test_a]
  script:
    - echo "build_a 및 test_a가 빠르게 실행되기 때문에 이 배포 작업은 훨씬 일찍 실행됩니다."
    - echo "build_b나 test_b를 기다릴 필요가 없습니다."
  environment: production

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo "build_b와 test_b가 느리게 실행되기 때문에 이 배포 작업은 훨씬 늦게 실행됩니다."
  environment: production

상위-하위 파이프라인

파이프라인이 더 복잡해지면 관련 문제가 발생합니다:

  • 모든 단계의 모든 작업이 완료된 후 다음 단계의 첫 번째 작업이 시작되어야 하는 스테이징 구조는 처리 지연을 초래합니다.
  • 단일 전역 파이프라인의 구성이 관리하기 어려워집니다.
  • include로 가져오는 것은 구성의 복잡성을 높이고, 의도하지 않게 작업이 중복되는 경우가 발생할 수 있습니다.
  • 파이프라인 사용자 경험이 처리할 작업 및 스테이지가 너무 많아집니다.

또한 때로는 파이프라인의 동작이 더 동적이어야 하는 경우가 있습니다. YAML이 동적으로 생성되는 경우 특히 상위-하위 파이프라인을 시작하거나 시작하지 않을 수 있는 능력은 강력합니다.

부모 파이프라인 그래프 확장

위의 기본 파이프라인유향 비순환 그래프 예제에서는 독립적으로 빌드할 수 있는 두 가지 패키지가 있습니다. 이러한 경우 상위-하위 파이프라인을 사용하는 것이 이상적입니다. 구성을 여러 파일로 분리하여 구성을 단순화합니다. 상위-하위 파이프라인을 다음과 함께 사용할 수 있습니다:

  • rules 키워드: 예를 들어, 해당 영역에 변경이 있는 경우에만 하위 파이프라인을 트리거할 수 있습니다.
  • include 키워드: 공통 동작을 가져와 중복을 피합니다.
  • 하위 파이프라인 내에서 DAG 파이프라인 사용으로 두 가지 모두의 장점을 얻을 수 있습니다.
graph LR subgraph 상위 파이프라인 trigger_a -.-> build_a trigger_b -.-> build_b subgraph 하위 파이프라인 B build_b --> test_b --> deploy_b end subgraph 하위 파이프라인 A build_a --> test_a --> deploy_a end end

다이어그램에 해당하는 상위 파이프라인을 위한 .gitlab-ci.yml 구성 예시:

stages:
  - triggers

trigger_a:
  stage: triggers
  trigger:
    include: a/.gitlab-ci.yml
  rules:
    - changes:
        - a/*

trigger_b:
  stage: triggers
  trigger:
    include: b/.gitlab-ci.yml
  rules:
    - changes:
        - b/*

위치: /a/.gitlab-ci.yml에 있는 하위 a 파이프라인 구성 예시, DAG needs 키워드 사용:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_a:
  stage: build
  script:
    - echo "이 작업은 무언가를 빌드합니다."

test_a:
  stage: test
  needs: [build_a]
  script:
    - echo "이 작업은 무언가를 테스트합니다."

deploy_a:
  stage: deploy
  needs: [test_a]
  script:
    - echo "이 작업은 무언가를 배포합니다."
  environment: production

위치: /b/.gitlab-ci.yml에 있는 하위 b 파이프라인 구성 예시, DAG needs 키워드 사용:

stages:
  - build
  - test
  - deploy

default:
  image: alpine

build_b:
  stage: build
  script:
    - echo "이 작업은 다른 것을 빌드합니다."

test_b:
  stage: test
  needs: [build_b]
  script:
    - echo "이 작업은 다른 것을 테스트합니다."

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo "이 작업은 다른 것을 배포합니다."
  environment: production

GitLab에서 하위 파이프라인을 트리거하기 전이나 후에 작업을 설정하거나 통합된 배포를 실행할 수 있습니다.