オフラインのGitLab Self-Managedインスタンスをインストールする
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
これは、GitLab Self-Managedインスタンスを完全にオフラインでインストール、設定、および使用するのに役立つ手順ガイドです。
インストール
このガイドでは、サーバーがLinuxパッケージインストール方法を使用するUbuntu 20.04であり、GitLab Enterprise Editionが実行されていることを前提としています。他のサーバーの手順は異なる場合があります。このガイドでは、サーバーホストがmy-host.internalとして解決されることも前提としています。そのためには、サーバーのFQDNに置き換える必要があり、必要なパッケージファイルをダウンロードするために、インターネットアクセスの可能な別のサーバーへのアクセスが必要となります。
このプロセスのビデオチュートリアルは、オフラインGitLabインストール: ダウンロードとインストールを参照してください。
GitLabパッケージをダウンロードする
インターネットにアクセスできる同じオペレーティングシステムタイプのサーバーを使用して、GitLabのパッケージと関連する依存関係をダウンロードする必要があります。
オフライン環境がローカルネットワークアクセスに対応していない場合は、USBドライブなどの物理メディアを介して関連パッケージを手動で転送する必要があります。
Ubuntuでこれを実行するには、インターネットアクセスの可能なサーバーで次のコマンドを使用します:
# Download the bash script to prepare the repository
curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash
# Download the gitlab-ee package and dependencies to /var/cache/apt/archives
sudo apt-get install --download-only gitlab-ee
# Copy the contents of the apt download folder to a mounted media device
sudo cp /var/cache/apt/archives/*.deb /path/to/mountGitLabパッケージをインストールする
前提要件:
- オフライン環境にGitLabパッケージをインストールする前に、必要なすべての依存関係が最初にインストールされていることを確認してください。
Ubuntuを使用している場合は、dpkgでコピーした依存関係.debパッケージをインストールできます。GitLabパッケージはまだインストールしないでください。
# Go to the physical media device
sudo cd /path/to/mount
# Install the dependency packages
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>.debSSLを有効にする
これらの手順に従って、新しいインスタンスのSSLを有効にします。これらの手順は、NGINX設定でSSLを手動で設定する手順を反映しています:
/etc/gitlab/gitlab.rbに次の変更を加えます:# Update external_url from "http" to "https" external_url "https://my-host.internal" # Set Let's Encrypt to false letsencrypt['enable'] = false自己署名証明書を生成するための適切な権限を持つ次のディレクトリを作成します:
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インスタンスを再設定して、変更を適用します:
sudo gitlab-ctl reconfigure
GitLabコンテナレジストリを有効にする
次の手順に従って、コンテナレジストリを有効にします。これらの手順は、既存のドメインでコンテナレジストリを設定する手順を反映しています:
/etc/gitlab/gitlab.rbに次の変更を加えます:# Change external_registry_url to match external_url, but append the port 4567 external_url "https://gitlab.example.com" registry_external_url "https://gitlab.example.com:4567"インスタンスを再設定して、変更を適用します:
sudo gitlab-ctl reconfigure
DockerデーモンがレジストリとGitLab Runnerを信頼できるように設定する
レジストリで信頼できる証明書を使用するための手順に従って、証明書を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.crtRunnerで信頼できる証明書を使用するための手順に従って、証明書をGitLab Runner(次にインストール)に提供します:
sudo mkdir -p /etc/gitlab-runner/certs
sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/gitlab-runner/certs/ca.crtGitLab Runnerを有効にする
当社のGitLab RunnerをDockerサービスとしてインストールする手順と同様のプロセスに従って、最初にRunnerを登録する必要があります:
$ sudo docker run --rm -it -v /etc/gitlab-runner:/etc/gitlab-runner gitlab/gitlab-runner register
Updating CA certificates...
Runtime platform arch=amd64 os=linux pid=7 revision=1b659122 version=12.8.0
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://my-host.internal
Enter the registration token:
XXXXXXXXXXX
Enter a description for the runner:
[eb18856e13c0]:
Enter tags for the runner (comma-separated):
Enter optional maintenance note for the runner:
Registering runner... succeeded 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
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!次に、Runnerに追加の設定を行う必要があります。
/etc/gitlab-runner/config.tomlに次の変更を加えます:
- Dockerソケットをボリューム
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]に追加 pull_policy = "if-not-present"をexecutorの設定に追加
これで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.バージョンチェックとService Pingを無効にする
バージョンチェックとService Pingは、GitLabユーザーエクスペリエンスを向上させ、ユーザーがGitLabの最新インスタンスを使用していることを確認する機能です。オフライン環境では、GitLabサービスへの接続を試行して失敗することがないように、これらの2つのサービスをオフにすることができます。
詳細については、Service Pingを有効または無効にするを参照してください。
Runnerのバージョン管理を無効にする
Runnerのバージョン管理では、GitLabから最新のRunnerバージョンを取得して、環境内のどのRunnerが古くなっているかを判断します。オフライン環境では、Runnerバージョン管理を無効にする必要があります。
NTPを設定する
Gitalyクラスター(Praefect)は、pool.ntp.orgにアクセスできることを前提としています。pool.ntp.orgにアクセスできない場合は、GitalyおよびPraefectサーバーで呼び出すタイムサーバー設定をカスタマイズして、アクセス可能なNTPサーバーを使用できるようにします。
オフラインインスタンスでは、GitLab GeoチェックRakeタスクはpool.ntp.orgを使用するため、常に失敗します。このエラーは無視できますが、回避する方法の詳細をお読みください。
パッケージメタデータデータベースを有効にする
継続的な脆弱性スキャンとCycloneDXファイルのパッケージライセンススキャンを有効にするには、パッケージメタデータデータベースを有効にする必要があります。このプロセスでは、EEライセンスに基づいてライセンス供与されている、パッケージメタデータデータベースと呼ばれるライセンスやアドバイザリデータを使用する必要があります。パッケージメタデータデータベースの使用に関して、次の点に注意してください:
- 当社は、独自の裁量により、いつでも予告なしに、パッケージメタデータデータベースの全部または一部を変更または中止する場合があります。
- パッケージメタデータデータベースには、サードパーティのWebサイトまたはリソースへのリンクが含まれている場合があります。これらのリンクは便宜上提供しているだけで、当社はこれらのWebサイトまたはリソースからのサードパーティのデータ、コンテンツ、製品、サービス、またはそのようなWebサイトに表示されるリンクについては責任を負いません。
- パッケージメタデータデータベースは、サードパーティが提供する情報に一部基づいており、GitLabは提供されるコンテンツの正確性または完全性について責任を負いません。
パッケージメタデータは、GitLabが保持し、所有する以下のGoogle Cloud Provider(GCP)バケットに保存されます:
- ライセンススキャン -
prod-export-license-bucket-1a6c642fc4de57d4 - 依存関係スキャン -
prod-export-advisory-bucket-1a6c642fc4de57d4
gsutilツールを使用してパッケージメタデータエクスポートをダウンロードする
gsutilツールをインストールします。GitLab Railsディレクトリのルートを検索します。
export GITLAB_RAILS_ROOT_DIR="$(gitlab-rails runner 'puts Rails.root.to_s')" echo $GITLAB_RAILS_ROOT_DIR同期するデータの種類を設定します。
# For License Scanning export PKG_METADATA_BUCKET=prod-export-license-bucket-1a6c642fc4de57d4 export DATA_DIR="licenses" # For Dependency Scanning export PKG_METADATA_BUCKET=prod-export-advisory-bucket-1a6c642fc4de57d4 export DATA_DIR="advisories"パッケージメタデータエクスポートをダウンロードします。
# To download the package metadata exports, an outbound connection to Google Cloud Storage bucket must be allowed. mkdir -p "$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/$DATA_DIR" gsutil -m rsync -r -d gs://$PKG_METADATA_BUCKET "$GITLAB_RAILS_ROOT_DIR/vendor/package_metadata/$DATA_DIR" # Alternatively, if the GitLab instance is not allowed to connect to the Google Cloud Storage bucket, the package metadata # exports can be downloaded using a machine with the allowed access, and then copied to the root of the GitLab Rails directory. 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/oおよびhttps://storage.googleapis.com/storage/v1/b/prod-export-advisory-bucket-1a6c642fc4de57d4/oで利用できます。次に、cURLとjqを使用してこれをダウンロードする方法の例を示します。
#!/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 "Usage: import_script.sh [license|advisory]"
exit 1
fi
PKG_METADATA_BUCKET="prod-export-$DATA_TYPE-bucket-1a6c642fc4de57d4"
PKG_METADATA_DOWNLOADS_OUTPUT_FILE="/tmp/package_metadata_${DATA_TYPE}_object_links.tsv"
# Download the contents of the bucket
# The script downloads all the objects and creates files with a maximum 1000 objects per file in JSON format.
MAX_RESULTS=1000
TEMP_FILE="out.json"
curl --silent --show-error --request GET "https://storage.googleapis.com/storage/v1/b/$PKG_METADATA_BUCKET/o?maxResults=$MAX_RESULTS" >"$TEMP_FILE"
NEXT_PAGE_TOKEN="$(jq -r '.nextPageToken' $TEMP_FILE)"
jq -r '.items[] | [.name, .mediaLink] | @tsv' "$TEMP_FILE" >"$PKG_METADATA_DOWNLOADS_OUTPUT_FILE"
while [ "$NEXT_PAGE_TOKEN" != "null" ]; do
curl --silent --show-error --request GET "https://storage.googleapis.com/storage/v1/b/$PKG_METADATA_BUCKET/o?maxResults=$MAX_RESULTS&pageToken=$NEXT_PAGE_TOKEN" >"$TEMP_FILE"
NEXT_PAGE_TOKEN="$(jq -r '.nextPageToken' $TEMP_FILE)"
jq -r '.items[] | [.name, .mediaLink] | @tsv' "$TEMP_FILE" >>"$PKG_METADATA_DOWNLOADS_OUTPUT_FILE"
#use for API rate-limiting
sleep 1
done
trap 'rm -f "$TEMP_FILE"' EXIT
echo "Fetched $DATA_TYPE export manifest"
# Parse the links and names for the bucket objects and output them into a tsv file
echo -e "Saving package metadata exports to $PKG_METADATA_DIR\n"
# Track how many objects will be downloaded
INDEX=1
TOTAL_OBJECT_COUNT="$(wc -l "$PKG_METADATA_DOWNLOADS_OUTPUT_FILE" | awk '{print $1}')"
# Download the objects
while IFS= read -r line; do
FILE="$(echo -n "$line" | awk '{print $1}')"
URL="$(echo -n "$line" | awk '{print $2}')"
OUTPUT_PATH="$PKG_METADATA_DIR/$FILE"
echo "Downloading $FILE"
if [ ! -f "$OUTPUT_PATH" ]; then
curl --progress-bar --create-dirs --output "$OUTPUT_PATH" --request "GET" "$URL"
else
echo "Existing file found"
fi
echo -e "$INDEX of $TOTAL_OBJECT_COUNT objects downloaded\n"
INDEX=$((INDEX + 1))
done <"$PKG_METADATA_DOWNLOADS_OUTPUT_FILE"
echo "All objects saved to $PKG_METADATA_DIR"自動同期
GitLabインスタンスは、定期的にpackage_metadataディレクトリのコンテンツと同期されます。アップストリームの変更に合わせてローカルコピーを自動的に更新するために、定期的に新しいエクスポートをダウンロードするようにcronジョブを追加できます。たとえば、次のcrontabを追加して、30分ごとに実行されるcronジョブを設定できます。
ライセンススキャンの場合:
*/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に変更されました。このディレクトリがインスタンスにすでに存在し、依存関係スキャンを追加する必要がある場合は、次の手順を実行する必要があります。
ライセンスディレクトリの名前を変更します(
mv vendor/package_metadata_db vendor/package_metadata/licenses)。vendor/package_metadata_dbをvendor/package_metadata/licensesに変更するために、保存された自動化スクリプトまたはコマンドを更新します。vendor/package_metadata_dbをvendor/package_metadata/licensesに変更するために、cronエントリを更新します。sed -i '.bckup' -e 's#vendor/package_metadata_db#vendor/package_metadata/licenses#g' [FILE ...]
トラブルシューティング
データベースデータが見つからない
ライセンスまたはアドバイザリデータが依存関係リストまたはマージリクエストページにない場合、考えられる原因の1つは、データベースがエクスポートデータと同期していないことです。
package_metadataの同期は、cronジョブ(アドバイザリ同期とライセンス同期 )を使用してトリガーされ、管理者設定で有効になっているパッケージレジストリタイプのみをインポートします。
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 \"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"}。