Omnibus GitLab 아키텍처 및 컴포넌트

Omnibus GitLab은 Chef의 Omnibus 프로젝트의 사용자 지정된 포크로, 사용자의 컴퓨터에서 GitLab을 구성하는 작업을 수행하기 위해 Chef 컴포넌트 및 레시피와 같은 Chef 구성요소를 사용합니다. Omnibus GitLab.com 리포지터리에는 Omnibus GitLab의 모든 필수 컴포넌트가 호스팅되어 있습니다. 이에는 패키지를 빌드하는 데 필요한 Omnibus의 일부인 구성 및 프로젝트 메타데이터, 그리고 설치 후 사용자 컴퓨터에서 사용되는 Chef 관련 컴포넌트가 포함됩니다.

Omnibus-GitLab 컴포넌트

이러한 컴포넌트들에 대한 체계적인 비디오 안내는 YouTube에서 확인할 수 있습니다.

소프트웨어 정의

GitLab 프로젝트 정의 파일

Omnibus 아키텍처의 주요 컴포넌트는 프로젝트 세부 정보 및 외부 소프트웨어 및 라이브러리와의 의존성 관계를 나열하는 프로젝트 정의 파일입니다.

프로젝트 정의 파일의 주요 컴포넌트는 다음과 같습니다.

  • 프로젝트 메타데이터: 프로젝트 이름 및 설명과 같은 속성을 포함합니다.
  • 프로젝트의 라이선스 세부 정보
  • 외부 도구 및 소프트웨어 디렉터리: GitLab을 빌드하거나 실행하는 데 필요한 외부 도구 및 소프트웨어 디렉터리 및 때로는 해당 메타데이터도 포함됩니다.
  • GitLab 설치에 사용되는 전역 구성 변수: 설치 디렉터리, 시스템 사용자 및 시스템 그룹을 포함합니다.

개별 소프트웨어 정의

Omnibus GitLab은 포함된 형식으로 GitLab 인스턴스의 올바른 작동에 필요한 모든 소프트웨어, 라이브러리 및 이진 파일을 제공하는 포함된 스타일의 배포를 따릅니다.

따라서 Omnibus 아키텍처의 주요 컴포넌트 중 하나는 소프트웨어 정의 및 구성입니다. 일반적인 소프트웨어 구성은 다음 부분으로 구성됩니다.

  • 필요한 소프트웨어의 버전
  • 소프트웨어의 라이선스
  • 소프트웨어가 빌드/실행되기 위한 의존성
  • 소프트웨어를 빌드하고 패키지에 포함하기 위해 필요한 명령어

가끔씩, 소프트웨어의 소스 코드는 GitLab과 함께 사용하기 위해 수정되어야 할 수 있습니다. 이는 보안 취약점을 수정하거나 GitLab에 필요한 기능을 추가하거나 GitLab의 다른 컴포넌트와 작동하도록 만들기 위한 것일 수 있습니다. 이를 위해 Omnibus GitLab에는 다양한 소프트웨어의 패치가 저장된 패치 디렉터리가 포함되어 있습니다.

더 확장된 변경을 위해, 필요한 변경 사항을 미러에서 브랜치로 추적하는 것이 더 편리할 수 있습니다. 이를 위한 패턴은 상위 스트림 태그 또는 sha로부터 브랜치를 생성하고 해당 브랜치 지점을 브랜치 이름에 참조하는 것입니다. 예를 들어, Omnibus 코드베이스에서 gitlab-omnibus-v5.6.10은 상위 프로젝트의 v5.6.10 태그를 기반으로합니다. 이를 통해 https://gitlab.com/gitlab-org/omnibus/compare/v5.6.10...gitlab-omnibus-v5.6.10와 같은 비교 링크를 생성하여 어떤 로컬 변경 사항이 있는지 확인할 수 있습니다.

Global GitLab 구성 템플릿

