오프라인 자체 관리 GitLab 인스턴스 설치

Tier: Free, Premium, Ultimate Offering: Self-Managed

자체 관리 GitLab 인스턴스를 설치, 구성 및 사용하는 단계별 가이드입니다. 완전히 오프라인에서 작동합니다.

설치

참고: 이 가이드는 서버가 Omnibus 설치 방법을 사용하는 Ubuntu 20.04서버이며 GitLab Enterprise Edition를 실행한다고 가정합니다. 다른 서버에 대한 지침은 다를 수 있습니다. 또한, 이 가이드는 서버 호스트가 my-host.internal로 해결되어 있다고 가정하며, 이는 귀하의 서버의 FQDN으로 대체해야 합니다. 또한 필요한 패키지 파일을 다운로드하기 위해 인터넷에 액세스할 수 있는 다른 서버에 액세스할 수 있다고 가정합니다.

이 프로세스에 대한 영상 안내는 오프라인 GitLab 설치: 다운로드 및 설치를 참조하세요.

GitLab 패키지 다운로드

인터넷 액세스 권한이 있는 동일한 OS 유형의 서버에서 명시적으로 GitLab 패키지와 관련 종속성을 다운로드해야 합니다.

오프라인 환경에 로컬 네트워크 액세스가 없는 경우 해당 패키지를 USB 드라이브와 같은 물리적 미디어를 통해 수동으로 전송해야 합니다.

Ubuntu에서는 다음 명령을 사용하여 인터넷 액세스가 있는 서버에서 수행할 수 있습니다.

# 저장소를 준비하는 bash 스크립트 다운로드
curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash

# gitlab-ee 패키지 및 종속성을 /var/cache/apt/archives에 다운로드
sudo apt-get install --download-only gitlab-ee

