Verify 단계 코드베이스에 기여하기

Verify에서 무엇에 참여하고 있나요?

Verify 단계는 GitLab 제품에 통합된 포괄적인 Continuous Integration 플랫폼에 참여하고 있습니다. 우리의 목표는 사용자들이 가정을 검증하고, CI/CD 구성에서 정의된 기준에 따라 그들을 확인하여 탁월한 기술 및 비즈니스 결정을 내릴 수 있도록 하는 것입니다. 이는 유닛 테스트, 종단 간 테스트, 벤치마킹, 성능 유효성 검사, 코드 커버리지 강제 등이 될 수 있습니다.

GitLab CI/CD로 제공되는 피드백을 통해 사용자는 성공을 위해 필요한 기술적 및 비즈니스적 선택에 대해 명확한 결정을 내릴 수 있습니다. 왜 Continuous Integration이 미션 크리티컬 제품인가요?

GitLab CI/CD는 사용자 및 고객에게 피드백을 제공하기 위한 플랫폼입니다.

사용자들은 지속적 통합 구성 파일인 .gitlab-ci.yml을 기여하여, 각 커밋을 푸시하거나 파이프라인을 트리거할 때 매우 중요한 질문에 대한 답변을 찾아야 합니다.

이러한 질문에 대답하지 못하거나, 더 나쁜 경우에는 틀린 답변을 제공하는 것은 사용자가 잘못된 결정을 내릴 수 있게 할 수 있습니다. 잘못된 결정은 매우 심각한 결과를 초래할 수 있습니다.

우리 CI/CD 플랫폼의 핵심 원칙

플랫폼에서 생산된 데이터는 다음과 같아야 합니다:

  1. 정확하고,
  2. 지속적이며,
  3. 접근 가능해야 합니다.

플랫폼 자체는 다음과 같아야 합니다:

  1. 신뢰할 수 있으며,
  2. 안전해야 하며,
  3. 결정론적이어야 합니다.
  4. 신뢰할 수 있는,
  5. 빠르고,
  6. 간단해야 합니다.

우리는 GitLab CI/CD 초기부터 이러한 원칙을 준수해왔고, 이러한 원칙은 우리와 우리 사용자에게 잘 들어맞고 있습니다. 이러한 원칙의 몇 가지 예는 다음과 같습니다:

  • GitLab CI/CD로부터 제공되는 피드백 및 플랫폼에서 생성된 데이터는 정확해야 합니다. 작업이 실패하고 사용자에게 성공적이었다고 알리는 경우, 심각한 부정적인 결과가 발생할 수 있습니다.
  • 피드백은 사용자가 필요할 때 사용 가능해야하며, 엔지니어들이 필요할 때 데이터가 예상하지 못한 방식으로 사라지면 안 됩니다.
  • 플랫폼이 안전하지 않거나, 자격 증명이나 비밀이 유출될 경우 모든 것은 의미가 없습니다.
  • 사용자가 CI/CD 구성의 형태로 선행 조건들을 제공할 때, 결과는 각 파이프라인 실행마다 결정적이어야 합니다. 그렇지 않으면, 플랫폼은 믿을 수 없게 될 수 있습니다.
  • 빠르고, 사용하기 쉽고, 훌륭한 UX를 갖추면 사용자에게 잘 봉사할 것입니다.

Verify에서 사물을 구축하기

최적화하기 전에 측정하고 데이터 기반 결정을 내리기

측정할 수 없는 것을 최적화하기는 매우 어렵습니다. 성공했는지, 또는 성공이 얼마나 중요했는지 어떻게 알 수 있을까요? 성능이나 신뢰성 향상에 작업 중이라면, 최적화하기 전에 측정하는 것이 중요합니다.

측정하는 가장 좋은 방법은 Prometheus 지표를 추가하는 것입니다. 카운터, 게이지 및 히스토그램은 빠르게 대략적인 결과를 얻는 좋은 방법입니다. 유감스럽게도, 이것은 꼬리 지연 시간을 측정하는 데는 최적의 방법은 아닙니다. 특히 히스토그램인 Prometheus 지표들은 보통 근사값입니다.

무언가가 얼마나 느릴 수 있는지 또는 요청 페이로드가 얼마나 큰지 같은 꼬리 지연 시간을 측정해야 할 경우, 사용자 정의 애플리케이션 로그를 추가하고 항상 구조화된 로깅을 사용하는 것을 고려해보세요.

코드 실행 경로를 정말로 이해하려면 프로파일링과 플레임그래프를 사용하는 것이 유용합니다!

간단한 해결책에 노력하기, 간략한 해결책 피하기

때로는 더 빨리 무언가를 전달하기 위해 간략한 해결책을 사용하는 것이 유혹스러울 수 있습니다. 우리는 간단한 해결책을 찾아내어 코드베이스를 진화시키기 쉽게 유지하고 참여 장벽을 낮추는 것을 피하기 위해 난처한 코드를 배송하는 것을 원하지 않습니다. 가능한 한 간단한 해결책을 찾고자 합니다.

