오프라인 Self-managed GitLab 인스턴스 설치

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

자세한 단계별 가이드로, 오프라인에서 완전히 Self-managed하는 GitLab 인스턴스를 설치, 구성 및 사용하는 데 도움이 되는 안내서입니다.

설치

note
이 안내서는 서버가 옴니버스 설치 방법을 사용하는 Ubuntu 20.04 서버이며 GitLab Enterprise Edition가 실행 중이라고 가정합니다. 다른 서버의 경우 지침이 다를 수 있습니다. 또한, 이 안내서는 서버 호스트가 my-host.internal로 해제되어 있다고 가정합니다. 이는 귀하의 서버 FQDN으로 교체해야 하며 해당 패키지 파일을 다운로드할 수 있는 다른 인터넷 액세스가 있는 서버에 액세스할 수 있다고 가정합니다.

이 프로세스의 비디오 안내를 보려면 오프라인 GitLab 설치: 다운로드 및 설치를 참조하십시오.

GitLab 패키지 다운로드

인터넷 액세스 권한을 가진 동일한 운영 체제 유형의 서버를 사용하여 매뉴얼으로 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 예제로 HTTP를 사용하여 EXTERNAL_URL을 지정하고 GitLab 패키지를 설치하는 내용입니다:

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

SSL 활성화

새로운 인스턴스에 SSL을 활성화하려면 다음 단계를 따르십시오. 이러한 단계는 옴니버스 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를 external_url과 일치하도록 변경하되 포트 4567을 추가합니다
    external_url "https://gitlab.example.com"
    registry_external_url "https://gitlab.example.com:4567"
    
  2. 변경 사항을 적용하도록 인스턴스를 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    

Docker 데몬에 레지스트리 및 GitLab Runner 신뢰 권장

