Omnibus GitLab 아키텍처 및 컴포넌트

Omnibus GitLab은 Chef의 Omnibus 프로젝트의 사용자 컴퓨터에서 GitLab을 구성하는 작업을 수행하는 데 사용되는 Chef 컴포넌트인 쿡북과 레시피와 같은 Chef 컴포넌트를 사용하는 Omnibus 프로젝트의 사용자 정의 버전입니다. Omnibus GitLab 리포지터리는 GitLab.com에 Omnibus GitLab의 모든 필수 컴포넌트를 호스팅합니다. 이에는 패키지를 빌드하는 데 필요한 Omnibus의 일부인 설정 및 프로젝트 메타데이터뿐만 아니라 사용자의 컴퓨터에서 설치된 후에 사용되는 Chef 관련 컴포넌트도 포함됩니다.

Omnibus-GitLab 컴포넌트

이러한 컴포넌트에 대한 심층 비디오 안내는 YouTube에서 제공됩니다.

소프트웨어 정의

GitLab 프로젝트 정의 파일

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

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

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

개별 소프트웨어 정의

Omnibus GitLab은 포함된 형식으로 GitLab 인스턴스의 올바른 작동에 필요한 모든 소프트웨어, 라이브러리 및 실행 파일을 제공하는 batteries-included 스타일을 따릅니다. 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과 같은 비교 링크를 생성하여 어떤 로컬 변경이 있는지 식별할 수 있습니다.

전역 GitLab 구성 템플릿

Omnibus GitLab은 사용자 컴퓨터에 설치될 GitLab 인스턴스의 모든 부분을 구성할 수 있는 단일 구성 파일을 제공합니다. 이 구성 파일은 GitLab 인스턴스에 적용될 모든 구성 설정의 근본적인 원본으로 작용합니다. 이 구성 파일에는 GitLab 인스턴스의 일반 설정 및 다양한 컴포넌트에 대한 여러 옵션이 나열되어 있습니다. 이 파일의 일반적인 구조는 <구성요소>['<설정>'] = <값> 형식의 구성을 포함하고 있습니다. 사용 가능한 모든 옵션은 구성 템플릿에 나열되어 있지만 GitLab의 기본 작동에 필요한 옵션을 제외한 모든 옵션은 기본적으로 주석 처리되어 있습니다. 사용자는 필요에 따라 그것들을 주석 해제하고 해당 값을 지정할 수 있습니다.

GitLab Cookbook

앞에서 설명한 대로 Omnibus GitLab은 쿡북, 속성 및 리소스와 같은 많은 Chef 컴포넌트를 사용합니다. GitLab EE는 GitLab CE에서 사용하는 것과 별도의 쿡북을 사용하고 EE 전용 컴포넌트를 추가합니다. Omnibus GitLab의 Chef 관련 주요 컴포넌트는 다음과 같습니다:

기본 속성

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

레시피

레시피는 Omnibus 패키지를 사용하여 GitLab을 설치하는 동안 대부분의 작업을 수행합니다. 이들은 사용자의 컴퓨터에 GitLab 생태계의 각 컴포넌트를 설정하는 데 책임이 있으며, 필요한 파일, 디렉터리 및 링크를 해당 위치에 만들고 권한과 소유자를 설정하고 필요한 서비스를 구성하고 시작하며 필요할 때 이러한 서비스에게 파일 변화를 알립니다. default라고 명명된 마스터 레시피는 여러 컴포넌트와 서비스에 필요한 다른 모든 레시피를 호출하는 것으로서 진입점으로 작용합니다.

사용자 정의 리소스

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

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

이전에 언급했듯이 Omnibus GitLab은 GitLab 인스턴스의 모든 컴포넌트를 조정하기 위해 단일 구성 파일을 제공합니다. 그러나 다른 컴포넌트의 아키텍처적 설계는 특정 위치에 상주하는 개별 구성 파일을 필요로 할 수 있습니다. 이러한 구성 파일은 사용자가 일반 구성 파일에 지정한 값이나 기본값에서 생성해야 합니다. 따라서 Omnibus GitLab은 이러한 구성 파일의 템플릿과 함께 제공됩니다. 이 템플릿에는 기본값이나 사용자로부터의 값으로 채울 수 있는 자리 표시자가 포함되어 있으며, 레시피는 이러한 템플릿을 완성하여 필요한 위치에 배치합니다.

