InfoGrab DocsInfoGrab Docs

배포 안전

요약

배포 job은 특정한 종류의 CI/CD job입니다. 지속적 배포(continuous deployment) 워크플로를 사용하면서 동일한 환경에 대한 동시 배포가 발생하지 않도록 하려면 다음을 수행해야 합니다: 개요는 CD 파이프라인/워크플로를 보호하는 방법을 참조합니다.

배포 job은 특정한 종류의 CI/CD job입니다. 파이프라인의 다른 job보다 민감할 수 있으며, 더 신경 써서 다뤄야 할 수도 있습니다. GitLab에는 배포의 보안과 안정성을 유지하는 데 도움이 되는 여러 기능이 있습니다.

다음을 할 수 있습니다:

지속적 배포(continuous deployment) 워크플로를 사용하면서 동일한 환경에 대한 동시 배포가 발생하지 않도록 하려면 다음을 수행해야 합니다:

개요는 CD 파이프라인/워크플로를 보호하는 방법을 참조합니다.

중요 환경에 대한 쓰기 접근 제한#

기본적으로 환경은 적어도 Developer 권한을 가진 모든 팀 구성원이 수정할 수 있습니다. 중요 환경(예: production 환경)에 대한 쓰기 접근을 제한하려면 보호된 환경을 설정할 수 있습니다.

한 번에 하나의 배포 job만 실행되도록 보장#

GitLab CI/CD의 파이프라인 job은 병렬로 실행되므로, 서로 다른 두 파이프라인의 배포 job이 동시에 같은 환경에 배포를 시도할 수 있습니다. 배포는 순차적으로 이루어져야 하므로 이러한 동작은 바람직하지 않습니다.

.gitlab-ci.yml에서 resource_group 키워드를 사용하면 한 번에 하나의 배포 job만 실행되도록 보장할 수 있습니다.

예를 들면 다음과 같습니다:

deploy:
 script: deploy-to-prod
 resource_group: prod

resource group이 없을 때 발생할 수 있는 문제가 있는 파이프라인 흐름의 예시입니다:

  1. Pipeline-A의 deploy job이 실행을 시작합니다.
  2. Pipeline-B의 deploy job이 실행을 시작합니다. 예상치 못한 결과를 초래할 수 있는 동시 배포입니다.
  3. Pipeline-A의 deploy job이 완료됩니다.
  4. Pipeline-B의 deploy job이 완료됩니다.

resource group을 사용했을 때 개선된 파이프라인 흐름입니다:

  1. Pipeline-A의 deploy job이 실행을 시작합니다.
  2. Pipeline-B의 deploy job이 시작을 시도하지만, 먼저 실행된 deploy job이 끝날 때까지 대기합니다.
  3. Pipeline-A의 deploy job이 완료됩니다.
  4. Pipeline-B의 deploy job이 실행을 시작합니다.

자세한 내용은 Resource Group 문서를 참조합니다.

오래된 배포 job 방지#

파이프라인 job의 실제 실행 순서는 실행마다 달라질 수 있으며, 이로 인해 원치 않는 동작이 발생할 수 있습니다. 예를 들어, 최신 파이프라인의 배포 job이 더 오래된 파이프라인의 배포 job보다 먼저 완료될 수 있습니다. 이 경우 더 오래된 배포가 나중에 완료되어 "최신" 배포를 덮어쓰는 경쟁 상태(race condition)가 발생합니다.

오래된 배포 job 방지 설정을 사용하면 더 최신 배포 job이 시작될 때 더 오래된 배포 job이 실행되지 않도록 방지할 수 있습니다.

오래된 배포 job이 시작되면 실패하며 다음과 같이 표시됩니다:

  • 파이프라인 보기에서 failed outdated deployment job.
  • 완료된 job을 볼 때 The deployment job is older than the latest deployment, and therefore failed.

오래된 배포 job이 수동(manual)인 경우, Run([play]) 버튼이 비활성화되며 This deployment job does not run automatically and must be started manually, but it's older than the latest deployment, and therefore can't run. 메시지가 표시됩니다.