# apt 다운로드 폴더의 내용을 마운트된 미디어 장치로 복사
sudo cp /var/cache/apt/archives/*.deb /path/to/mount

GitLab 패키지 설치

필수 사항:

  • 오프라인 환경에서 GitLab 패키지를 설치하기 전에 필요한 모든 종속성이 설치되었는지 확인하세요.

Ubuntu를 사용하는 경우, 복사한 .deb 패키지를 dpkg로 설치할 수 있습니다. 하지만 아직 GitLab 패키지를 설치하지는 마세요.

# 물리적 미디어 장치로 이동
sudo cd /path/to/mount

# 종속 패키지 설치
sudo dpkg -i <package_name>.deb

패키지를 설치하는 단계에서 EXTERNAL_URL 설치 단계에 http URL을 지정해야 하지만 운영 체제에 맞게 해당 명령을 사용하여 패키지를 설치하세요. 설치된 후 SSL을 직접 구성할 수 있습니다.

서버의 IP 주소에 바인딩하기보다는 IP 해결을 위해 도메인을 설정하는 것이 강력히 권장됩니다. 이것은 인증서의 CN에 대한 안정적인 대상을 확보하고 장기적인 해결을 더욱 간단하게 만들어줍니다.

다음 예는 Ubuntu를 위해 EXTERNAL_URL을 HTTP를 사용하여 지정하고 GitLab 패키지를 설치합니다.

sudo EXTERNAL_URL="http://my-host.internal" dpkg -i <gitlab_package_name>.deb

SSL 활성화

새로운 인스턴스에 SSL을 활성화하려면 다음 단계를 따르세요. 이러한 단계는 Omnibus의 NGINX 구성에서 SSL 수동 구성을 반영합니다:

  1. /etc/gitlab/gitlab.rb에 다음 변경 사항을 적용하세요:

    # external_url을 "http"에서 "https"로 업데이트
    external_url "https://my-host.internal"
    
    # Let's Encrypt를 false로 설정
    letsencrypt['enable'] = false
    
  2. 다음과 같은 권한으로 셀프 사인 인증서를 생성하기 위해 다음 디렉토리를 만드세요:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/gitlab/ssl/my-host.internal.key -out /etc/gitlab/ssl/my-host.internal.crt
    
  3. 변경 사항을 적용하기 위해 인스턴스를 재구성하세요:

    sudo gitlab-ctl reconfigure
    

GitLab 컨테이너 레지스트리 활성화

컨테이너 레지스트리를 활성화하려면 다음 단계를 따르세요. 이러한 단계는 기존 도메인에서 컨테이너 레지스트리 구성을 반영합니다:

  1. /etc/gitlab/gitlab.rb에 다음 변경 사항을 적용하세요:

    # external_registry_url을 외부 URL과 일치하도록 변경하되 포트 4567을 추가하세요
    external_url "https://gitlab.example.com"
    registry_external_url "https://gitlab.example.com:4567"
    
  2. 변경 사항을 적용하기 위해 인스턴스를 재구성하세요:

    sudo gitlab-ctl reconfigure
    

Docker 데몬에게 레지스트리 및 GitLab 러너를 신뢰하도록 허용

귀하의 Docker 데몬에게 다음 단계에 따라 귀하의 인증서를 제공하십시오. 레지스트리와 함께 신뢰할 수 있는 인증서를 사용:

sudo mkdir -p /etc/docker/certs.d/my-host.internal:5000

sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/docker/certs.d/my-host.internal:5000/ca.crt

귀하의 GitLab 러너(다음에 설치됨)에게도 다음 단계에 따라 귀하의 인증서를 제공하십시오. 신뢰할 수 있는 인증서를 사용하여 러너:

sudo mkdir -p /etc/gitlab-runner/certs

sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/gitlab-runner/certs/ca.crt

GitLab 러너 활성화

GitLab 러너를 Docker 서비스로 설치하는 단계와 유사한 프로세스를 따라, 우리는 먼저 러너를 등록해야합니다:

$ sudo docker run --rm -it -v /etc/gitlab-runner:/etc/gitlab-runner gitlab/gitlab-runner register
CA 인증서 업데이트 중...
Runtime platform                                    arch=amd64 os=linux pid=7 revision=1b659122 version=12.8.0
Running in system-mode.

Please enter the gitlab-ci coordinator URL (for example, https://gitlab.com/):
https://my-host.internal
Please enter the gitlab-ci token for this runner:
XXXXXXXXXXX
Please enter the gitlab-ci description for this runner:
[eb18856e13c0]:
Please enter the gitlab-ci tags for this runner (comma separated):

러너 등록 중... 성공                     runner=FSMwkvLZ
Please enter the executor: custom, docker, virtualbox, kubernetes, docker+machine, docker-ssh+machine, docker-ssh, parallels, shell, ssh:
docker
Please enter the default Docker image (for example, ruby:2.6):
ruby:2.6
러너가 성공적으로 등록되었습니다. 실행해도 상관없지만, 이미 실행 중인 경우 구성은 자동으로 다시로드됩니다!

이제 러너에 몇 가지 추가 구성을 추가해야합니다:

/etc/gitlab-runner/config.toml에 다음 변경 사항을 추가하십시오:

  • 볼륨에 Docker 소켓 추가 volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
  • 실행자 구성에 pull_policy = "if-not-present" 추가

이제 러너를 시작할 수 있습니다:

sudo docker run -d --restart always --name gitlab-runner -v /etc/gitlab-runner:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
90646b6587127906a4ee3f2e51454c6e1f10f26fc7a0b03d9928d8d0d5897b64

호스트 OS에서 레지스트리를 인증

Docker 레지스트리 인증 문서에 언급된 대로, 특정 버전의 Docker는 OS 수준에서 인증서 체인을 신뢰해야합니다.

Ubuntu의 경우, update-ca-certificates 사용이 포함됩니다:

sudo cp /etc/docker/certs.d/my-host.internal\:5000/ca.crt /usr/local/share/ca-certificates/my-host.internal.crt

sudo update-ca-certificates

모두 잘 되면 다음을 볼 수 있습니다:

1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

버전 확인 및 서비스 핑 비활성화

버전 확인 및 서비스 핑은 GitLab 사용자 경험을 향상시키고 사용자가 가장 최신의 GitLab 인스턴스를 사용하는 것을 보장합니다. 오프라인 환경에서는 이 두 서비스를 GitLab 서비스에 접근하려고 시도하지 않고 실패하지 않도록 꺼두어야 합니다.

자세한 정보는 서비스 핑 활성화 또는 비활성화를 참조하십시오.

NTP 구성

GitLab 15.4 및 15.5에서 Gitaly Cluster는 pool.ntp.org가 접근 가능하다고 가정합니다. pool.ntp.org에 접근할 수 없는 경우, Gitaly 및 Praefect 서버에서 시간 서버 설정을 사용자 정의하여 접근 가능한 NTP 서버를 사용할 수 있도록해야합니다.

오프라인 인스턴스에서는 GitLab Geo 확인 Rake task가 항상 pool.ntp.org를 사용하기 때문에 항상 실패합니다. 이 오류를 무시할 수 있지만, 어떻게 해결할 수 있는지 자세히 알아보십시오.

패키지 메타데이터베이스 활성화

패키지 메타데이터베이스를 활성화하면 지속적 취약점 스캐닝CycloneDX 파일의 라이선스 스캐닝을 활성화할 수 있습니다. 이 프로세스는 패키지 메타데이터베이스로 통칭되는 라이선스 및/또는 조언 데이터의 사용을 필요로 합니다. 해당 데이터는 EE 라이선스에 따라 라이선스가 부여됩니다. 패키지 메타데이터베이스의 사용과 관련하여 다음 사항을 참고하세요:

  • 우리는 패키지 메타데이터베이스 전체 또는 일부를 우리의 재량에 따라 언제든지 사전 통지 없이 변경하거나 중단할 수 있습니다.
  • 패키지 메타데이터베이스에는 제3자 웹사이트 또는 리소스로의 링크가 포함될 수 있습니다. 이 링크는 편의를 위해 제공되었으며 해당 웹사이트나 리소스에서 제공되는 제3자 데이터, 콘텐츠, 제품 또는 서비스에 대한 책임은 없습니다.
  • 패키지 메타데이터베이스는 제3자가 제공한 정보를 일부 기반으로 하며 GitLab은 해당 콘텐츠의 정확성이나 완전성에 대해 책임지지 않습니다.

패키지 메타데이터는 다음과 같은 Google Cloud Provider (GCP) 버킷에 저장됩니다:

  • 라이선스 스캐닝 - prod-export-license-bucket-1a6c642fc4de57d4
  • 의존성 스캐닝 - prod-export-advisory-bucket-1a6c642fc4de57d4

gsutil 도구를 사용하여 패키지 메타데이터 익스포트 다운로드하기

  1. gsutil 도구를 설치합니다.
  2. GitLab Rails 디렉토리의 루트를 찾습니다.

    export GITLAB_RAILS_ROOT_DIR="$(gitlab-rails runner 'puts Rails.root.to_s')"
    echo $GITLAB_RAILS_ROOT_DIR
    
  3. 동기화할 데이터 유형을 설정합니다.

    # 라이선스 스캐닝의 경우
    export PKG_METADATA_BUCKET=prod-export-license-bucket-1a6c642fc4de57d4
    export DATA_DIR="licenses"
    
    # 의존성 스캐닝의 경우
    export PKG_METADATA_BUCKET=prod-export-advisory-bucket-1a6c642fc4de57d4
    export DATA_DIR="advisories"
    
  4. 패키지 메타데이터 익스포트를 다운로드합니다.

    # 패키지 메타데이터 익스포트를 다운로드하려면 Google Cloud Storage 버킷에 대한 아웃바운드 연결이 허용되어야 합니다.
    # v1 객체는 더 이상 사용되지 않으며 16.3 이후로 사용이 중단되었으므로 -y "^v1\/"를 사용하여 v1 객체를 건너뜁니다.
    mkdir -p "$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/$DATA_DIR"
    gsutil -m rsync -r -d -y "^v1\/" gs://$PKG_METADATA_BUCKET "$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/$DATA_DIR"
    
    # 또는 GitLab 인스턴스가 Google Cloud Storage 버킷에 연결할 수 없는 경우에는, 패키지 메타데이터 익스포트를 다운로드하는 것은 허용된 액세스를 가진 머신을 사용하여 수행한 후, 해당 데이터를 GitLab Rails 디렉토리의 루트로 복사할 수 있습니다.
    rsync rsync://example_username@gitlab.example.com/package_metadata/$DATA_DIR "$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/$DATA_DIR"
    

Google Cloud Storage REST API를 사용하여 패키지 메타데이터 익스포트 다운로드하기

Google Cloud Storage API를 사용하여 패키지 메타데이터 익스포트를 다운로드할 수도 있습니다. 해당 내용은 https://storage.googleapis.com/storage/v1/b/prod-export-license-bucket-1a6c642fc4de57d4/ohttps://storage.googleapis.com/storage/v1/b/prod-export-advisory-bucket-1a6c642fc4de57d4/o에서 사용할 수 있습니다. 이를 cURLjq을 사용하여 다음과 같이 다운로드할 수 있습니다.

자동 동기화

당신의 GitLab 인스턴스는 package_metadata 디렉토리의 내용과 정기적으로 동기화됩니다. 이전 브랜치에서 대상 브랜치로 변경 사항을 포함하는 제안입니다. 정기적으로 GitLab 인스턴스를 동기화하려면 다음과 같이 크론탭을 추가하여 주기적으로 새로운 익스포트를 다운로드할 수 있습니다.

라이센스 스캔:

*/30 * * * * gsutil -m rsync -r -d -y "^v1\/" gs://prod-export-license-bucket-1a6c642fc4de57d4 $GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/licenses