일반 라이브러리 메소드

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

Omnibus GitLab에서 사용하는 라이브러리 중 특별한 것들이 있습니다: 주요 GitLab 모듈과 해당 컴포넌트 라이브러리를 호출하는 모든 컴포넌트별 라이브러리입니다. 컴포넌트별 라이브러리에는 해당 컴포넌트에 대한 설정을 구문 분석하는 작업을 수행하는 메소드가 포함되어 있습니다. 주요 GitLab 모듈에는 이를 조정하는 메소드가 포함되어 있습니다. 이 모듈은 기본 값 식별, 컴포넌트별 라이브러리 호출, 기본 값 및 사용자 지정 값 Merge, 유효성 검사, 초기 값에 따라 추가 구성 생성 등을 담당합니다. Omnibus GitLab 패키지로 제공되는 모든 최상위 컴포넌트는 이 모듈에 추가되어 구성 파일 및 기본 속성에 언급되고 올바르게 구문 분석될 수 있도록 합니다.

runit

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

서비스

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

추가 gitlab-ctl 명령

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

테스트

Omnibus GitLab 리포지터리는 ChefSpec을 사용하여 쿡북 및 레시피를 테스트합니다. 일반적인 전략은 사용자가 해당 구성을 지정하지 않았을 때(즉, 기본값을 사용한 경우) 및 사용자가 지정한 구성을 사용했을 때와 같이 두 가지(또는 그 이상) 상황에서 레시피가 올바르게 작동하는지 확인하는 것입니다. 테스트에는 올바른 위치에 파일이 생성되는지, 서비스가 시작/중지/알림이 오는지, 올바른 이진 파일이 호출되는지, 메소드 호출에 올바른 매개변수가 전달되는지 확인하는 등이 포함될 수 있습니다. 레시피 및 라이브러리 메소드에는 연결된 테스트가 있습니다. Omnibus GitLab은 테스트 프로세스를 돕기 위해 일부 지원 메소드나 매크로를 사용합니다. 가능한 경우 병렬화를 위해 테스트가 호환되도록 정의되어 있어 전체 테스트 스위트 실행에 필요한 시간을 줄일 수 있습니다.

위에서 설명한 컴포넌트 중에서 일부는 빌드 환경에서 패키지 빌드 중에 사용되고 다른 일부는 사용자가 설치한 인스턴스를 구성하는 데 사용됩니다.

Omnibus GitLab의 작업 수명 주기

패키지 빌드 중 발생하는 일들

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

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

캐싱

Omnibus는 빌드 프로세스 최적화를 위해 두 가지 유형의 캐시를 사용합니다: 소프트웨어 아티팩트(의존 소프트웨어 소스)를 저장하기 위한 하나와 각 소프트웨어 컴포넌트가 빌드된 후의 프로젝트 트리를 저장하기 위한 하나입니다.

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

소프트웨어 아티팩트 캐시는 Amazon S3 버킷을 사용하여 의존 소프트웨어의 소스를 저장합니다. 빌드 프로세스에서 이 캐시는 bin/omnibus cache populate 명령을 사용하여 채워집니다. 이 명령은 필요한 소프트웨어 소스를 모두 Amazon 버킷에서 가져와 필요한 위치에 저장합니다. 소프트웨어의 버전 요구 사항이 변경될 때, omnibus는 이를 원본 upstream에서 가져와 아티팩트 캐시에 추가합니다. 이 프로세스는 omnibus의 내부적인 것이며 리포지터리 루트에 있는 omnibus.rb 파일에서 구성하기 때문에 원격지 upstream이 다운되어 있더라도 의존 소프트웨어를 사용할 수 있도록 합니다.

빌드 캐시