Omnibus GitLab은 사용자의 컴퓨터에 설치될 GitLab 인스턴스의 모든 부분을 구성하는 데 사용할 수 있는 단일 구성 파일과 함께 제공됩니다. 이 구성 파일은 GitLab 인스턴스에 적용될 모든 구성 설정의 권위 있는 소스 역할을 합니다. 이 파일은 GitLab 인스턴스의 일반 설정 및 다양한 컴포넌트에 대한 여러 옵션을 나열합니다. 이 파일의 일반적인 구조는 <component>['<setting>'] = <value> 형식으로 지정된 구성으로 구성되어 있지만, 기본적으로 GitLab의 기본 작동에 필요한 것을 제외하고는 모두 주석 처리되어 있습니다. 사용자는 필요한 경우 이를 주석 해제하고 해당 값을 지정할 수 있습니다.

GitLab Cookbook

이전에 설명한대로 Omnibus GitLab은 cookbooks, attributes 및 리소스와 같은 많은 Chef 컴포넌트를 사용합니다. GitLab EE는 GitLab CE에서 확장되는 별도의 cookbook을 사용하며 EE 전용 컴포넌트를 추가합니다. Omnibus GitLab의 Chef 관련 부분에서 주요 요소는 다음과 같습니다.

기본 속성

기본 속성은 이름에서 알 수 있듯이 구성 파일에 제공된 다른 설정에 대한 기본 값을 지정합니다. 이러한 값은 사용자가 설정에 값을 지정하지 않으면 사용되는 기본 값으로, 최소한의 사용자 조정이 필요한 작동하는 GitLab 인스턴스를 보장합니다.

레시피

레시피는 Omnibus 패키지를 사용하여 GitLab을 설치하는 동안 대부분의 작업을 수행합니다. 이들은 사용자 컴퓨터에 GitLab 생태계의 각 컴포넌트를 설정합니다. 그들은 해당 위치에 필요한 파일, 디렉터리 및 링크를 생성하고, 권한 및 소유자를 설정하며, 필요한 서비스를 구성하고 시작하여 파일이 변경될 때 해당 서비스에 통보합니다. default라고 명명된 마스터 레시피는 입구점 역할을하며 다양한 컴포넌트와 서비스에 대한 모든 필요한 레시피를 호출합니다.

사용자 정의 리소스

사용자 정의 리소스는 레시피 간에 재사용될 수 있는 전역 수준의 매크로로 간주될 수 있습니다. 사용자 정의 리소스의 일반적인 사용 사례로는 일반적인 서비스에 사용되는 포트를 정의하거나 다른 레시피에서 사용될 수있는 중요한 디렉터리를 나열하는 것이 포함됩니다. 다양한 레시피에서 재사용 될 수있는 리소스를 정의합니다.

컴포넌트 구성을위한 템플릿

이전에 언급했듯이 Omnibus GitLab은 GitLab 인스턴스의 모든 컴포넌트를 원하는만큼 수정할 수 있는 단일 구성 파일을 제공합니다. 그러나 다양한 컴포넌트의 ​​구조적 설계는 특정 위치에 상주하는 각 구성 파일을 필요로 할 수 있습니다. 이러한 구성 파일은 사용자가 일반 구성 파일에 지정한 값이나 기본 값에서 생성되어야 합니다. 따라서 Omnibus GitLab에는 그런 구성 파일들의 템플릿이 함께 제공되어 있습니다. 템플릿에는 기본 값이나 사용자로부터의 값을 채워넣을 수 있는 자리 표시자가 있습니다. 레시피는 이러한 템플릿을 완성하여 필요한 위치에 두고 채우는 작업을 수행합니다.

일반 라이브러리 메서드

Omnibus GitLab은 주로 코드 재사용을 목적으로하는 일부 라이브러리 메서드도 함께 제공합니다. 이에는 서비스가 실행 중인지 확인하는 메서드, 파일이 있는지 확인하는 메서드, 다른 컴포넌트와 상호 작용하는 도우미 메서드 등이 포함됩니다. 이들은 종종 Chef 레시피에서 사용됩니다.