의존성 스캔:

*/30 * * * gsutil -m rsync -r -d gs://prod-export-advisory-bucket-1a6c642fc4de57d4 $GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/advisories

변경 사항

16.2 버전에서 vendor/package_metadata_db에서 vendor/package_metadata/licenses로 패키지 메타데이터 디렉토리가 변경되었습니다. 이 디렉토리가 이미 인스턴스에 존재하고 의존성 스캔이 추가되어야 하는 경우 다음 단계를 수행해야 합니다.

  1. licenses 디렉토리의 이름 변경: mv vendor/package_metadata_db vendor/package_metadata/licenses.
  2. vendor/package_metadata_dbvendor/package_metadata/licenses로 변경된 자동화 스크립트 또는 저장된 명령을 업데이트합니다.
  3. 크론 항목을 변경하여 vendor/package_metadata_db에서 vendor/package_metadata/licenses로 변경합니다.

     sed -i '.bckup' -e 's#vendor/package_metadata_db#vendor/package_metadata/licenses#g' [FILE ...]
    

문제 해결

데이터베이스 데이터 누락

라이센스 또는 자문 데이터가 종속성 목록 또는 MR 페이지에서 누락된 경우, 이것의 한 가지 가능한 원인은 데이터베이스가 익스포트 데이터와 동기화되지 않은 것입니다.

