This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
accepted @nolith @glopezfernandez @marin devops data stores 2021-11-18

객체 리포지터리: direct_upload 통합

요약

GitLab은 데이터베이스 레코드, Git 리포지터리 및 사용자가 업로드한 파일(여기서는 파일 리포지터리로 참조됨)의 세 가지 클래스의 사용자 데이터를 저장합니다.

파일 리포지터리에 대한 사용자 및 기여자 경험은 크게 향상될 여지가 있습니다.

  • 초기 GitLab 구성 UX에서는 1개가 아닌 13개의 버킷을 생성하고 설정해야 합니다.
  • 파일 리포지터리를 사용하는 기능은 로컬 리포지터리와 객체 리포지터리 모두에 대해 생각해야 하므로 마찰과 복잡성을 야기합니다. 이로 인해 종종 기능이 손상되고 보안 문제가 발생합니다.
  • 파일 리포지터리에서 작업하는 기여자는 종종 Workhorse, Omnibus 및 클라우드 네이티브 GitLab(CNG)용 코드를 작성해야 합니다.

문제 정의

객체 리포지터리는 공유, 분산, 고가용성(HA) 파일 리포지터리의 기본 컴포넌트입니다.

우리는 시간이 지남에 따라 객체 리포지터리에 대한 지원을 애플리케이션 전반에 걸쳐 구축하여 여러 가지 반복에서 특정 문제를 해결했습니다. 이로 인해 개발(새로운 기능 및 버그 수정)에서 설치에 이르기까지 전반적으로 복잡성이 증가했습니다.

  • 새로운 GitLab 설치에 필요한 버킷은 그룹마다 하나씩 필요하기 때문에, 각 그룹의 기능에 대한 버킷을 작성하고 설정해야 합니다. 이는 설치 경험 및 새로운 기능 채택에 영향을 미치며, 단조로운 솔루션에서 멀어지도록 합니다.
  • 클라우드 네이티브 GitLab의 릴리스에는 NFS 공유 리포지터리의 제거와 전역적으로 활성화되지 않은 채로 여러 유형의 업로드로 이루어진 직접 업로드 기능의 개발이 필요했습니다.
  • 현재, GitLab은 로컬 리포지터리와 객체 리포지터리를 모두 지원합니다. 로컬 리포지터리는 단일 상자 설치에서만 또는 NFS와 함께 동작하는데에만 사용되며, 이는 더 이상 우리가 사용자에게 권장하지 않습니다. 또한, GitLab.com에서 사용되지 않습니다.
  • 모든 컴포넌트와 흐름을 이해하는 것은 매우 복잡합니다. CarrierWave, Fog, Go S3/Azure SDK와 같은 모든 것이 사용되며, 이로 인해 테스트가 복잡해집니다.
  • Fog와 CarrierWave는 공식 지원되는 SDK(AWS S3 SDK와 같은)만큼 유지되지 않으므로, 일반적으로 무료인 요청된 고객 기능을 지원하기 위해 해당 도구를 유지하거나 monkey patch해야 합니다. (예: 이슈 #242245)
  • 많은 경우, 무분별하게 객체 리포지터리 파일을 복사합니다. (예: 이슈 #285597). 큰 파일(예: LFS 및 패키지)은 완료하는 데 느리거나 전혀 작동하지 않습니다.

현재 상황 대비 개선 사항

다음은 객체 리포지터리 구현에 영향을 주는 통합 점을 해결하기 위해 취할 수 있는 주요 방향의 간단한 설명입니다.

유튜브 비디오로도 확인하실 수 있습니다. 이 비디오는 객체 리포지터리 워킹 그룹을 위해 녹화되었습니다.

MinIO를 제공하여 GitLab 아키텍처 간단화

초기에 객체 리포지터리 지원은 Premium 기능이었으며 CE 배포의 일부가 아니었습니다. 따라서 로컬 리포지터리와 객체 리포지터리를 모두 지원해야 했습니다.

로컬 리포지터리에서는 컴포넌트 간의 공유 리포지터리라는 가정이 있습니다. 이는 HA가 없는 단일 상자 설치 또는 더 이상 우리가 추천하지 않는 NFS를 사용하여 달성할 수 있습니다.

우리는 객체 리포지터리에서 테스트 갭이 있습니다. 이것은 Workhorse와 MinIO를 필요로 하며, 이들은 우리의 파이프라인에 없기 때문에 너무 많은 것이 목업 구현으로 대체됩니다. 또한 CI 및 로컬 개발에서 공유 디스크의 존재는 종종 끊어진 구현을 숨깁니다. 그런 구현은 HA 환경에 배포할 때까지 숨겨졌다가 들통합니다.

우리가 고려할 수 있는 한 가지 사항은 제품의 일부로 MinIO를 제공하는 것입니다. 이로써 클라우드와 로컬 설치 사이의 차이를 줄일 수 있으며, 파일 리포지터리를 단일 기술에 표준화할 수 있습니다.

로컬 디스크 작업의 제거로 개발 복잡성이 줄어들고 로컬 리포지터리에 사용자 제공 데이터를 더 이상 기록하지 않으므로 여러 안전 공격 벡터에 대한 복잡성도 줄어들 것입니다.

이러한 노력은 이 이픽에서 설명되어 있습니다.

특정 타사 기술을 고려하기 전에 오픈 소스 소프트웨어 라이선스 측면에서 유의해야 합니다. 2021년 4월 23일 기준으로, MinIO는 AGPL v3 라이선스에 따라 제공됩니다. 이 설계안에서 제안된 대로 MinIO를 제품에 제공할 여부를 결정하기 전에 GitLab Legal에 상의해야 합니다.

기본적으로 모든 업로드에 대해 직접 업로드 활성화

각 그룹의 기능마다 별도의 버킷이 필요하기 때문에 모든 곳에서 직접 업로드를 활성화하지 않습니다. 새로운 업로드에 기여하려면 Ruby on Rails와 Go에서 모두 코드를 작성해야 합니다.

독립된 버킷이 없는 새로운 기능을 구현하려면 해당 개발자는 Omnibus 및 CNG에서 Merge Request를 만들어야 하며, 우리 자체 환경에서 새로운 버킷을 구성하기 위해 SRE들과 협의해야 합니다.

이로 인해 사용자는 GitLab을 재구성하고 인프라에서 새로운 버킷을 준비해야 하므로 기능 채택이 늦어지고, 각 기능마다 초기 설치가 더 복잡해집니다.

하나의 버킷으로 모든 객체 유형에 대한 단일 스토리지 연결 구성을 가능하게 하는 기본적인 직접 업로드를 구현함으로써 새로운 기능을 배포하기 위해 필요한 Merge Request 수를 4개에서 1개로 줄일 수 있습니다. 또한, 버킷은 항상 동일하게 유지되므로 SRE 개입이 필요 없어집니다.

이로써 개발 및 리뷰 프로세스가 간소화되며 GitLab 구성 파일도 간소화됩니다. 그리고 모든 사용자는 인프라 과정없이 즉시 새로운 기능에 액세스할 수 있게 됩니다.

객체 리포지터리 코드 간소화

우리의 구현은 모든 객체 리포지터리 클라이언트가 타사 라이브러리인 3rd-party 프레임워크를 기반으로 작성되었습니다. 불행히도 그 중 일부는 유지관리되지 않았습니다. 5GB 규모의 Git LFS 객체를 밀어 넣을 수 없는 고객도 있지만, 3rd-party 라이브러리로 구현된 이러한 중요한 기능으로 인해 이 문제를 해결하는 데 시간이 많이 소요되었으며, 외부 유지보수자에 의존하여 수정 사항을 Merge하고 릴리스하기도 합니다.

직접 업로드를 도입하기 전의 CarrierWave 라이브러리는 “루비 애플리케이션에서 파일을 간단하고 매우 유연하게 업로드하는 방법을 제공하는 gem” 였습니다. 그러나 이제는 우리의 사용 사례가 아니며 Workhorse에서 파일을 업로드하며 CarrierWave의 내부를 패치하여 직접 업로드를 지원해야 했습니다.

CarrierWave의 제거와 새로운 간소화된 내부 업로드 API에 대한 간략한 제안은 이 이슈 코멘트에서 설명되어 있습니다.

이상적으로는 Go와 Ruby에서 객체 리포지터리 클라이언트를 중복해서 작성할 필요가 없을 것입니다. CarrierWave를 제거함으로써 공급자 S3 호환성 수준이 충분하지 않을 때 공식으로 지원되는 네이티브 클라이언트를 활용할 수 있습니다.

반복 작업

이 섹션에서는 가능한 반복 작업 디렉터리을 나열합니다. 이는 최종 도로맵이 아니며 Object Storage 작업 그룹을 위한 대화 시작입니다.

  1. CarrierWave 없이 승인을 위한 새로운 catchall 버킷과 통합 내부 API를 생성합니다.
  2. Omnibus에 MinIO를 제공합니다(CNG 이미지에 이미 포함되어 있음).
  3. 모든 지원되는 구성을 커버할 수 있도록 GitLab-QA 확장합니다.
  4. 로컬 디스크 액세스를 폐기합니다.
  5. 여러 버킷으로 구성을 폐기합니다.
  6. 버킷 간 이관을 구현합니다.
  7. 현재 CarrierWave 업로드를 새로운 구현으로 이관합니다.
  8. 다음 주요 릴리스에서: 로컬 디스크 액세스 및 여러 버킷 구성 지원을 제거합니다.

현재 반복 작업 계획의 이점

현재 계획은 첫 번째 단계부터 현실적인 이점을 제공하도록 설계되었습니다.

catchall 버킷을 소개함으로써 현재 직접 업로드 대상이 아닌 모든 업로드가 혜택을 받으며, 새로운 기능은 단일 Merge Request과 함께 제공될 수 있습니다.

MinIO를 Omnibus와 함께 제공하면 새로운 설치를 객체 리포지터리로 기본 설정할 수 있으며, Omnibus가 버킷을 만드는 작업을 처리할 수 있습니다. 이는 쿠버네티스 외부의 HA 설치를 단순화할 것입니다.

그런 다음 각 CarrierWave 업로더를 새로운 구현으로 이관하여 GitLab 설치가 하나의 버킷만 필요로 할 때까지 진행할 수 있습니다.

추가 독서 자료