Omnibus GitLab에서 사용되는 모든 라이브러리 중에는 주요 GitLab 모듈과 해당 호출 될 구성 컴포넌트 라이브러리가 있는데, 구성 파일에 지정된 설정을 구문 분석하는 역할을합니다. 기본 값 식별, 컴포넌트별 라이브러리를 호출, 기본 값 및 사용자 지정 값을 Merge, 유효성을 검사하고 초기값에 따라 추가 구성을 생성하는 메서드가 포함됩니다. Omnibus GitLab 패키지로 제공되는 모든 최상위 컴포넌트는이 모듈에 추가되어야합니다. 이렇게 하면 구성 파일 및 기본 속성에서 언급되고 올바르게 구문 분석 될 수 있습니다.

runit

GitLab은 runit 레시피를 사용하여 서비스 관리와 지도를 수행합니다. runit 레시피는 OS에서 사용 중인 초기화 시스템을 식별하고 GitLab을 위해 필요한 서비스 파일을 생성하며, 서비스를 활성화하고 다시 로드하는 등 기본 서비스 관리 작업을 수행합니다. runit은 다른 레시피에서 사용할 수 있는 runit_service 정의를 제공하며 자세한 내용은 /files/gitlab-cookbooks/runit를 참조하세요.

서비스

서비스는 runit 프로세스 초기화/지도를 사용하여 실행하는 소프트웨어 프로세스입니다. gitlab-ctl 명령을 사용하여 상태를 확인하고 시작, 중지, 다시 시작할 수 있습니다. 레시피는 또한 이러한 서비스를 프로세스 그룹 및 구성된 GitLab 인스턴스를 기반으로 비활성화하거나 활성화할 수 있습니다. 서비스 디렉터리 및 해당하는 서비스 그룹은 files/gitlab-cookbooks/package/libraries/config/services.rb에서 찾을 수 있습니다.

추가적인 gitlab-ctl 명령어

기본적으로 Omnibus는 gitlab-ctl reconfiguregitlab-ctl restart와 같은 래퍼 명령어를 제공하여 GitLab 인스턴스를 관리합니다. Omnibus GitLab 리포지터리에 정의된 몇 가지 추가 래퍼 명령어는 Omnibus GitLab 리포지터리에서 정의된 특정한 유증상을 대상으로 합니다. 이러한 명령어는 데이터베이스 마이그레이션 실행 또는 휴면 계정 제거와 같은 특정 작업을 수행하는 데 gitlab-ctl 명령과 함께 사용됩니다.

테스트

Omnibus GitLab 리포지터리는 ChefSpec을 사용하여 cookbook 및 레시피를 테스트합니다. 일반적인 전략은 사용자가 해당 구성을 지정하지 않았거나(즉, 기본값을 사용했을 때) 사용자가 구성을 지정했을 때와 같은 두 가지 조건에서 레시피가 올바르게 동작하는지 확인하는 것입니다. 테스트에는 제대로된 위치에 파일이 생성되는지, 서비스가 시작/중지/통지되는지, 올바른 이진 파일이 호출되는지, 메서드 호출에 올바른 매개변수가 전달되는지 확인하는 작업이 포함될 수 있습니다. 레시피 및 라이브러리 메서드에는 관련된 테스트가 있습니다. Omnibus GitLab은 테스트를 병렬화에 호환되도록 정의하여 전체 테스트 스위트 실행에 소요되는 시간을 줄입니다.

따라서 위에 설명된 구성요소 중 일부(예: 소프트웨어 정의, 프로젝트 메타데이터 및 테스트)는 빌드 환경에서 패키지 빌딩 중에 사용되며 일부(예: Chef cookbooks 및 레시피, GitLab 구성 파일, runit 및 gitlab-ctl 명령)는 사용자가 설치한 인스턴스를 구성하는 데 사용됩니다.