job의 순서는 커밋 시각이 아니라 job 시작 시각을 기준으로 결정되므로, 경우에 따라 더 최신 커밋이 차단될 수 있습니다. 예를 들어, 파이프라인 A(오래된 커밋)와 파이프라인 B(최신 커밋)에 모두 수동 배포 job이 있다고 가정합니다. 파이프라인 B를 생성한 후에 파이프라인 A의 job을 시작하면, 파이프라인 B 자체가 더 최신임에도 파이프라인 B의 수동 배포 job이 오래된 job으로 차단됩니다.

롤백 배포에 대한 job 재시도#

안정적이지만 오래된 배포로 빠르게 롤백해야 할 수도 있습니다. 기본적으로 배포 롤백에 대한 파이프라인 job 재시도는 활성화되어 있습니다.

파이프라인 재시도를 비활성화하려면 Allow job retries for rollback deployments 체크박스를 해제합니다. 민감한 프로젝트에서는 파이프라인 재시도를 비활성화하는 것이 좋습니다.

롤백이 필요한 경우, 이전 커밋으로 새 파이프라인을 실행해야 합니다.

예시#

Prevent outdated deployment jobs 설정이 비활성화되어 있을 때 발생할 수 있는 문제가 있는 파이프라인 흐름의 예시입니다:

  1. 기본 브랜치에 Pipeline-A가 생성됩니다.
  2. 이후 기본 브랜치에 (더 최신 커밋 SHA를 가진) Pipeline-B가 생성됩니다.
  3. Pipeline-B의 deploy job이 먼저 완료되어 더 최신 코드를 배포합니다.
  4. Pipeline-A의 deploy job이 나중에 완료되어 더 오래된 코드를 배포하며, 더 최신(최근) 배포를 덮어씁니다.

설정을 활성화했을 때 개선된 파이프라인 흐름은 다음과 같습니다:

  1. 기본 브랜치에 Pipeline-A가 생성됩니다.
  2. 이후 기본 브랜치에 (더 최신 SHA를 가진) Pipeline-B가 생성됩니다.
  3. Pipeline-B의 deploy job이 먼저 완료되어 더 최신 코드를 배포합니다.
  4. Pipeline-A의 deploy job이 실패하여 더 최신 파이프라인의 배포를 덮어쓰지 않습니다.

배포 정지 기간 동안 배포 방지#

예를 들어 대부분의 직원이 자리를 비우는 계획된 휴가 기간처럼 특정 기간 동안 배포를 방지하려면 배포 정지(Deploy Freeze)를 설정할 수 있습니다. 배포 정지 기간 동안 GitLab은 모든 배포를 차단하여 의도치 않은 배포가 발생하지 않도록 합니다.

다음에 예정된 배포 정지 일정은 환경 배포 목록 페이지 상단에 표시됩니다.

프로덕션 시크릿 보호#

프로덕션 시크릿은 배포를 성공적으로 수행하는 데 필요합니다. 예를 들어 클라우드에 배포할 때, 클라우드 제공업체는 자사 서비스에 연결하기 위해 이러한 시크릿을 요구합니다. 프로젝트 설정에서 이러한 시크릿에 대한 CI/CD 변수를 정의하고 보호할 수 있습니다. 보호된 변수는 보호된 브랜치 또는 보호된 태그에서 실행되는 파이프라인에만 전달됩니다. 다른 파이프라인은 보호된 변수를 받지 못합니다. 또한 변수를 특정 환경으로 범위 지정할 수도 있습니다. 시크릿이 의도치 않게 노출되지 않도록 하려면 보호된 환경에서 보호된 변수를 사용합니다. 또한 러너 측에서 프로덕션 시크릿을 정의할 수도 있습니다. 이렇게 하면 Maintainer 권한을 가진 다른 사용자가 시크릿을 읽지 못하도록 방지하고, 러너가 보호된 브랜치에서만 실행되도록 보장합니다.