package_metadata 동기화는 크론 작업을 사용하여 트리거됩니다(자문 동기화라이센스 동기화)하여 관리 설정에서 활성화된 패키지 레지스트리 유형만 가져옵니다.

vendor/package_metadata의 파일 구조는 위에 활성화된 패키지 레지스트리 유형과 일치해야 합니다. 예를 들어 maven 라이센스 또는 자문 데이터를 동기화하려면 Rails 디렉토리 아래의 패키지 메타데이터 디렉토리는 다음 구조를 가져야 합니다:

  • 라이센스의 경우: $GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/licenses/v2/maven/**/*.ndjson.
  • 자문의 경우: $GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/advisories/v2/maven/**/*.ndjson.

성공적으로 실행한 후에 데이터베이스의 pm_ 테이블 아래의 데이터가 채워져 있어야 합니다( Rails console을 사용하여 확인):

  • 라이센스의 경우: sudo gitlab-rails runner "puts \"Package model has #{PackageMetadata::Package.where(purl_type: 'maven').size} packages\""
  • 자문의 경우: sudo gitlab-rails runner "puts \"Advisory model has #{PackageMetadata::AffectedPackage.where(purl_type: 'maven').size} packages\""

또한, 특정 패키지 레지스트리에 대한 체크포인트 데이터가 존재해야 합니다. 예를 들어 Maven의 경우, 성공적인 동기화 후 체크포인트가 생성되어 있어야 합니다:

  • 라이센스의 경우: sudo gitlab-rails runner "puts \"maven data has been synced up to #{PackageMetadata::Checkpoint.where(data_type: 'licenses', purl_type: 'maven')}\""
  • 자문의 경우: sudo gitlab-rails runner "puts \"maven data has been synced up to #{PackageMetadata::Checkpoint.where(data_type: 'advisories', purl_type: 'maven')}\""

마지막으로, application_json.log 로그에서 PackageMetadata::SyncService 클래스의 DEBUG 메시지를 검색하여 동기화 작업이 오류 없이 실행되었는지 확인할 수 있습니다. 예: {"severity":"DEBUG","time":"2023-06-22T16:41:00.825Z","correlation_id":"a6e80150836b4bb317313a3fe6d0bbd6","class":"PackageMetadata::SyncService","message":"Evaluating data for licenses:gcp/prod-export-license-bucket-1a6c642fc4de57d4/v2/pypi/1694703741/0.ndjson"}.