간단한 해결책을 쉬운 해결책과 혼동하지 마세요

간단한 해결책을 쉬운 해결책과 혼동하기 쉽습니다. 매우 자주 정반대가 사실일 수 있습니다. 간단한 해결책이 간단하지 않을 수 있습니다 - 예를 들어, 매우 작은 기능을 추가하기 위해 복잡한 새 라이브러리가 포함될 수 있습니다 - 이 라이브러리를 포함하는 것은 이것을 구축하는 것보다는 더 쉽지만, 제품에 많은 복잡성을 가져올 것입니다.

반면에, 단순하고, 테스트가 완료되었고, 잘 유지되는 라이브러리가 있는 경우에도 과도하게 엔지니어링하는 것이 가능합니다. 이러한 경우에는 라이브러리를 사용하는 것이 타당할 수 있습니다. 우리는 항상 간단하고 쉬운 해결책을 균형 있게 유지하고 있는 것을 알아야 합니다.

“간단함”이 “유연성”과 상반되는 것은 아닙니다

간단한 것을 만드는 것은 더 고급 및 유연한 해결책이 없을 거라는 것을 의미하지 않습니다. 여기 좋은 예가 있습니다. .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를 보급하는 이유는 기업이 더 효율적이고 더 나은 결과를 달성하도록 돕기 때문입니다. DevOps 문화의 중요한 구성 요소 중 하나는 구축 중인 기능 및 코드에 대한 소유권을 가져야 한다는 것입니다. 제품 환경에서 기능 또는 코드의 동작을 이해하는 것이 얼마나 잘 또는 나쁘게 동작하는지 작성하는 방식으로 되어야 합니다. 보통 이는 적절한 조화의 프로메테우스 메트릭 및 애플리케이션 로거를 도입함으로써 이루어집니다.

TODO 언제 프로메테우스 메트릭을 사용해야하며, 언제 로거를 사용해야하는지 문서화하세요. 히스토그램 및 카운터에 대한 간략한 설명을 작성하세요. 점진적인 롤아웃시 메트릭의 중요성을 강조하는 몇 가지 문장을 작성하세요.

고객 데이터 보호

우리의 CI/CD 플랫폼에서 생성된 데이터를 비파괴적으로하는 것은 중요합니다. 사용자와 고객에 의해 생성된 데이터가 중요하며 보호해야 함을 인식합니다. 이 데이터는 중요한 정보를 포함할 수 있기 때문뿐만 아니라, 우리는 규정 준수와 감사 책임이 있기 때문에 보호해야 합니다. 따라서 데이터베이스, 파일 시스템 또는 객체 저장소에서 데이터를 제거하는 코드를 작성할 때는 항상 다른 시각을 얻어야 합니다. 새로운 유지 정책을 정의할 때는 제품 관리자 및 엔지니어 관리자들과 반드시 확인해야 합니다.

디자인 검토 받기

파이프라인 처리 및 CI/CD 상태 전환을 위한 하위 시스템을 설계할 때, 가능한 빨리 Verify 유지자(@gitlab-org/maintainers/cicd-verify)로부터 디자인에 대한 추가 의견을 요청하고, 다른 사람들에게도 같은 일을 요구하세요. Verify 유지자에 의해 디자인을 검토받는 것은 가능한 빨리 간과한 무언가를 식별하고 더 나은 해결책으로 이끌 가능성이 있습니다.

개발 작업을 시작하기 전에 디자인을 검토받음으로써 머지 요청 리뷰를 더 효율적으로 만들어줍니다. 디자인이 Verify 유지자에 의해 검토되었다면 유지자 리뷰 중에 의견이 현저히 다르거나 변경 요청을 만날 가능성이 적을 것입니다. 결과적으로 머지 요청을 더 빨리 병합할 수 있을 것입니다.

변경 내용 검토받기

머지 요청이 리뷰를 위해 준비되었을 때 리뷰어 및 유지자를 지정해야 합니다. 변경의 복잡성에 따라 코드베이스 영역에 대해 가장 많은 지식을 갖고 있는 사람들을 참여시키고 싶을 수 있습니다. Verify에는 많은 도메인 전문가 및 유지자가 있으며, 리뷰어 룰렛이 지정한 리뷰어 또는 유지자가 변경 사항에 대한 충분한 컨텍스트를 갖고 있는지 확실치 않을 경우 코드를 리뷰할 것을 요청하는 것은 절대적으로 허용되는 것입니다.

