배포 안전
배포 안전 (Deployment safety)
배포 잡은 CI/CD 잡 중에서도 특히 민감한 종류예요. 파이프라인의 다른 잡보다 신중하게 다뤄야 할 때가 많죠. GitLab은 배포의 보안과 안정성을 유지하는 데 도움을 주는 여러 기능을 제공합니다.
출처: 문서
본문
배포 잡은 특별한 종류의 CI/CD 잡입니다. 파이프라인의 다른 잡보다 더 민감할 수 있고, 특별히 더 신경 써서 다뤄야 할 수 있어요. GitLab에는 배포의 보안과 안정성을 유지하는 데 도움을 주는 여러 기능이 있습니다.
할 수 있는 일들:
- 프로젝트에 적절한 역할을 설정. GitLab이 지원하는 다양한 사용자 역할과 각 역할의 권한은 프로젝트 멤버 권한을 참고하세요.
- 중요한 환경에 대한 쓰기 접근 제한
- 배포 동결 기간 동안 배포 방지
- 프로덕션 시크릿 보호
- 배포용 별도 프로젝트
지속적 배포(continuous deployment) 워크플로를 쓰면서 같은 환경에 동시 배포가 일어나지 않게 하려면:
전체 개요는 CD 파이프라인/워크플로를 안전하게 하는 방법 영상을 참고하세요.
중요한 환경에 대한 쓰기 접근 제한
기본적으로 환경은 Developer 역할 이상을 가진 팀 구성원이라면 누구나 수정할 수 있습니다. production 같은 중요한 환경에 대한 쓰기 접근을 제한하고 싶다면 protected 환경을 설정할 수 있어요.
한 번에 하나의 배포 잡만 실행되게 하기
GitLab CI/CD의 파이프라인 잡은 병렬로 실행되므로, 서로 다른 두 파이프라인의 배포 잡 두 개가 같은 환경에 동시에 배포를 시도할 수 있어요. 배포는 순차적으로 일어나야 하므로 이런 동작은 바람직하지 않습니다.
.gitlab-ci.yml에서 resource_group 키워드를 사용하면 한 번에 하나의 배포 잡만 실행되게 할 수 있습니다.
예를 들어:
deploy:
script: deploy-to-prod
resource_group: prod
resource group 없이 생기는 문제 있는 파이프라인 흐름의 예:
- Pipeline-A의
deploy잡이 실행을 시작합니다. - Pipeline-B의
deploy잡이 실행을 시작합니다. 예상치 못한 결과를 낳을 수 있는 동시 배포입니다. - Pipeline-A의
deploy잡이 끝납니다. - Pipeline-B의
deploy잡이 끝납니다.
resource group이 있을 때 개선된 파이프라인 흐름:
- Pipeline-A의
deploy잡이 실행을 시작합니다. - Pipeline-B의
deploy잡이 시작을 시도하지만, 첫 번째deploy잡이 끝날 때까지 기다립니다. - Pipeline-A의
deploy잡이 끝납니다. - Pipeline-B의
deploy잡이 실행을 시작합니다.
자세한 내용은 Resource Group 문서를 참고하세요.
오래된 배포 잡 방지
파이프라인 잡의 실제 실행 순서는 실행 때마다 달라질 수 있어서 바람직하지 않은 동작을 일으킬 수 있어요. 예를 들어 더 새로운 파이프라인의 배포 잡이 더 오래된 파이프라인의 배포 잡보다 먼저 끝날 수 있죠. 이러면 오래된 배포가 나중에 끝나면서 "더 새로운" 배포를 덮어쓰는 경쟁 상태가 생깁니다.
오래된 배포 잡 방지 설정을 통해 더 새로운 배포 잡이 시작될 때 오래된 배포 잡이 실행되지 않게 막을 수 있어요.
오래된 배포 잡이 시작되면 실패하고 다음과 같이 표시됩니다.
- 파이프라인 뷰에서
failed outdated deployment job - 완료된 잡을 볼 때
The deployment job is older than the latest deployment, and therefore failed.
오래된 배포 잡이 수동 잡이면 Run(플레이) 버튼이 비활성화되고 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. 메시지가 표시됩니다.
잡 나이는 커밋 시간이 아니라 잡 시작 시간으로 결정되므로, 어떤 상황에서는 더 새로운 커밋이 막힐 수 있습니다. 예를 들어 파이프라인 A(오래된 커밋)와 파이프라인 B(새로운 커밋) 둘 다 수동 배포 잡이 있다고 해보죠. 파이프라인 B를 만든 후에 파이프라인 A의 잡을 시작하면, 파이프라인 자체는 더 새롭더라도 파이프라인 B의 수동 배포 잡이 오래된 것으로 차단됩니다.
롤백 배포의 잡 재시도
안정적이고 오래된 배포로 빠르게 롤백해야 할 수 있어요. 기본적으로 배포 롤백을 위한 파이프라인 잡 재시도가 활성화되어 있습니다.
파이프라인 재시도를 비활성화하려면 Allow job retries for rollback deployments 체크박스를 해제하세요. 민감한 프로젝트에서는 파이프라인 재시도를 비활성화하는 편이 좋습니다.
롤백이 필요하면 이전 커밋으로 새 파이프라인을 실행해야 합니다.
예시
오래된 배포 잡 방지 설정이 비활성화된 경우의 문제 있는 파이프라인 흐름 예:
- 기본 브랜치에서 Pipeline-A가 생성됩니다.
- 나중에 기본 브랜치에서 Pipeline-B가 생성됩니다(더 새로운 커밋 SHA).
- Pipeline-B의
deploy잡이 먼저 끝나서 더 새로운 코드를 배포합니다. - Pipeline-A의
deploy잡이 나중에 끝나서 더 오래된 코드를 배포하며, 더 새로운(최신) 배포를 덮어씁니다.
설정이 활성화된 경우의 개선된 파이프라인 흐름:
- 기본 브랜치에서 Pipeline-A가 생성됩니다.
- 나중에 기본 브랜치에서 Pipeline-B가 생성됩니다(더 새로운 SHA).
- Pipeline-B의
deploy잡이 먼저 끝나서 더 새로운 코드를 배포합니다. - Pipeline-A의
deploy잡은 실패해서 더 새로운 파이프라인의 배포를 덮어쓰지 않습니다.
배포 동결 기간 동안 배포 방지
특정 기간, 예를 들어 대부분의 직원이 자리를 비우는 계획된 휴가 기간 동안 배포를 막고 싶다면 Deploy Freeze를 설정할 수 있어요. 배포 동결 기간 동안 GitLab은 모든 배포를 차단해서 예상치 못한 배포가 일어나지 않게 합니다.
다음으로 구성된 배포 동결은 환경 배포 목록 페이지 상단에 표시됩니다.
프로덕션 시크릿 보호
프로덕션 시크릿은 배포를 성공시키는 데 필요해요. 예를 들어 클라우드로 배포할 때 클라우드 제공자가 서비스에 연결하려면 이 시크릿을 요구합니다. 프로젝트 설정에서 CI/CD 변수로 이 시크릿들을 정의하고 보호할 수 있어요. 보호된 변수는 보호된 브랜치 또는 보호된 태그에서 실행되는 파이프라인에만 전달됩니다. 다른 파이프라인은 보호된 변수를 받지 못해요. 변수를 특정 환경으로 범위 지정할 수도 있습니다. 시크릿이 의도치 않게 노출되지 않도록 protected 환경에서 보호된 변수를 사용하세요. 프로덕션 시크릿은 러너 쪽에서도 정의할 수 있어요. 그러면 Maintainer 역할을 가진 다른 사용자가 시크릿을 읽는 것을 막고, 러너가 보호된 브랜치에서만 실행되게 합니다.
자세한 내용은 파이프라인 보안을 참고하세요.
배포용 별도 프로젝트
프로젝트에 Maintainer 역할이 있는 모든 사용자는 프로덕션 시크릿에 접근할 수 있습니다. 프로덕션 환경에 배포할 수 있는 사용자 수를 제한해야 한다면, 별도 프로젝트를 만들고 원래 프로젝트에서 CD 권한을 격리하는 새 권한 모델을 구성할 수 있어요. 그러면 원래 프로젝트에 Maintainer 역할이 있던 사용자가 프로덕션 시크릿과 CD 구성에 접근하지 못하게 됩니다. 멀티-프로젝트 파이프라인으로 CD 프로젝트를 개발 프로젝트에 연결할 수 있어요.
.gitlab-ci.yml이 변경되지 않게 보호
.gitlab-ci.yml에는 애플리케이션을 프로덕션 서버에 배포하는 규칙이 들어갈 수 있어요. 이 배포는 보통 머지 리퀘스트를 푸시한 후 자동으로 실행됩니다. 개발자가 .gitlab-ci.yml을 변경하지 못하게 하려면 이를 다른 저장소에 정의할 수 있습니다. 이 구성은 완전히 다른 권한 집합을 가진 다른 프로젝트의 파일을 참조할 수 있어요(배포용 별도 프로젝트와 비슷). 이 시나리오에서 .gitlab-ci.yml은 공개적으로 접근 가능하지만, 다른 프로젝트에서 적절한 권한을 가진 사용자만 편집할 수 있습니다.
자세한 내용은 커스텀 CI/CD 구성 경로를 참고하세요.
배포 전 승인 요구
배포를 프로덕션 환경으로 승격하기 전에 전담 테스트 그룹으로 교차 검증하는 것은 안전을 보장하는 효과적인 방법입니다. 자세한 내용은 배포 승인 문서를 참고하세요.
더 알아보기
배포 안전은 크게 세 축으로 생각할 수 있어요. 접근 권한을 제한하고(protected 환경), 동시 배포나 오래된 배포 같은 경쟁 상태를 막고(resource_group, 오래된 배포 방지), 시크릿을 안전하게 지키는 것(보호된 변수)이죠. 프로덕션 배포를 운영 중이라면 resource_group과 오래된 배포 방지 설정부터 적용해 보는 걸 추천해요.