빌드 프로세스에서 중요한 역할을 하는 두 번째 유형의 캐시는 빌드 캐시입니다. 빌드 캐시는 프로젝트 트리의 스냅숏(프로젝트가 빌드되는 위치 - /opt/gitlab)로 설명될 수 있습니다. 각 종속 소프트웨어가 빌드된 후의 스냅숏입니다. A, B, C, D 및 E라는 다섯 가지 종속 소프트웨어가 있는 프로젝트를 고려해 보겠습니다. 이들 간의 의존성은 고려하지 않습니다. 빌드 캐시는 스냅숏을 만들기 위해 Git 태그를 사용합니다. 각 소프트웨어가 빌드된 후 Git 태그가 계산되고 커밋됩니다. 이제 소프트웨어 D의 정의를 변경했다고 가정해 보겠습니다. A, B, C 및 E는 그대로입니다. 다시 빌드하려고 할 때 Omnibus는 이전 빌드에서 D가 빌드되기 전에 만들어진 스냅숏을 재사용할 수 있습니다. 따라서 A, B 및 C를 빌드하는 데 걸리는 시간을 저장할 수 있습니다. Omnibus는 “캐시를 ‘더티’하게 하는” 소프트웨어 직전의 스냅숏을 사용합니다 (‘더티’하게 만드는 것은 소프트웨어 정의의 변경, 이전 컴포넌트의 이름/버전 변경 또는 현재 컴포넌트 버전의 변경에 의해 발생할 수 있습니다). 마찬가지로, 빌드 중에 소프트웨어 A의 정의가 변경되면 캐시가 ‘더티’되고 따라서 A 및 모든 다음 의존성이 처음부터 다시 빌드됩니다. C가 캐시를 ‘더티’하게 만들면 A와 B가 재사용되고 C, D 및 E가 처음부터 다시 빌드됩니다.

이 캐시는 빌드 간에 유지된다면 의미가 있습니다. 이를 위해 우리는 GitLab CI의 캐싱 메커니즘을 사용합니다. 우리는 내부 캐시를 Amazon 버킷에 저장하도록 구성된 전용 러너를 사용합니다. 각 빌드 전에 이 캐시를 가져와야 합니다 (우리의 Makefile에 있는 restore_cache_bundle 대상), 적절한 위치로 이동시키고 빌드를 시작합니다. 이는 캐시가 ‘더티’되는 지점까지 Omnibus에 의해 사용됩니다. 빌드 후에 우리는 새로운 캐시를 패킹하고 CI에 이를 Amazon 버킷에 백업할 것을 알려줍니다 (우리의 Makefile에 있는 pack_cache_bundle).

두 유형의 캐시는 GitLab 및 외부 요소에 대한 의존성을 줄입니다.

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

  1. 각 소프트웨어 의존성에 대해:
    1. 버전 및 SHA256을 이해하기 위해 정의를 구문 분석합니다.
    2. Amazon 버킷의 아티팩트 캐시에서 사용 가능한 소스 파일 타볼이 버전 및 SHA256과 일치하는지 확인합니다.
    3. 그렇지 않으면 upstream 원격에서 올바른 타볼을 다운로드합니다.
  2. CI 캐시에서 캐시를 가져옵니다.
  3. 각 소프트웨어 의존성에 대해:
    1. 캐시가 ‘더티’되었다면 루프를 중지합니다.
    2. 그렇지 않으면 스냅숏을 체크아웃합니다.
  4. 남아있는 의존성이 있는 경우:
    1. 남아있는 각 의존성에 대해:
      1. 의존성을 빌드합니다.
      2. 스냅숏을 만들고 커밋합니다.
  5. 새로운 빌드 캐시를 CI 캐시에 밀어넣습니다.

gitlab-ctl reconfigure 중에 발생하는 일들

GitLab 인스턴스를 관리하는 동안 자주 사용되는 명령어 중 하나는 gitlab-ctl reconfigure입니다. 간단히 말해, 이 명령어는 구성 파일을 구문 분석하고 그 값으로 레시피를 실행합니다. 실행할 레시피는 설치 디렉터리 내의 embedded 폴더에 있는 dna.json이라는 파일에 정의되어 있습니다 (이 파일은 소프트웨어 정의에서 정의된 gitlab-cookbooks라는 소프트웨어 의존성에 의해 생성됩니다). GitLab CE의 경우, 마스터 레시피로 gitlab라는 쿡북이 선택되며, 이는 모든 다른 필요한 레시피, runit을 포함하여 호출합니다. 간단히 말해, reconfigure는 구성 템플릿에서 제공된 값으로 다른 파일 및 서비스를 구성하는 chef-client 실행입니다.

다중 데이터베이스

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

  • Praefect 및 Container Registry는 각각 고유의 데이터베이스를 사용합니다.
  • Rails 애플리케이션은 이제 분해된 데이터베이스를 사용합니다.

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