파이프라인 아키텍처

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

파이프라인은 GitLab의 CI/CD를 위한 기본 빌딩 블록입니다. 이 페이지는
그들과 관련된 몇 가지 중요한 개념을 문서화합니다.

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

기본 파이프라인

기본 파이프라인은 GitLab에서 가장 간단한 파이프라인입니다. 빌드 단계에서 모든 작업을 동시에 실행하고,
이 모든 작업이 완료되면 테스트 및 후속 단계에서 모든 작업을 동일하게 실행합니다.
가장 효율적인 방법은 아니며, 단계가 많으면 꽤 복잡해질 수 있지만,
유지 관리하기는 더 쉽습니다:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: 기본 파이프라인 accDescr: 빌드, 테스트 및 배포 단계를 순차적으로 실행하는 파이프라인을 보여줍니다. 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 "이 작업은 무언가를 테스트합니다. 빌드 단계의 모든 작업이"
    - echo "완료되면 실행됩니다."

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

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

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

needs 키워드를 사용한 파이프라인

효율성이 중요하고 모든 작업을 가능한 한 빨리 실행하고 싶다면,

needs 키워드를 사용하여 작업 간의 의존성을 정의할 수 있습니다.

GitLab이 작업 간의 의존성을 알게 되면, 작업이 가능한 한 빨리 실행될 수 있으며,

같은 단계의 다른 작업보다 먼저 시작할 수도 있습니다.

아래 예시에서 build_atest_abuild_btest_b보다 훨씬 빠르다면,

GitLab은 build_b가 여전히 실행 중일지라도 deploy_a를 시작합니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: needs를 사용한 파이프라인 accDescr: 두 작업이 이전 단계가 완료되기를 기다리지 않고 시작하는 방식을 보여줍니다. subgraph needs를 사용한 파이프라인 build_a --> test_a --> deploy_a build_b --> test_b --> deploy_b end

다이어그램과 일치하는 예제 /.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를 기다릴 필요가 없습니다."
  환경: production

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo "build_b와 test_b가 천천히 실행되므로 이 배포 작업은 나중에 실행됩니다."
  환경: production

부모-자식 파이프라인

파이프라인이 더 복잡해짐에 따라 몇 가지 관련 문제가 발생하기 시작합니다:

  • 모든 단계의 모든 작업이 완료되어야 다음 단계의 첫 번째 작업이 시작되는 단계 구조는 대기 시간을 초래하여 속도를 늦춥니다.
  • 단일 글로벌 파이프라인의 구성은 관리하기 어려워집니다.
  • include로 가져오는 것은 구성의 복잡성을 증가시키며, 의도하지 않게 작업이 중복되는 네임스페이스 충돌을 일으킬 수 있습니다.
  • 파이프라인 UX는 작업과 단계가 너무 많이 존재하여 다루기 힘듭니다.

또한, 때때로 파이프라인의 동작이 더 동적으로 필요할 때도 있습니다.

하위 파이프라인을 시작할지 여부를 선택할 수 있는 능력은 특히 YAML이 동적으로 생성될 때 강력한 기능입니다.

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

위의 기본 파이프라인needs 파이프라인 예제에서는

서로 독립적으로 빌드될 수 있는 두 개의 패키지가 있습니다.

이러한 경우에 부모-자식 파이프라인을 사용하는 것이 이상적입니다.

구성을 여러 파일로 분리하여 더 간단하게 유지합니다.

부모-자식 파이프라인은 다음과 결합할 수 있습니다:

  • rules 키워드: 예를 들어, 해당 영역에 변경 사항이 있을 때만 자식 파이프라인을 트리거합니다.
  • include 키워드: 공통 동작을 가져와서 반복하지 않도록 합니다.
  • 자식 파이프라인 내에서의 needs 키워드: 두 가지의 장점을 동시에 얻습니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: 부모 및 자식 파이프라인 accDescr: 부모 파이프라인이 독립적인 자식 파이프라인을 트리거할 수 있음을 보여줍니다. 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/*

needs 키워드를 사용하는 /a/.gitlab-ci.yml에 위치한 자식 파이프라인 구성 예제:

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 "이 작업은 무언가를 배포합니다."
  환경: production

needs 키워드를 사용하는 /b/.gitlab-ci.yml에 위치한 자식 파이프라인 구성 예제:

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 "이 작업은 다른 것을 배포합니다."
  환경: production

작업은 GitLab에서 자식 파이프라인을 트리거하기 전이나 후에 실행될 수 있어, 공통 설정 단계나 통합된 배포를 허용합니다.