Omnibus GitLab의 작업 수명주기

패키지 빌딩 중의 작업

빌드하는 패키지 유형은 빌드 프로세스를 실행하는 OS에 따라 다릅니다. Debian 환경에서 빌드하는 경우 .deb 패키지가 생성됩니다. 패키지 빌딩 중에 발생하는 작업은 다음 단계로 요약할 수 있습니다.

  1. 의존 소프트웨어의 소스 가져오기:
    1. 해당하는 버전을 찾기 위해 소프트웨어 정의를 구문 분석합니다.
    2. 원격지 또는 캐시에서 소스 코드를 가져옵니다.
  2. 개별 소프트웨어 컴포넌트 빌드:
    1. 필요한 환경 변수 및 플래그 설정합니다.
    2. 해당하는 경우 패치를 적용합니다.
    3. 소프트웨어 컴포넌트의 빌드 및 설치를 수행합니다. 이 과정에는 적절한 위치(예: /opt/gitlab 내부)에 설치됩니다.
  3. 외부 소프트웨어, Ruby 젬 및 JS 모듈을 포함한 모든 번들된 컴포넌트의 라이선스 정보 생성: 각 의존성의 정의 분석과 컴포넌트 제공된 추가 라이선스 문서(예: GitLab Rails에서 제공된 licenses.csv 파일)를 분석합니다.
  4. 비호환 라이선스를 포함하지 않도록 컴포넌트의 라이선스를 확인합니다.
  5. 사용 가능한 라이브러리에 바이너리를 연결하는지 확인하기 위해 패키지에 대한 상태 체크를 실행합니다. 번들된 라이브러리의 경우 바이너리가 해당 라이브러리에 연결되어 있어야 합니다.
  6. /opt/gitlab 내용으로 패키지 빌딩: 리포지터리 내부의 gitlab.rb(https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/config/projects/gitlab.rb)에서 제공된 메타데이터를 사용합니다. 이에는 패키지 이름, 버전, 유지 관리자, 홈페이지 및 다른 패키지와의 충돌 정보가 포함됩니다.

캐싱

Omnibus는 빌드 프로세스를 최적화하기 위해 두 가지 유형의 캐시를 사용합니다: 소프트웨어 아티팩트(의존 소프트웨어의 소스)를 저장하는 캐시 및 각 소프트웨어 구성요소가 빌드된 후 프로젝트 트리를 저장하는 캐시

소프트웨어 아티팩트 캐시(GitLab Inc 빌드용)

소프트웨어 아티팩트 캐시는 의존 소프트웨어의 소스를 저장하기 위해 Amazon S3 버킷을 사용합니다. 빌드 프로세스에서 이 캐시는 bin/omnibus cache populate 명령을 사용하여 채워지며, 이를 통해 필요한 소프트웨어 소스를 Amazon 버킷에서 가져와 필요한 위치에 저장합니다. 소프트웨어 버전 요구 사항이 변경되면 omnibus에서 원래 원격지에서 가져와서 아티팩트 캐시에 추가합니다. 이 프로세스는 omnibus 내부적으로 이루어지며 리포지터리 루트에 있는 omnibus.rb 파일을 사용하여 Amazon 버킷을 구성합니다. 이 캐시를 통해 소프트웨어의 의존성은 원격지가 중단되어도 사용할 수 있습니다.

빌드 캐시

