Verify Stage 코드베이스에 기여하기
GitLab v19.4요약
Verify 스테이지는 GitLab 제품에 통합된 종합 Continuous Integration 플랫폼을 만들고 있습니다. GitLab CI/CD가 전달하는 피드백은 사용자가 성공에 필요한 기술적·비즈니스적 선택을 충분한 정보에 근거해 내릴 수 있게 합니다.
Verify의 작업 방향#
Verify 스테이지는 GitLab 제품에 통합된 종합 Continuous Integration 플랫폼을 만들고 있습니다. 사용자가 세운 가정을 검증하고 CI/CD 설정에 정의된 기준과 대조하는 빠르고 안정적이며 안전한 플랫폼을 제공해, 사용자가 훌륭한 기술적·비즈니스적 의사 결정을 내릴 수 있도록 하는 것이 목표입니다. 여기에는 단위 테스트, 종단 간 테스트, 벤치마킹, 성능 검증, 코드 커버리지 강제 등이 포함됩니다.
GitLab CI/CD가 전달하는 피드백은 사용자가 성공에 필요한 기술적·비즈니스적 선택을 충분한 정보에 근거해 내릴 수 있게 합니다. Continuous Integration 이 미션 크리티컬한 제품인 이유는 다음과 같습니다.
GitLab CI/CD는 사용자와 고객에게 피드백을 전달하는 플랫폼입니다.
사용자는 답을 얻고자 하는 질문을 기술하기 위해 Continuous
Integration 설정 파일 .gitlab-ci.yml을 작성합니다. 누군가
커밋을 푸시하거나 파이프라인을 트리거할 때마다, GitLab은
CI/CD 설정에 담긴 매우 중요한 질문들에 대한 답을 찾아야 합니다.
이 질문에 답하지 못하거나, 더 나쁘게는 잘못된 답을 제공하면 사용자가 잘못된 결정을 내릴 수 있습니다. 그러한 잘못된 결정은 매우 심각한 결과로 이어질 수 있습니다.
CI/CD 플랫폼의 핵심 원칙#
플랫폼이 생성하는 데이터는 다음 조건을 갖춰야 합니다.
- 정확성.
- 내구성.
- 접근성.
플랫폼 자체는 다음 조건을 갖춰야 합니다.
- 안정성.
- 보안성.
- 결정성.
- 신뢰성.
- 신속성.
- 단순성.
GitLab CI/CD는 시작 이래 이 원칙에 따라 운영돼 왔고, 이 원칙은 GitLab 과 사용자 모두에게 도움이 되고 있습니다. 예를 들면 다음과 같습니다.
- GitLab CI/CD가 전달하는 피드백과 플랫폼이 생성하는 데이터는 정확해야 합니다.
job이 실패했는데 성공했다고 알린다면 심각한 악영향이 발생할 수 있습니다. - 피드백은 사용자가 필요로 할 때 제공돼야 하며, 엔지니어가 필요로 할 때 데이터가 예기치 않게 사라져서는 안 됩니다.
- 플랫폼이 안전하지 않아 자격 증명이나 시크릿이 유출된다면 나머지는 모두 의미가 없습니다.
- 사용자가 CI/CD 설정 형태로 전제 조건을 제공하면 파이프라인이 실행될 때마다 결과가 결정적이어야 합니다. 그렇지 않으면 플랫폼을 신뢰할 수 없게 됩니다.
- 빠르고 사용하기 단순하며 UX가 뛰어나면 사용자에게 큰 도움이 됩니다.
Verify에서 구현하기#
최적화 전 측정과 데이터 기반 의사 결정#
측정할 수 없는 대상을 최적화하기는 매우 어렵습니다. 측정하지 않으면 성공했는지, 성공이 얼마나 유의미했는지 알 수 없습니다. 성능이나 안정성 개선 작업을 한다면 최적화하기 전에 먼저 측정해야 합니다.
가장 좋은 측정 방법은 Prometheus 메트릭을 추가하는 것입니다. 카운터, 게이지, 히스토그램은 근사치 결과를 빠르게 얻기에 좋은 수단입니다. 다만 꼬리 지연 시간을 측정하기에 가장 좋은 방법은 아닙니다. Prometheus 메트릭, 특히 히스토그램은 대체로 근사치입니다.
어떤 동작이 얼마나 느릴 수 있는지, 요청 페이로드가 얼마나 클 수 있는지처럼 꼬리 지연 시간을 측정해야 한다면 애플리케이션 로그를 직접 추가하는 방안을 고려하고 항상 구조화된 로깅을 사용합니다.
코드 실행 경로가 실제로 어떤 모습인지 파악하려면 프로파일링과 플레임그래프를 활용하는 것이 유용합니다.
단순한 해결책 추구와 영리한 해결책 회피#
무언가를 더 빨리 내놓기 위해 영리한 해결책을 쓰고 싶어질 때가 있습니다. GitLab은 영리한 코드를 내보내지 않으려 합니다. 그런 코드는 대개 장기적으로 이해하고 유지 보수하기가 더 어렵기 때문입니다. 대신 코드베이스를 발전시키기 쉽게 하고 기여 장벽을 낮게 유지하는 지루한 해결책에 집중합니다. 가능한 한 단순한 해결책을 찾는 것이 목표입니다.
지루한 해결책과 쉬운 해결책의 구분#
지루한 해결책은 쉬운 해결책과 혼동될 때가 있습니다. 실제로는 그 반대인 경우가 많습니다. 쉬운 해결책이 단순하지 않을 수 있습니다. 예를 들어 빠르게 구현할 수 있는 아주 작은 기능을 추가하려고 복잡한 새 라이브러리를 포함하는 경우, 직접 만드는 것보다 라이브러리를 포함하는 편이 쉽지만 제품에 많은 복잡성을 들여오게 됩니다.
반대로 단순하고 테스트가 잘 되어 있으며 잘 유지 보수되는 라이브러리가 있는데도 해결책을 과도하게 설계하는 일도 가능합니다. 그런 경우에는 라이브러리를 쓰는 편이 합리적일 수 있습니다. GitLab은 단순한 해결책과 쉬운 해결책 사이에서 늘 균형을 잡고 있으며, 그 균형점을 찾는 것이 중요하다고 봅니다.
"단순함"은 "유연함"과 상호 배타적이지 않습니다#
단순한 것을 만든다고 해서 더 진보적이고 유연한 해결책을
제공하지 않는다는 뜻은 아닙니다. .gitlab-ci.yml 설정 작성의
복잡도가 단계적으로 확장되는 것이 좋은 예입니다. 예를 들어
환경 이름은 다음과 같이 단순한 방식으로 정의할 수 있습니다.
deploy:
environment: production
script: cap deploy
그리고 environment 키워드는 더 높은 유연성을
제공하는 다음 단계의 설정으로 확장할 수도 있습니다.
deploy:
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://prod.example.com
script: cap deploy
이런 접근 방식은 신규 사용자를 플랫폼의 복잡성으로부터 보호하면서도, 필요할 때는 더 깊이 들어갈 수 있게 합니다. 이 방식은 다른 여러 기술 구현에도 적용할 수 있습니다.
관찰 가능한 구현#
GitLab은 DevOps 플랫폼입니다. DevOps는 기업이 더 효율적으로 일하고 더 나은 결과를 얻도록 돕기 때문에 GitLab은 DevOps를 확산시키고 있습니다. DevOps 문화의 중요한 구성 요소 하나는 자신이 만드는 기능과 코드에 대해 오너십을 갖는 것입니다. 기능이 프로덕션 환경에서 어떻게 동작하는지 모른다면 오너십을 갖기가 매우 어렵습니다.
그래서 GitLab은 기능과 코드를 관찰 가능하게 만들고자 합니다. 작성자가 해당 기능이나 코드가 프로덕션 환경에서 얼마나 잘, 또는 얼마나 나쁘게 동작하는지 이해할 수 있는 방식으로 작성해야 합니다. 보통은 Prometheus 메트릭과 애플리케이션 로거를 적절히 조합해 이를 달성합니다.
TODO Prometheus 메트릭을 언제 쓰고 로거를 언제 쓸지 문서화합니다. 히스토그램과 카운터에 대해 몇 문장 작성합니다. 점진적 롤아웃을 진행할 때 메트릭이 갖는 중요성을 강조하는 몇 문장을 작성합니다.
고객 데이터 보호#
CI/CD 플랫폼이 생성하는 데이터를 내구성 있게 유지하는 일은 중요합니다. GitLab은 사용자와 고객이 CI/CD에서 생성한 데이터가 중요하며 반드시 보호해야 한다고 봅니다. 이 데이터가 중요한 이유는 중요한 정보를 담을 수 있다는 점만이 아닙니다. GitLab에는 컴플라이언스와 감사 책임도 있습니다.
따라서 데이터베이스에서 데이터를 영구적으로 제거하는 마이그레이션을 작성하거나 새 보존 정책을 정의할 때는 각별히 주의해야 합니다.
일반적인 규칙으로, 데이터베이스나 파일 시스템, 오브젝트 스토리지에서 데이터를 제거하는 코드를 작성할 때는 변경 사항을 다른 사람에게 한 번 더 확인받아야 합니다. 새 보존 정책을 정의할 때는 PM 및 EM과 다시 확인해야 합니다.
설계 리뷰#
파이프라인 처리와 CI/CD 상태 전환을 담당하는 하위 시스템을 설계할 때는 가능한
한 이른 시점에 Verify 메인테이너(@gitlab-org/maintainers/cicd-verify)에게
설계에 대한 추가 의견을 요청하고, 다른 사람도 같은 절차를 따르도록 합니다.
Verify 메인테이너에게 설계를 리뷰받으면 놓쳤을 수 있는 맹점을 가능한
한 이른 시점에 파악할 수 있고, 더 나은 해결책으로 이어지기도 합니다.
개발 작업을 시작하기 전에 설계를 리뷰받으면 머지 리퀘스트 리뷰도 더 효율적으로 진행됩니다. Verify 메인테이너가 설계를 리뷰한 상태라면 메인테이너 리뷰 단계에서 크게 다른 의견이나 변경 요청을 만날 가능성이 줄어듭니다. 그 결과 머지 리퀘스트를 더 빨리 머지할 수 있습니다.
변경 사항 리뷰#
머지 리퀘스트가 리뷰 준비를 마치면 리뷰어를 지정하고 이어서 메인테이너를 지정해야 합니다. 변경의 복잡도에 따라, 변경하려는 코드베이스 영역을 가장 잘 아는 사람을 참여시키는 편이 좋을 수 있습니다. Verify에는 도메인 전문가와 메인테이너가 많이 있으며, Reviewer Roulette가 지정한 리뷰어나 메인테이너가 해당 변경에 대한 컨텍스트를 충분히 갖고 있는지 확신이 서지 않는다면 이들에게 코드 리뷰를 요청해도 전혀 문제가 없습니다.
Reviewer Roulette는 유용한 제안을 제공하지만, 적합한 리뷰어를 지정하는 일이 중요한 만큼 매번 자동으로 처리해서는 안 됩니다. 변경하려는 영역을 전혀 모르는 사람을 지정하는 것은 적절하지 않을 수 있습니다. 그런 경우 피드백이 코드 스타일과 문법에 그칠 수 있기 때문입니다. 변경의 복잡도와 영향 범위에 따라, 적합한 사람을 리뷰어로 지정하는 일이 매우 중요할 수 있습니다.
누구를 지정해야 할지 모른다면 git blame을 확인하거나
#s_verify Slack 채널(GitLab 팀원 전용)에 문의합니다.
리뷰어의 추가 주의와 별도의 리뷰어가 필요한 변경 및 머지 리퀘스트는 두 종류입니다.
- 파이프라인 / 스테이지 / 빌드 상태 관련 코드를 변경하는 머지 리퀘스트.
- 인증 / 보안 기능 관련 코드를 변경하는 머지 리퀘스트.
두 경우 모두 엔지니어는 메인테이너와 도메인 전문가에게 리뷰를 요청해야 합니다. 메인테이너가 곧 도메인 전문가라면 다른 사람을 한 명 더 참여시키는 것을 권장합니다.
점진적 롤아웃#
메인테이너가 머지 리퀘스트를 머지하고 나면, 이를 사용자와 더 넓은 커뮤니티에 릴리스할 차례입니다. 보통은 기능 플래그로 진행합니다. 모든 머지 리퀘스트에 기능 플래그가 필요한 것은 아니지만, Verify의 대부분의 머지 리퀘스트에는 기능 플래그가 있어야 합니다.
이 페이지의 권고를 이미 따르고 있다면, 새 코드를 프로덕션 환경에서 관찰 가능하게 만드는 메트릭 몇 개와 로거 몇 개를 이미 추가했을 것입니다. 이제 이 메트릭을 사용해 변경 사항을 점진적으로 롤아웃할 수 있습니다.
일반적인 시나리오는 내부 프로젝트 몇 곳에서 기능 몇 개를 활성화하고 메트릭이나 로거를 관찰하는 방식입니다. Elastic 또는 Kibana에서 로그를 수집하는 데 약간의 지연이 있을 수 있다는 점에 유의합니다. 내부 프로젝트에서 기능이 잘 동작하는 것을 확인한 다음에는 다른 프로젝트를 대상으로 점진적 롤아웃을 시작할 수 있습니다.
"시간 비율" 방식의 점진적 롤아웃은 피합니다. 이 방식은 오류가 발생하기 쉬우며, 특히 코드베이스의 여러 지점에서 기능 플래그를 확인하면서 확인 결과를 한 곳에 메모이제이션하지 않은 경우에 그렇습니다.
우주를 붕괴시키지 않기 위한 주의#
초기 GitLab Contributes 행사 중 하나에서 CI/CD 파이프라인, 스테이지, job 상태를 정확하게 유지하는 일의
중요성을 논의한 적이 있습니다. 당시 초기 고객
중 한 곳이 개발하던 소프트웨어와 관련해 가상의 시나리오를 검토했습니다.
파이프라인이 통과했다고 표시했지만 그 데이터가 정확하지 않아 실제로는 유효하지 않은 소프트웨어가 배포됐고, 그 GitLab CI/CD 버그 때문에 대형 강입자 충돌기(LHC)에 배포된 소프트웨어가 오작동하는 상황을 가정합니다. 이런 문제는 LHC의 오작동을 유발할 수 있고, 그로 인해 새로운 입자가 생성돼 우주가 붕괴할 수도 있습니다.
GitLab CI/CD 상태 처리의 작은 버그가 낳는 결과로는 상당히 바람직하지 않은 결말입니다. CI/CD 상태와 관련된 작업을 할 때는 각별히 주의합니다. 우주를 붕괴시켜서는 안 됩니다.
이는 극단적이고 일어날 가능성이 낮은 시나리오지만, 정확하지 않은 데이터를 제시하면 나비 효과를 통해 수많은 문제를 일으킬 수 있습니다. 훨씬 더 일어나기 쉬우면서 파괴적인 결과를 낳을 수 있는 시나리오도 많습니다. GitLab CI/CD는 의료, 항공, 자동차 소프트웨어를 개발하는 기업에서 사용되고 있습니다. Continuous Integration은 소프트웨어 엔지니어링의 미션 크리티컬한 구성 요소입니다.
완료의 정의#
Verify에서는 개발 팀의 완료의 정의를 따릅니다. 또한 사용자의 질문에 답하고 문제를 해결할 때 효율성과 DRY 원칙을 유지하고자 합니다.
기존 .gitlab-ci.yml 문법으로 지원되는 해결책이 있어 해결된 이슈에 대해서는
ci-sample-projects
그룹에 해결책을 보여 주는 프로젝트를 생성합니다.
해당 프로젝트에는 다음이 있어야 합니다.
- 단순한 제목.
- 명확한 설명.
- 다음을 담은
README.md:- 해결된 이슈로 연결되는 링크. 질문이 생기면 해결된 이슈에서 함께 논의하도록 사용자를 안내해야 합니다.
- 관련 문서로 연결되는 링크.
- 예제가 무엇을 하는지에 대한 상세한 설명.