리소스 그룹
기본적으로 GitLab CI/CD의 파이프라인은 동시에 실행됩니다. 동시성은 MR(병합 요청)에서의 피드백 루프를 개선하는 데 중요한 요소이지만, 배포 작업에서 동시성을 제한하고 순차적으로 실행하는 경우가 필요할 수 있습니다. 리소스 그룹을 사용하여 지속적인 배포 워크플로우의 동시성을 전략적으로 제어하세요.
리소스 그룹 추가
다음 파이프라인 설정이 있는 경우(.gitlab-ci.yml
에서 귀하의 저장소):
build:
stage: build
script: echo "빌드 스크립트"
deploy:
stage: deploy
script: echo "배포 스크립트"
environment: production
새로운 커밋을 브랜치에 푸시할 때마다 build
와 deploy
두 개의 작업이 있는 새로운 파이프라인이 실행됩니다. 그러나 짧은 간격으로 여러 커밋을 푸시하는 경우 여러 파이프라인이 동시에 실행됩니다. 예를 들어:
- 첫 번째 파이프라인은 작업
build
->deploy
를 실행합니다. - 두 번째 파이프라인은 작업
build
->deploy
를 실행합니다.
이 경우 서로 다른 파이프라인에서 production
환경으로의 deploy
작업이 동시에 실행될 수 있습니다. 동일한 인프라에 대해 여러 배포 스크립트를 실행하는 것은 최악의 경우 인스턴스를 손상시키거나 혼란스럽게 할 수 있습니다.
deploy
작업이 한 번에 한 번씩 실행되도록 하려면 동시성 민감 작업에 resource_group
키워드를 지정할 수 있습니다:
deploy:
...
resource_group: production
이 구성으로 배포의 안전성은 보장되지만 파이프라인 효율을 극대화하기 위해 여전히 build
작업을 동시에 실행할 수 있습니다.
필수 요구 사항
- GitLab CI/CD 파이프라인에 대한 기본 지식
- GitLab 환경 및 배포에 대한 기본 지식
- 프로젝트에서 CI/CD 파이프라인을 구성하려면 적어도 개발자 역할이 필요합니다.
제한 사항
한 리소스 그룹에는 하나의 리소스만 연결할 수 있습니다.
프로세스 모드
배포 환경 설정을 위해 작업 동시성을 전략적으로 제어하기 위해 프로세스 모드를 선택할 수 있습니다. 다음과 같은 모드가 지원됩니다:
- 순서 없음: 실행 작업의 동시성을 제한하는 기본 프로세스 모드입니다. 작업의 실행 순서가 중요하지 않을 때 가장 쉽게 사용할 수 있는 옵션입니다. 작업이 실행 준비가 되면 즉시 처리를 시작합니다.
-
가장 오래된 것 먼저: 이 프로세스 모드는 작업의 동시성을 제한합니다. 리소스가 비어있을 때 예정된 작업 목록(
created
,scheduled
, 또는waiting_for_resource
상태)에서 파이프라인 ID로 오름차순으로 정렬된 첫 번째 작업을 선택합니다. 작업이 가장 오래된 파이프라인에서 실행되도록 보장하려면 이 모드가 효과적입니다. 파이프라인 효율에 있어서unordered
모드보다 효율성은 낮지만 지속적인 배포에 대해 안전합니다. -
가장 최근 것 먼저: 이 프로세스 모드는 작업의 동시성을 제한합니다. 리소스가 비어있을 때 예정된 작업 목록(
created
,scheduled
, 또는waiting_for_resource
상태)에서 파이프라인 ID로 내림차순으로 정렬된 첫 번째 작업을 선택합니다. 이 모드는 작업이 가장 최근 파이프라인에서 실행되도록 보장하고 오래된 배포 작업 방지 기능을 통해 모든 이전 배포 작업을 방지합니다. 파이프라인 효율에 있어서 가장 효과적이지만 각 배포 작업이 멱듭(한 번 이상 호출해도 동일한 결과를 얻는)인지 확인해야 합니다.
프로세스 모드 변경
리소스 그룹의 프로세스 모드를 변경하려면 API를 사용하고 process_mode
를 지정하여 기존 리소스 그룹 편집에 요청을 보내야 합니다:
unordered
oldest_first
newest_first
프로세스 모드 간 차이 예시
다음 .gitlab-ci.yml
을 고려해보겠습니다. 이 설정에는 build
와 deploy
두 개의 작업이 있으며 동일한 스테이지에서 실행되며 deploy
작업은 production
리소스 그룹으로 설정되어 있습니다:
build:
stage: build
script: echo "빌드 스크립트"
deploy:
stage: deploy
script: echo "배포 스크립트"
environment: production
resource_group: production
프로젝트에 세 개의 커밋이 짧은 간격으로 푸시되면 거의 동시에 세 개의 파이프라인이 실행됩니다:
- 첫 번째 파이프라인은 작업
build
->deploy
를 실행합니다. 이 배포 작업을deploy-1
이라고 합시다. - 두 번째 파이프라인은 작업
build
->deploy
를 실행합니다. 이 배포 작업을deploy-2
라고 합시다. - 세 번째 파이프라인은 작업
build
->deploy
를 실행합니다. 이 배포 작업을deploy-3
이라고 합시다.
리소스 그룹의 프로세스 모드에 따라:
- 프로세스 모드가
unordered
로 설정된 경우:-
deploy-1
,deploy-2
,deploy-3
은 동시에 실행되지 않습니다. - 작업 실행 순서에 대한 보장이 없으며, 예를 들어
deploy-1
이deploy-3
보다 먼저 실행될 수도, 늦게 실행될 수도 있습니다.
-
- 프로세스 모드가
oldest_first
인 경우:-
deploy-1
,deploy-2
,deploy-3
은 동시에 실행되지 않습니다. -
deploy-1
이 먼저,deploy-2
가 두 번째,deploy-3
이 마지막으로 실행됩니다.
-
- 프로세스 모드가
newest_first
인 경우:-
deploy-1
,deploy-2
,deploy-3
은 동시에 실행되지 않습니다. -
deploy-3
이 먼저,deploy-2
가 두 번째,deploy-1
이 마지막으로 실행됩니다.
-
프로젝트 수준의 교차 프로젝트/부모-자식 파이프라인 동시성 제어
동시 실행에 민감한 하위 파이프라인에 대해 resource_group
을 정의할 수 있습니다. trigger
키워드는 하위 파이프라인을 트리거할 수 있으며 resource_group
키워드는 함께 존재할 수 있습니다. 다른 작업은 계속해서 동시에 실행될 수 있으며, resrouce_group
은 배포 파이프라인의 동시성을 효과적으로 제어합니다.
다음 예시는 프로젝트에서 두 개의 파이프라인 설정이 있습니다. 파이프라인이 실행되면 민감하지 않은 작업이 먼저 실행되며, 다른 파이프라인의 동시 실행에 영향을 받지 않습니다. 그러나 GitLab은 배포(하위) 파이프라인을 트리거하기 전에 다른 배포 파이프라인이 실행되지 않도록 보장합니다. 다른 배포 파이프라인이 실행 중이면 GitLab은 다른 하나를 실행하기 전에 해당 파이프라인이 완료될 때까지 기다립니다.
# .gitlab-ci.yml (부모 파이프라인)
build:
stage: build
script: echo "빌드 중..."
test:
stage: test
script: echo "테스트 중..."
deploy:
stage: deploy
trigger:
include: deploy.gitlab-ci.yml
strategy: depend
resource_group: AWS-production
# deploy.gitlab-ci.yml (하위 파이프라인)
stages:
- provision
- deploy
provision:
stage: provision
script: echo "프로비저닝 중..."
deployment:
stage: deploy
script: echo "배포 중..."
environment: production
trigger
키워드와 함께 stratgey: depend
를 정의해야 합니다. 이렇게 함으로써 하위 파이프라인이 완료될 때까지 잠금이 해제되지 않도록 보장합니다.
관련 주제
문제 해결
파이프라인 설정에서 데드락 피하기
oldest_first
프로세스 모드는 작업이 파이프라인 순서대로 실행되도록 강제하기 때문에
다른 CI 기능과 잘 작동하지 않을 수 있습니다.
예를 들어, 자식 파이프라인을 실행할 때 부모 파이프라인과 동일한 리소스 그룹이 필요한 경우, 데드락이 발생할 수 있습니다. 다음은 나쁜 설정 예입니다:
# 나쁨
test:
stage: test
trigger:
include: child-pipeline-requires-production-resource-group.yml
strategy: depend
deploy:
stage: deploy
script: echo
resource_group: production
environment: production
부모 파이프라인에서는 이전에 test
작업을 실행하고 그 다음 자식 파이프라인을 실행하며,
strategy: depend
옵션은 test
작업이 자식 파이프라인이 완료될 때까지 기다리도록 만듭니다.
부모 파이프라인은 다음 단계에서 production
리소스가 필요한 deploy
작업을 실행합니다.
프로세스 모드가 oldest_first
이면 작업은 가장 이전의 파이프라인부터 실행되므로 deploy
작업이 다음으로 실행됩니다.
그러나 자식 파이프라인도 production
리소스 그룹에서 리소스가 필요합니다.
자식 파이프라인이 부모 파이프라인보다 최근이므로 자식 파이프라인은 deploy
작업이 완료될 때까지 기다립니다.
이 경우 부모 파이프라인 구성에서 resource_group
키워드를 명시해야 합니다:
# 좋음
test:
stage: test
trigger:
include: child-pipeline.yml
strategy: depend
resource_group: production # 부모 파이프라인에서 리소스 그룹 명시
deploy:
stage: deploy
script: echo
resource_group: production
environment: production
작업이 “리소스 대기 중”에 멈추는 경우
가끔 작업이 Waiting for resource: <resource_group>
메시지와 함께 멈추는 경우가 있습니다. 이를 해결하려면 먼저 리소스 그룹이 올바르게 작동하는지 확인하세요:
- 작업 상세 페이지로 이동합니다.
-
리소스가 작업에 할당되어 있는 경우 View job currently using resource를 선택하고 작업 상태를 확인합니다.
- 상태가
running
또는pending
이면 기능이 올바르게 작동 중입니다. 작업이 완료되고 리소스를 해제할 때까지 기다립니다. - 상태가
created
이고 프로세스 모드가 Oldest first 또는 Newest first인 경우 기능이 올바르게 작동 중입니다. 작업이 실행을 차단하는 상위 스테이지나 작업을 확인하기 위해 해당 작업의 파이프라인 페이지로 이동합니다. - 위의 어느 조건도 해당하지 않는 경우에는 기능이 올바르게 작동하지 않을 수 있습니다. GitLab에 문제 보고를 합니다.
- 상태가
-
View job currently using resource을 사용할 수 없는 경우 리소스가 작업에 할당되지 않은 것입니다. 대신 리소스의 예정된 작업을 확인합니다.
- REST API를 사용하여 리소스의 예정된 작업을 가져옵니다.
- 리소스 그룹의 프로세스 모드가 Oldest first인지 확인합니다.
- 예정된 작업 목록에서 첫 번째 작업을 찾고 GraphQL을 사용하여 작업 상세 정보를 가져옵니다.
- 첫 번째 작업의 파이프라인이 이전 파이프라인인 경우 파이프라인이나 해당 작업 자체를 취소해 봅니다.
- 선택 사항입니다. 다음 예정된 작업이 여전히 더 이상 실행되지 않아야 하는 이전 파이프라인에 있으면 이 프로세스를 반복합니다.
- 문제가 지속되면 GitLab에 문제 보고를 합니다.
복잡하거나 바쁜 파이프라인에서의 레이스 조건
위의 해결 방법으로 문제를 해결할 수 없는 경우, 알려진 레이스 조건 문제에 부딪힐 수 있습니다. 레이스 조건은 복잡하거나 바쁜 파이프라인에서 발생할 수 있습니다. 예를 들어, 다음과 같은 경우 레이스 조건 문제가 발생할 수 있습니다:
- 여러 자식 파이프라인을 실행하는 파이프라인.
- 동시에 여러 파이프라인을 실행하는 단일 프로젝트.
이러한 문제에 부딪힌 것으로 생각된다면 GitLab에 문제를 보고하고 새로운 문제에 링크를 걸어 issue 436988에 댓글을 남깁니다. 문제를 확인하기 위해 GitLab에서는 파이프라인 구성과 같은 추가 세부 정보를 요청할 수 있습니다.
일시적인 해결책으로 다음을 할 수 있습니다:
- 새로운 파이프라인을 시작합니다.
-
멈춘 작업과 동일한 리소스 그룹을 가진 완료된 작업을 다시 실행합니다.
예를 들어,
setup_job
과 “대기 중인 리소스”가 “setup_job”을 재 실행하여 “deploy_job”이 완료될 수 있도록 프로세스를 다시 시작합니다.
GraphQL을 통해 작업 세부 정보 가져오기
GraphQL API에서 작업 정보를 가져올 수 있습니다. 파이프라인-수준 동시성 제어와 교차 프로젝트/부모-자식 파이프라인과 함께 trigger 작업이 UI에서 액세스할 수 없는 경우에는 GraphQL API를 사용해야 합니다.
GraphQL API에서 작업 정보를 가져 오려면 다음 단계를 수행하세요:
- 파이프라인 세부 정보 페이지로 이동합니다.
- Jobs 탭을 선택하고 멈춰 있는 작업의 ID를 찾습니다.
- 대화형 GraphQL 탐색기로 이동합니다.
-
다음 쿼리를 실행합니다:
{ project(fullPath: "<fullpath-to-your-project>") { name job(id: "gid://gitlab/Ci::Build/<job-id>") { name status detailedStatus { action { path buttonTitle } } } } }
job.detailedStatus.action.path
필드에 리소스를 사용하는 작업 ID가 포함되어 있습니다. -
다음 쿼리를 실행하고 위의 기준에 따라
job.status
필드를 확인합니다.pipeline.path
필드에서 파이프라인 페이지로 이동할 수도 있습니다.{ project(fullPath: "<fullpath-to-your-project>") { name job(id: "gid://gitlab/Ci::Build/<job-id-currently-using-the-resource>") { name status pipeline { path } } } }
문제 신고
다음 정보를 포함하여 새로운 문제를 열어주세요:
- 영향 받는 작업의 ID.
- 작업 상태.
- 문제가 발생하는 빈도.
-
문제를 재현하는 단계.
더 많은 지원이 필요하거나 개발팀과 연락하려면 지원팀에 연락할 수도 있습니다.