빌드 프로세스에 중요한 역할을 하는 두 번째 유형의 캐시는 빌드 캐시입니다. 빌드 캐시는 각 종속 소프트웨어가 빌드된 후 프로젝트 트리의 스냅샷입니다. 순서상으로 A, B, C, D 및 E와 같은 다섯 개의 종속 소프트웨어를 갖는 프로젝트를 고려하고, 여기서는 의존성은 고려하지 않습니다. 빌드 캐시는 Git 태그를 사용하여 스냅샷을 만듭니다. 각 소프트웨어가 빌딩된 후에는 Git 태그가 계산되고 커밋됩니다. 이제 소프트웨어 D의 정의에 변경이 있었다고 가정해봅시다. A, B, C 및 E는 그대로입니다. 다시 빌드하려고하면 omnibus는 이전 빌드에서 D가 빌드되기 전에 만든 스냅샷을 재사용할 수 있습니다. 따라서 A, B 및 C의 빌드 시간을 저장할 수 있으며 C가 빌드된 후의 스냅샷을 확인할 수 있습니다. Omnibus는 이전 빌드에서 빌드 캐시를 더러워지게하는 소프트웨어를 먼저 빌드하기 전에 만든 스냅샷을 사용합니다. 마찬가지로, 빌드 중에 소프트웨어 A의 정의가 변경되면 캐시가 더러워지고 따라서 A 및 모든 뒤이어 사용하는 의존성이 처음부터 다시 빌드됩니다. C가 캐시를 더러워지면 A와 B가 재사용되고 C, D 및 E가 처음부터 다시 빌드됩니다.

이 캐시는 빌드별로 유지되어야 유효합니다. 그 때문에 우리는 GitLab CI의 캐싱 메커니즘을 사용합니다. 우리는 특정 Amazon 버킷에 내부 캐시를 저장하도록 구성된 전용 러너를 가지고 있습니다. 각 빌드 전에 이 캐시를 가져와서(restore_cache_bundle는 우리 Makefile에서의 대상) 적절한 위치로 이동한 후 빌드를 시작합니다. Omnibus는 캐시를 먼저 더럽히기 직전의 소프트웨어를 사용합니다. 빌드 후 우리는 새 캐시를 패킹하여 CI에 백업할 것을 요청합니다(pack_cache_bundle는 우리 Makefile에서의 대상).

두 가지 유형의 캐시는 GitLab 및 외부 요소에 대한 전체적인 빌드 시간을 줄입니다.

캐시 메커니즘을 다음과 같이 요약할 수 있습니다:

  1. 각 소프트웨어 의존성마다:
    1. 버전 및 SHA256을 이해하기 위해 정의를 구문 분석합니다.
    2. 소프트웨어 소스 파일의 tarball이 Amazon 버킷 내의 아티팩트 캐시와 버전 및 SHA256이 일치하는 경우 사용합니다.
    3. 그렇지 않으면 해당하는 원격지에서 올바른 tarball을 다운로드합니다.
  2. CI 캐시 가져오기
    1. 각 소프트웨어 의존성마다:
    2. 캐시가 더러워지면 루프를 중단합니다.
    3. 그렇지 않으면 스냅샷을 확인합니다.
  3. 나머지 의존성이 있다면:
    1. 나머지 의존성마다:
      1. 의존성을 빌드합니다.
      2. 스냅샷을 생성하고 커밋합니다.
  4. 새로운 빌드 캐시를 CI 캐시에 밀어넣습니다.

다중 데이터베이스

이전에는 GitLab Rails 애플리케이션이 Omnibus GitLab 데이터베이스에 연결된 유일한 클라이언트였습니다. 그러나 시간이 지나면서 이것은 변경되었습니다.

  • Praefect 및 컨테이너 레지스트리는 각자의 데이터베이스를 사용합니다.
  • Rails 애플리케이션은 이제 분해된 데이터베이스를 사용합니다.

추가 데이터베이스가 필요할 수 있기 때문에:

  • 다중 데이터베이스 청사진은 Omnibus GitLab에 새로운 컴포넌트와 기능에 대한 데이터베이스 지원을 추가하는 방법을 설명합니다.
  • 관련 개발 문서는 구현 모델을 설명하고 데이터베이스 지원을 추가하는 예시를 제공합니다.