자세한 내용은 파이프라인 보안을 참조합니다.

배포용 별도 프로젝트 구성#

프로젝트에 대해 Maintainer 권한을 가진 모든 사용자는 프로덕션 시크릿에 접근할 수 있습니다. 프로덕션 환경에 배포할 수 있는 사용자 수를 제한해야 하는 경우, 별도의 프로젝트를 생성하고 원본 프로젝트로부터 CD 권한을 분리하는 새로운 권한 모델을 구성하여, 원본 프로젝트에서 Maintainer 권한을 가진 사용자가 프로덕션 시크릿과 CD 구성에 접근하지 못하도록 할 수 있습니다. 다중 프로젝트 파이프라인을 사용하여 CD 프로젝트를 개발 프로젝트에 연결할 수 있습니다.

.gitlab-ci.yml 변경 방지#

.gitlab-ci.yml에는 애플리케이션을 프로덕션 서버에 배포하는 규칙이 포함될 수 있습니다. 이러한 배포는 보통 머지 리퀘스트를 푸시한 후 자동으로 실행됩니다. 개발자가 .gitlab-ci.yml을 변경하지 못하도록 하려면, 이를 다른 리포지터리에 정의할 수 있습니다. 이 구성은 완전히 다른 권한 집합을 가진 다른 프로젝트의 파일을 참조할 수 있습니다 (배포용 별도 프로젝트 구성과 유사합니다). 이 경우 .gitlab-ci.yml은 공개적으로 접근할 수 있지만, 다른 프로젝트에서 적절한 권한을 가진 사용자만 편집할 수 있습니다.

자세한 내용은 사용자 지정 CI/CD 구성 경로를 참조합니다.

배포 전 승인 요구#

배포를 프로덕션 환경으로 승격하기 전에, 전담 테스트 그룹과 함께 교차 검증하는 것은 안전을 보장하는 효과적인 방법입니다. 자세한 내용은 배포 승인을 참조합니다.

배포 안전

GitLab v19.5
Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기

요약

배포 job은 특정한 종류의 CI/CD job입니다. 지속적 배포(continuous deployment) 워크플로를 사용하면서 동일한 환경에 대한 동시 배포가 발생하지 않도록 하려면 다음을 수행해야 합니다: 개요는 CD 파이프라인/워크플로를 보호하는 방법을 참조합니다.

배포 job은 특정한 종류의 CI/CD job입니다. 파이프라인의 다른 job보다 민감할 수 있으며, 더 신경 써서 다뤄야 할 수도 있습니다. GitLab에는 배포의 보안과 안정성을 유지하는 데 도움이 되는 여러 기능이 있습니다.

다음을 할 수 있습니다:

지속적 배포(continuous deployment) 워크플로를 사용하면서 동일한 환경에 대한 동시 배포가 발생하지 않도록 하려면 다음을 수행해야 합니다:

개요는 CD 파이프라인/워크플로를 보호하는 방법을 참조합니다.

중요 환경에 대한 쓰기 접근 제한#

기본적으로 환경은 적어도 Developer 권한을 가진 모든 팀 구성원이 수정할 수 있습니다. 중요 환경(예: production 환경)에 대한 쓰기 접근을 제한하려면 보호된 환경을 설정할 수 있습니다.

한 번에 하나의 배포 job만 실행되도록 보장#

GitLab CI/CD의 파이프라인 job은 병렬로 실행되므로, 서로 다른 두 파이프라인의 배포 job이 동시에 같은 환경에 배포를 시도할 수 있습니다. 배포는 순차적으로 이루어져야 하므로 이러한 동작은 바람직하지 않습니다.

.gitlab-ci.yml에서 resource_group 키워드를 사용하면 한 번에 하나의 배포 job만 실행되도록 보장할 수 있습니다.

예를 들면 다음과 같습니다:

deploy:
 script: deploy-to-prod
 resource_group: prod