리뷰어 룰렛은 유용한 제안을 제공하지만, 올바른 리뷰어를 지정하는 것이 중요하기 때문에 매번 자동으로 수행해서는 안됩니다. 업데이트하는 영역에 대해 아무것도 알지 못하는 사람을 지정하는 것은 의미가 없을 수 있습니다. 변경의 복잡성과 영향에 따라 올바른 사람들을 지정하여 변경 내용을 검토하는 것이 매우 중요할 수 있습니다.

지정할 대상이 모르는 경우에는 git blame을 참고하거나 #s_verify Slack 채널에서 (GitLab 팀 멤버 전용) 질문하세요.

추가적인 검토 및 리뷰어가 필요한 변경 내용 / 머지 요청은 두 가지 유형이 있습니다:

  1. 파이프라인 / 스테이지 / 빌드 상태 주변의 코드를 변경하는 머지 요청
  2. 인증 / 보안 기능 주변의 코드를 변경하는 머지 요청

양쪽 경우 모두, 엔지니어들은 유지자 및 도메인 전문가로부터 리뷰를 요청하는 것이 예상됩니다. 유지자가 도메인 전문가라면, 다른 사람을 참여시키는 것이 권장됩니다.

점진적 롤아웃

유지자에 의해 머지된 후에는 사용자 및 더 넓은 커뮤니티에게 릴리스할 시간입니다. 보통 우리는 이를 feature flag를 사용하여 수행합니다. 모든 머지 요청이 feature flag를 필요로 하는 것은 아니지만, Verify의 대부분 머지 요청은 feature flags를 가져야 합니다.

이 페이지의 충고를 이미 따른 경우, 새로운 코드를 프로덕션 환경에서 살펴볼 수 있도록 몇 가지 메트릭 및 로거를 추가했을 것입니다. 이제 이러한 메트릭을 사용하여 변경 사항을 점진적으로 롤아웃할 수 있습니다!

전형적인 시나리오는 몇 가지 내부 프로젝트에서 몇 가지 기능을 활성화하면서 메트릭이나 로거를 관찰하는 것입니다. Elastic이나 Kibana에 로그를 흡수하는 데 약간의 지연이 있을 수 있음을 유의하세요. 내부 프로젝트에서 기능이 잘 작동하는 것을 확인한 후 다른 프로젝트에 대한 점진적인 롤아웃을 시작할 수 있습니다.

시간의 퍼센트로 점진적인 롤아웃을 사용하는 것은 피하세요. 이것들은 코드베이스의 몇 군데에서 feature flag를 확인하고 결과를 단일 위치에 메모화하지 않았을 때 특히 오류가 발생하기 쉽습니다.

우주를 붕괴시키지 마세요

GitLab Contributes 행사 중에 CI/CD 파이프라인, 스테이지 및 작업 상태의 중요성에 대한 토론이 있었습니다. 우리는 이른 시기 고객 중 한 곳에서 빌드된 소프트웨어와 관련된 가정적인 시나리오를 고려했습니다.

만약 GitLab CI/CD에서 파이프라인이 통과되었다고 보이지만 이 데이터가 정확하지 않았고 실제로 배포된 소프트웨어가 유효하지 않았을 경우에 라지 하드론 충돌기(LHC)에 영향을 미친다면 어떻게 될까요? 이와 같은 문제는 LHC의 오작동을 일으킬 수 있고, 새로운 입자를 생성하여 우주를 붕괴시킬 수 있습니다.

이것은 CI/CD 상태 처리의 작은 버그로 인한 매우 바람직하지 않은 결과가 될 것입니다. CI/CD 상태에 작업할 때 추가로 신경을 써야 합니다. 우리는 우리의 우주를 붕괴시키고 싶지 않습니다!

이는 극단적이고 발생 가능성이 낮은 시나리오이지만, 정확하지 않은 데이터를 제시하는 것은 잠재적으로 나비 효과를 통해 수많은 문제를 유발할 수 있습니다. 기업들이 의료, 항공 및 자동차 소프트웨어를 개발하는 데 GitLab CI/CD를 사용하고 있습니다. 지속적 통합은 소프트웨어 엔지니어링의 중요한 부분입니다.

완료의 정의

Verify에서는 개발팀의 완료 정의를 따릅니다. 또한 사용자들에게 대답하고 문제를 해결하는 것이 효율적이고 DRY하게 유지하기를 원합니다.

기존 .gitlab-ci.yml 구문을 지원하는 해결책으로 해결된 문제에 대해서는, 그 해결책이 나타나는 프로젝트를 ci-sample-projects 그룹에 만들어야 합니다.

프로젝트는 다음을 포함해야 합니다:

  • 간단한 제목.
  • 명확한 설명.
  • 다음 항목을 포함하는 README.md:
    • 해결된 이슈로의 링크. 만약 질문이 생기면 사용자들이 해결된 이슈에서 협업할 수 있도록 안내하세요.
    • 관련 문서로의 링크.
    • 예시가 무엇을 하는지에 대한 상세한 설명.