도커 데몬에 레지스트리에 대한 인증서를 추가하여, 레지스트리에 신뢰할 수 있는 인증서를 사용하는 방법에 대한 단계를 따르십시오(../../administration/packages/container_registry.md#using-self-signed-certificates-with-container-registry):

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 Runner에 인증서를 제공하려면 아래 단계를 따르십시오(https://docs.gitlab.com/runner/install/docker.html#installing-trusted-ssl-server-certificates):

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

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

GitLab Runner 활성화

GitLab Runner를 Docker 서비스로 설치하는 단계와 유사한 과정을 따라서 먼저 Runner를 등록해야 합니다:

$ sudo docker run --rm -it -v /etc/gitlab-runner:/etc/gitlab-runner gitlab/gitlab-runner register
CA 인증서 업데이트 중...
런타임 플랫폼                                    arch=amd64 os=linux pid=7 revision=1b659122 version=12.8.0
시스템 모드에서 실행 중.

gitlab-ci 코디네이터 URL을 입력하십시오 (예: https://gitlab.com/):
https://my-host.internal
이 Runner가 삽입하고 있는 gitlab-ci 토큰을 입력하십시오.
XXXXXXXXXXX
이 Runner에 대한 gitlab-ci 설명을 입력하십시오:
[eb18856e13c0]:
이 Runner에 대한 gitlab-ci 태그를 입력하십시오 (쉼표로 구분):

Runner 등록 중... 성공                      runner=FSMwkvLZ
실행하기를 원하는 executor를 입력하십시오: custom, docker, virtualbox, kubernetes, docker+machine, docker-ssh+machine, docker-ssh, parallels, shell, ssh:
docker
기본 Docker 이미지를 입력하십시오 (예: ruby:2.6):
ruby:2.6
Runner가 성공적으로 등록되었습니다. 실행하지 않으려면 설정은 자동으로 다시로드되어야 합니다!

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

  • /etc/gitlab-runner/config.toml에 Docker 소켓을 추가하십시오 volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
  • 실행기 구성에 pull_policy = "if-not-present"를 추가하십시오

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

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 서버에서 시간 서버 설정 사용자 정의를 해야합니다.

오프라인 인스턴스에서는 GitLab Geo check Rake task가 항상 pool.ntp.org을 사용하기 때문에 항상 실패합니다. 이 오류는 무시할 수 있지만, 이를 해결하는 방법에 대해 더 알아보세요.

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

패키지 메타데이터 데이터베이스를 활성화해야만 지속적 취약점 스캐닝CycloneDX 파일의 라이선스 스캔를 가능하게 합니다. 이 프로세스는 EE 라이선스에 따라 라이선스 및/또는 고문 데이터를 사용하여 패키지 메타데이터 데이터베이스라 불리는 것에 필요합니다. 이 데이터베이스는 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 객체를 건너뛰려면 -y "^v1\/"을 사용하여 v2 객체만 다운로드하세요. v1 데이터는 더 이상 사용되지 않으며 16.3 이후로 사용이 중지되었습니다.
    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를 사용하여 이를 다운로드하는 예시입니다.

#!/bin/bash

set -euo pipefail

DATA_TYPE=$1

GITLAB_RAILS_ROOT_DIR="$(gitlab-rails runner 'puts Rails.root.to_s')"

if [ "$DATA_TYPE" == "license" ]; then
  PKG_METADATA_DIR="$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/licenses"
elif [ "$DATA_TYPE" == "advisory" ]; then
  PKG_METADATA_DIR="$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/advisories"
else
  echo "사용법: import_script.sh [licenses|advisories]"
  exit 1
fi

PKG_METADATA_BUCKET="prod-export-$DATA_TYPE-bucket-1a6c642fc4de57d4"
PKG_METADATA_MANIFEST_OUTPUT_FILE="/tmp/package_metadata_${DATA_TYPE}_export_manifest.json"
PKG_METADATA_DOWNLOADS_OUTPUT_FILE="/tmp/package_metadata_${DATA_TYPE}_object_links.tsv"

# 버킷의 내용 다운로드
# `prefix=v2`를 사용하여 v2 객체만 다운로드하세요. v1 데이터는 더 이상 사용되지 않으며 16.3 이후로 사용이 중지되었습니다.
# API에서 반환하는 객체의 최대 수는 5000개이며 현재(2023-12-21) v2 데이터셋에는 2650개의 객체가 있습니다.
curl --silent --show-error --request GET "https://storage.googleapis.com/storage/v1/b/$PKG_METADATA_BUCKET/o?prefix=v2%2f&maxResults=5000" > "$PKG_METADATA_MANIFEST_OUTPUT_FILE"

# 버킷 객체의 링크와 이름을 구문 분석하여 tsv 파일로 출력합니다.
jq -r '.items[] | [.name, .mediaLink] | @tsv' "$PKG_METADATA_MANIFEST_OUTPUT_FILE" > "$PKG_METADATA_DOWNLOADS_OUTPUT_FILE"

echo -e "$PKG_METADATA_DIR에 패키지 메타데이터 익스포트를 저장 중입니다\n"

# 다운로드할 객체 수를 추적합니다.
INDEX=1
TOTAL_OBJECT_COUNT="$(wc -l $PKG_METADATA_DOWNLOADS_OUTPUT_FILE | awk '{print $1}')"

# 객체를 다운로드합니다.
while IFS= read -r line; do
   FILE="$(echo -n $line | awk '{print $1}')"
   URL="$(echo -n $line | awk '{print $2}')"
   OUTPUT_DIR="$(dirname $PKG_METADATA_DIR/$FILE)"
   OUTPUT_PATH="$PKG_METADATA_DIR/$FILE"
   
   echo "$FILE 다운로드 중"
   
   curl --progress-bar --create-dirs --output "$OUTPUT_PATH" --request "GET" "$URL"
   
   echo -e "$INDEX$TOTAL_OBJECT_COUNT 개의 객체를 다운로드 중\n"
   
   let INDEX=(INDEX+1)
done < "$PKG_METADATA_DOWNLOADS_OUTPUT_FILE"

echo "모든 객체를 $PKG_METADATA_DIR에 저장했습니다"

자동 동기화

귀하의 GitLab 인스턴스는 package_metadata 디렉터리의 내용과 정기적으로 동기화됩니다. 상위 변경 사항으로 로컬 사본을 자동으로 업데이트하려면 cron 작업을 추가하여 주기적으로 새로운 익스포트를 다운로드할 수 있습니다. 예를 들어, 매 30분마다 실행되는 cron 작업을 설정하는 데 다음과 같은 crontab을 추가할 수 있습니다.

라이선스 스캔:

*/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_dbvendor/package_metadata/licenses로 변경하는 cron 항목 업데이트.

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

문제 해결

누락된 데이터베이스 데이터

라이선스 또는 고려 사항 데이터가 의존성 디렉터리 또는 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 콘솔을 사용하여 확인):

  • 라이선스의 경우: sudo gitlab-rails runner "puts \"패키지 모델에는 #{PackageMetadata::Package.where(purl_type: 'maven').size}개의 패키지가 있습니다\""
  • 고려 사항의 경우: sudo gitlab-rails runner "puts \"고려 사항 모델에는 #{PackageMetadata::AffectedPackage.where(purl_type: 'maven').size}개의 패키지가 있습니다\""

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

  • 라이선스의 경우: sudo gitlab-rails runner "puts \"maven 데이터가 #{PackageMetadata::Checkpoint.where(data_type: 'licenses', purl_type: 'maven')}로 동기화되었습니다\""
  • 고려 사항의 경우: sudo gitlab-rails runner "puts \"maven 데이터가 #{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":"라이선스:gcp/prod-export-license-bucket-1a6c642fc4de57d4/v2/pypi/1694703741/0.ndjson"에 대한 데이터 평가"}를 검색하여 확인할 수 있습니다.