resource group이 없을 때 발생할 수 있는 문제가 있는 파이프라인 흐름의 예시입니다:

  1. Pipeline-A의 deploy job이 실행을 시작합니다.
  2. Pipeline-B의 deploy job이 실행을 시작합니다. 예상치 못한 결과를 초래할 수 있는 동시 배포입니다.
  3. Pipeline-A의 deploy job이 완료됩니다.
  4. Pipeline-B의 deploy job이 완료됩니다.

resource group을 사용했을 때 개선된 파이프라인 흐름입니다:

  1. Pipeline-A의 deploy job이 실행을 시작합니다.
  2. Pipeline-B의 deploy job이 시작을 시도하지만, 먼저 실행된 deploy job이 끝날 때까지 대기합니다.
  3. Pipeline-A의 deploy job이 완료됩니다.
  4. Pipeline-B의 deploy job이 실행을 시작합니다.

자세한 내용은 Resource Group 문서를 참조합니다.

오래된 배포 job 방지#

파이프라인 job의 실제 실행 순서는 실행마다 달라질 수 있으며, 이로 인해 원치 않는 동작이 발생할 수 있습니다. 예를 들어, 최신 파이프라인의 배포 job이 더 오래된 파이프라인의 배포 job보다 먼저 완료될 수 있습니다. 이 경우 더 오래된 배포가 나중에 완료되어 "최신" 배포를 덮어쓰는 경쟁 상태(race condition)가 발생합니다.

오래된 배포 job 방지 설정을 사용하면 더 최신 배포 job이 시작될 때 더 오래된 배포 job이 실행되지 않도록 방지할 수 있습니다.

오래된 배포 job이 시작되면 실패하며 다음과 같이 표시됩니다:

  • 파이프라인 보기에서 failed outdated deployment job.
  • 완료된 job을 볼 때 The deployment job is older than the latest deployment, and therefore failed.

오래된 배포 job이 수동(manual)인 경우, Run([play]) 버튼이 비활성화되며 This deployment job does not run automatically and must be started manually, but it's older than the latest deployment, and therefore can't run. 메시지가 표시됩니다.

job의 순서는 커밋 시각이 아니라 job 시작 시각을 기준으로 결정되므로, 경우에 따라 더 최신 커밋이 차단될 수 있습니다. 예를 들어, 파이프라인 A(오래된 커밋)와 파이프라인 B(최신 커밋)에 모두 수동 배포 job이 있다고 가정합니다. 파이프라인 B를 생성한 후에 파이프라인 A의 job을 시작하면, 파이프라인 B 자체가 더 최신임에도 파이프라인 B의 수동 배포 job이 오래된 job으로 차단됩니다.

롤백 배포에 대한 job 재시도#

안정적이지만 오래된 배포로 빠르게 롤백해야 할 수도 있습니다. 기본적으로 배포 롤백에 대한 파이프라인 job 재시도는 활성화되어 있습니다.

파이프라인 재시도를 비활성화하려면 Allow job retries for rollback deployments 체크박스를 해제합니다. 민감한 프로젝트에서는 파이프라인 재시도를 비활성화하는 것이 좋습니다.

롤백이 필요한 경우, 이전 커밋으로 새 파이프라인을 실행해야 합니다.

예시#

Prevent outdated deployment jobs 설정이 비활성화되어 있을 때 발생할 수 있는 문제가 있는 파이프라인 흐름의 예시입니다:

  1. 기본 브랜치에 Pipeline-A가 생성됩니다.
  2. 이후 기본 브랜치에 (더 최신 커밋 SHA를 가진) Pipeline-B가 생성됩니다.
  3. Pipeline-B의 deploy job이 먼저 완료되어 더 최신 코드를 배포합니다.
  4. Pipeline-A의 deploy job이 나중에 완료되어 더 오래된 코드를 배포하며, 더 최신(최근) 배포를 덮어씁니다.

설정을 활성화했을 때 개선된 파이프라인 흐름은 다음과 같습니다:

  1. 기본 브랜치에 Pipeline-A가 생성됩니다.
  2. 이후 기본 브랜치에 (더 최신 SHA를 가진) Pipeline-B가 생성됩니다.
  3. Pipeline-B의 deploy job이 먼저 완료되어 더 최신 코드를 배포합니다.
  4. Pipeline-A의 deploy job이 실패하여 더 최신 파이프라인의 배포를 덮어쓰지 않습니다.

배포 정지 기간 동안 배포 방지#

예를 들어 대부분의 직원이 자리를 비우는 계획된 휴가 기간처럼 특정 기간 동안 배포를 방지하려면 배포 정지(Deploy Freeze)를 설정할 수 있습니다. 배포 정지 기간 동안 GitLab은 모든 배포를 차단하여 의도치 않은 배포가 발생하지 않도록 합니다.

다음에 예정된 배포 정지 일정은 환경 배포 목록 페이지 상단에 표시됩니다.

프로덕션 시크릿 보호#

프로덕션 시크릿은 배포를 성공적으로 수행하는 데 필요합니다. 예를 들어 클라우드에 배포할 때, 클라우드 제공업체는 자사 서비스에 연결하기 위해 이러한 시크릿을 요구합니다. 프로젝트 설정에서 이러한 시크릿에 대한 CI/CD 변수를 정의하고 보호할 수 있습니다. 보호된 변수는 보호된 브랜치 또는 보호된 태그에서 실행되는 파이프라인에만 전달됩니다. 다른 파이프라인은 보호된 변수를 받지 못합니다. 또한 변수를 특정 환경으로 범위 지정할 수도 있습니다. 시크릿이 의도치 않게 노출되지 않도록 하려면 보호된 환경에서 보호된 변수를 사용합니다. 또한 러너 측에서 프로덕션 시크릿을 정의할 수도 있습니다. 이렇게 하면 Maintainer 권한을 가진 다른 사용자가 시크릿을 읽지 못하도록 방지하고, 러너가 보호된 브랜치에서만 실행되도록 보장합니다.

자세한 내용은 파이프라인 보안을 참조합니다.

배포용 별도 프로젝트 구성#

프로젝트에 대해 Maintainer 권한을 가진 모든 사용자는 프로덕션 시크릿에 접근할 수 있습니다. 프로덕션 환경에 배포할 수 있는 사용자 수를 제한해야 하는 경우, 별도의 프로젝트를 생성하고 원본 프로젝트로부터 CD 권한을 분리하는 새로운 권한 모델을 구성하여, 원본 프로젝트에서 Maintainer 권한을 가진 사용자가 프로덕션 시크릿과 CD 구성에 접근하지 못하도록 할 수 있습니다. 다중 프로젝트 파이프라인을 사용하여 CD 프로젝트를 개발 프로젝트에 연결할 수 있습니다.

.gitlab-ci.yml 변경 방지#

.gitlab-ci.yml에는 애플리케이션을 프로덕션 서버에 배포하는 규칙이 포함될 수 있습니다. 이러한 배포는 보통 머지 리퀘스트를 푸시한 후 자동으로 실행됩니다. 개발자가 .gitlab-ci.yml을 변경하지 못하도록 하려면, 이를 다른 리포지터리에 정의할 수 있습니다. 이 구성은 완전히 다른 권한 집합을 가진 다른 프로젝트의 파일을 참조할 수 있습니다 (배포용 별도 프로젝트 구성과 유사합니다). 이 경우 .gitlab-ci.yml은 공개적으로 접근할 수 있지만, 다른 프로젝트에서 적절한 권한을 가진 사용자만 편집할 수 있습니다.

자세한 내용은 사용자 지정 CI/CD 구성 경로를 참조합니다.

배포 전 승인 요구#

배포를 프로덕션 환경으로 승격하기 전에, 전담 테스트 그룹과 함께 교차 검증하는 것은 안전을 보장하는 효과적인 방법입니다. 자세한 내용은 배포 승인을 참조합니다.