0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

パッケージとレジストリ

Posted at

パッケージとレジストリ

(トップページはこちら) - (アプリケーションのデプロイとリリースを始める)

「また Docker Hub のレート制限に引っかかった」「依存パッケージのダウンロードでビルドが遅い」「どのパイプラインがこのパッケージを公開したのか追跡できない」。こうした課題に直面したことはありませんか。

GitLabのパッケージ管理機能は、これらの問題を根本から解決します。本記事では、パッケージレジストリ、コンテナレジストリ、仮想レジストリ、依存関係プロキシという4つの中核機能を軸に、実践的な活用方法と技術的な仕組みを解説します。

1. なぜGitLabのパッケージ管理なのか

1.1 解決できる3つの課題

課題1: 外部レジストリへの依存とレート制限

Docker Hubは無料プランで6時間あたり100回のプル制限を設けています。CI/CDパイプラインが頻繁に実行される環境では、この制限にすぐ到達します。

課題2: 依存関係のダウンロード時間

外部レジストリから毎回パッケージをダウンロードすると、ネットワーク遅延やレジストリの応答速度がビルド時間に直結します。

課題3: セキュリティとトレーサビリティの欠如

「誰が」「いつ」「どのパイプラインで」パッケージを公開したのか。外部レジストリだけでは、この情報を追跡できません。

1.2 GitLabが提供する解決策

GitLabは、これらの課題に対して以下の機能で応えます。

2. アーキテクチャと使い分け

2.1 4つの機能の位置づけ

GitLabのパッケージ管理機能は、用途に応じて使い分けます。

機能 主な用途 キャッシュ 複数ソース 対象
パッケージレジストリ 自社パッケージの公開・管理 なし なし Maven, npm, PyPI, NuGet等
コンテナレジストリ 自社コンテナイメージの管理 なし なし Docker/OCI イメージ
仮想レジストリ 複数外部レジストリの統合 あり あり(最大20) Maven(今後拡張予定)
依存関係プロキシ Docker Hubのキャッシュ あり なし Docker イメージのみ

2.2 選択基準

自社で開発したパッケージを管理したい
→ パッケージレジストリまたはコンテナレジストリ

外部レジストリのレート制限を回避したい(Docker Hub)
→ 依存関係プロキシ

複数の外部Mavenレジストリを一元管理したい
→ 仮想レジストリ

コンテナイメージに署名を付けて管理したい
→ コンテナレジストリ(Cosign対応)

3. パッケージレジストリ:トレーサビリティの実現

3.1 CI/CDパイプラインとの完全統合

パッケージレジストリの最大の特徴は、GitLab CI/CDとの深い統合です。CI_JOB_TOKENを使用することで、認証情報をハードコードせずにパッケージを公開できます。

# .gitlab-ci.yml
stages:
  - build
  - test
  - publish

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

build:
  stage: build
  image: maven:3.8-openjdk-17
  script:
    - mvn clean package
  artifacts:
    paths:
      - target/*.jar

publish:
  stage: publish
  image: maven:3.8-openjdk-17
  script:
    - mvn deploy -s ci_settings.xml -DskipTests
  only:
    - tags
<!-- ci_settings.xml -->
<settings>
  <servers>
    <server>
      <id>gitlab-maven</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Job-Token</name>
            <value>${env.CI_JOB_TOKEN}</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
</settings>

3.2 パッケージのトレーサビリティ

パッケージの詳細ページでは、以下の情報が自動的に記録されます。

  • どのパイプラインが公開したか
  • どのコミットSHAから生成されたか
  • 誰がトリガーしたか
  • いつ公開されたか

これにより、問題のあるパッケージが見つかった場合、即座にソースコードまで遡ることができます。

3.3 監査イベント(Premium/Ultimate)

GitLab 18.2以降、パッケージの公開・削除時に監査イベントが作成されます。

# GraphQL APIで監査イベントを有効化
mutation {
  updateNamespacePackageSettings(input: {
    namespacePath: "my-group",
    mavenPackageRequestsForwarding: true,
    auditEventsEnabled: true
  }) {
    packageSettings {
      auditEventsEnabled
    }
  }
}

監査イベントには以下の情報が含まれます。

  • イベントタイプ(公開/削除)
  • パッケージ名とバージョン
  • 実行ユーザー
  • タイムスタンプ
  • IPアドレス

3.4 柔軟な権限管理

パッケージレジストリの可視性は、リポジトリとは独立して制御できます。

実用例:オープンソースプロジェクトでの活用

  • リポジトリ:パブリック(ソースコードは公開)
  • パッケージレジストリ:プライベート(ビルド済みパッケージは内部のみ)

または逆に、

  • リポジトリ:プライベート(ソースコードは非公開)
  • パッケージレジストリ:パブリック(パッケージは誰でも利用可能)

GitLab 15.7以降では、「誰でもパッケージレジストリから取得可能」設定により、認証なしでのパッケージ取得も可能です。

# .gitlab-ci.yml(外部プロジェクトから公開パッケージを利用)
image: maven:3.8-openjdk-17

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

build:
  script:
    # 認証不要で公開パッケージを取得
    - mvn dependency:get -Dartifact=com.example:my-library:1.0.0 -DremoteRepositories=https://gitlab.example.com/api/v4/projects/123/packages/maven

4. コンテナレジストリ:セキュアなイメージ管理

4.1 OCI準拠の意義

GitLab 16.6以降、コンテナレジストリはOCI配布仕様に準拠しています。これにより、以下のメリットがあります。

1. Helmチャートの保存

Helm 3以降、チャートはOCIイメージとして配布できます。GitLabコンテナレジストリに直接保存可能です。

# Helmチャートをコンテナレジストリにプッシュ
helm package ./my-chart
helm push my-chart-1.0.0.tgz oci://registry.gitlab.com/my-group/my-project

2. マルチアーキテクチャイメージのサポート

AMD64とARM64の両方のイメージを同じタグで管理できます。

# .gitlab-ci.yml
build-multiarch:
  image: docker:24-dind
  services:
    - docker:24-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker buildx create --use
    - docker buildx build --platform linux/amd64,linux/arm64 -t $CI_REGISTRY_IMAGE:latest --push .

4.2 コンテナイメージ署名とセキュリティ

GitLab 17.1以降、Cosign署名をコンテナイメージに関連付けることができます。

# .gitlab-ci.yml
stages:
  - build
  - sign

build-image:
  stage: build
  image: docker:24-dind
  services:
    - docker:24-dind
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

sign-image:
  stage: sign
  image: 
    name: gcr.io/projectsigstore/cosign:v2.2.0
    entrypoint: [""]
  variables:
    COSIGN_EXPERIMENTAL: "1"
  script:
    - echo "$COSIGN_PRIVATE_KEY" > cosign.key
    - cosign sign --key cosign.key --registry-referrers-mode oci-1-1 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  only:
    - main

署名されたイメージは、GitLab UIで署名アイコンが表示され、以下の情報を確認できます。

  • 署名者
  • 署名日時
  • 署名アルゴリズム
  • 公開鍵フィンガープリント

4.3 プロジェクト移動時の自動対応

GitLab 16.7以降、コンテナリポジトリを含むプロジェクトの名前変更や移転が自動的に処理されます。

従来の問題

プロジェクトをgroup-a/project-xからgroup-b/project-xに移動すると、コンテナイメージのパスが変わり、既存のデプロイメントが壊れる。

GitLabの解決策

プロジェクト移動時に、コンテナレジストリのパスも自動的に更新されます。ただし、パフォーマンス上の理由から、コンテナリポジトリが1,000個以下のプロジェクトに限定されています。

5. 仮想レジストリ:複数ソースの統合管理

5.1 仮想レジストリが解決する課題

企業環境では、複数のMavenレジストリを使用することが一般的です。

  • 社内プライベートレジストリ(独自ライブラリ)
  • Maven Central(オープンソースライブラリ)
  • JFrog Artifactory(サードパーティライブラリ)
  • AWS CodeArtifact(クラウド環境用)

開発者は、これらすべてをpom.xmlsettings.xmlに設定する必要があり、管理が煩雑になります。

5.2 仮想レジストリのアーキテクチャ

5.3 インテリジェントキャッシング

仮想レジストリのキャッシングは、単純なプロキシキャッシュとは異なります。

キャッシュ有効期間の戦略

デフォルト: 24時間
推奨設定(Maven Central): 0時間(無期限)
推奨設定(社内レジストリ): 1時間

Maven Centralは不変性を保証しているため、一度キャッシュしたパッケージは再検証不要です。一方、社内レジストリはSNAPSHOTバージョンが更新される可能性があるため、短い有効期間を設定します。

ネットワーク障害時のフォールバック

仮想レジストリがアップストリームに接続できない場合でも、キャッシュが存在すれば、有効期間外でもそのキャッシュを返します。これにより、外部レジストリの障害時でもビルドが継続できます。

5.4 アップストリーム優先順位の最適化

アップストリームの順序は、パフォーマンスに大きく影響します。

最適化の原則

  1. 最も頻繁に使用するレジストリを上位に配置

    • 社内レジストリ(80%のパッケージ)→ 優先度1
    • Maven Central(15%のパッケージ)→ 優先度2
    • その他(5%のパッケージ)→ 優先度3
  2. 地理的に近いレジストリを優先

    • 同一リージョンのレジストリ → 優先度高
    • 異なるリージョンのレジストリ → 優先度低
  3. 認証が不要なレジストリを優先

    • パブリックレジストリ → 優先度高
    • 認証が必要なレジストリ → 優先度低(認証オーバーヘッドを考慮)

5.5 クリーンアップポリシーによるストレージ最適化

GitLab 18.6以降、仮想レジストリにはクリーンアップポリシーが導入されました。

// GraphQL APIでクリーンアップポリシーを設定
{
  "cadence": "weekly",
  "retentionPeriod": 30
}

設定例

  • 頻度: 週次
  • 保持期間: 30日間ダウンロードされていないキャッシュを削除

これにより、使用されていない古いパッケージのキャッシュが自動的に削除され、ストレージコストを削減できます。

6. 依存関係プロキシ:Docker Hubレート制限の完全回避

6.1 Docker Hubレート制限の実態

Docker Hubのレート制限は以下の通りです。

アカウントタイプ 制限
匿名ユーザー 6時間あたり100プル(IPアドレス単位)
無料アカウント 6時間あたり200プル(ユーザー単位)
Pro/Teamアカウント 無制限

CI/CDパイプラインでは、以下のような状況でプルがカウントされます。

# .gitlab-ci.yml
# この設定では、ジョブ実行ごとに3回のプルが発生
image: node:18-alpine  # 1回目

services:
  - docker:24-dind     # 2回目

test:
  image: postgres:15   # 3回目
  script:
    - npm test

1日に50回パイプラインが実行されると、150プルとなり、無料アカウントの制限に到達します。

6.2 依存関係プロキシの動作原理

依存関係プロキシは、HEADリクエストを活用してレート制限を回避します。

重要なポイント

  • HEADリクエストはレート制限にカウントされない
  • マニフェストが変更されていない限り、キャッシュから返却
  • alpine:latestのような最新タグでも、実際に更新されたときだけプル

6.3 Docker Hub認証の設定

GitLab 17.10以降、Docker Hub認証をサポートしています。これにより、以下のメリットがあります。

  • レート制限が200プル/6時間に向上(無料アカウント)
  • プライベートイメージへのアクセスが可能

設定方法(UI)

  1. グループ設定 → パッケージとレジストリ
  2. 依存関係プロキシセクション
  3. Docker Hub認証
    • Identity: Docker Hubユーザー名
    • Secret: Personal Access Token

設定方法(GraphQL API)

mutation {
  updateDependencyProxySettings(input: {
    enabled: true,
    identity: "yamada-taro",
    secret: "dckr_pat_xxxxxxxxxxxx",
    groupPath: "my-group"
  }) {
    dependencyProxySetting {
      enabled
      identity
    }
    errors
  }
}

6.4 CI/CD内での活用

依存関係プロキシは、CI/CD変数を通じて自動的に利用できます。

# .gitlab-ci.yml
# 依存関係プロキシを使用した設定
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/node:18-alpine

services:
  - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:24-dind
    alias: docker

variables:
  DOCKER_HOST: tcp://docker:2375

test:
  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/postgres:15
  script:
    - npm test

build:
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

Dockerfileでの使用

# Dockerfile
# 依存関係プロキシ経由でベースイメージを取得
FROM gitlab.example.com:443/my-group/dependency_proxy/containers/node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .

CMD ["node", "server.js"]

ビルド時には、以下のように認証します。

# .gitlab-ci.yml
build-with-proxy:
  image: docker:24-cli
  services:
    - docker:24-dind
  before_script:
    - echo "$CI_DEPENDENCY_PROXY_PASSWORD" | docker login $CI_DEPENDENCY_PROXY_SERVER -u $CI_DEPENDENCY_PROXY_USER --password-stdin
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .

6.5 レート制限の確認方法

現在のレート制限状況を確認できます。

# .gitlab-ci.yml
check-rate-limit:
  stage: .pre
  image: alpine:latest
  before_script:
    - apk add curl jq
  script:
    - |
      TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token)
      curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1 | grep -i RateLimit
  allow_failure: true

出力例:

RateLimit-Limit: 200;w=21600
RateLimit-Remaining: 187;w=21600

7. Terraformモジュールレジストリ:Infrastructure as Codeの管理

7.1 Terraformモジュールの課題

Terraformモジュールを管理する際、以下の課題があります。

  • モジュールのバージョン管理が煩雑
  • 社内モジュールと外部モジュールの混在
  • モジュールの変更履歴が追跡できない

7.2 CI/CDテンプレートによる自動公開

GitLabは、Terraformモジュールの公開を自動化するテンプレートを提供しています。

# .gitlab-ci.yml
include:
  - template: Terraform-Module.gitlab-ci.yml

variables:
  TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR}
  TERRAFORM_MODULE_NAME: ${CI_PROJECT_NAME}
  TERRAFORM_MODULE_SYSTEM: aws
  TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG}

このテンプレートには、以下のジョブが含まれます。

1. fmt(フォーマット検証)

terraform fmt -check -recursive

2. kics-iac-sast(セキュリティスキャン)

Terraformコードの脆弱性をスキャンします。

3. deploy(モジュール公開)

タグがプッシュされたときのみ実行され、モジュールをレジストリに公開します。

7.3 モジュールの参照方法

名前空間レベルからの参照

# main.tf
module "vpc" {
  source = "gitlab.example.com/infrastructure/terraform-aws-vpc/aws"
  version = "1.2.0"
  
  cidr_block = "10.0.0.0/16"
  availability_zones = ["ap-northeast-1a", "ap-northeast-1c"]
}

プロジェクトレベルからの参照

# main.tf
module "vpc" {
  source = "https://gitlab.example.com/api/v4/projects/123/packages/terraform/modules/terraform-aws-vpc/aws/1.2.0"
  
  cidr_block = "10.0.0.0/16"
}

7.4 重複モジュールの管理

GitLab 16.8以降、重複するモジュール名の公開を許可できます。

ユースケース:マルチテナント環境

group-a/terraform-aws-vpc  (バージョン 1.0.0)
group-b/terraform-aws-vpc  (バージョン 2.0.0)

重複を許可することで、各チームが独自のバージョンを管理できます。

設定方法

  1. グループ設定 → パッケージとレジストリ
  2. Terraformモジュールの「重複を許可」をオン
  3. 例外パターンを正規表現で指定(オプション)
例外パターン: ^terraform-aws-.*
→ terraform-aws-で始まるモジュールは重複を許可しない

8. 実践シナリオ:マイクロサービス開発での活用

8.1 構成例

以下のようなマイクロサービスアーキテクチャを想定します。

my-company/
├── shared-libraries/          # 共通ライブラリ(Javaパッケージ)
├── api-gateway/               # APIゲートウェイ(コンテナ)
├── user-service/              # ユーザーサービス(コンテナ)
├── order-service/             # 注文サービス(コンテナ)
└── infrastructure/            # Terraformモジュール

8.2 共通ライブラリの管理

shared-libraries/.gitlab-ci.yml

include:
  - template: Maven.gitlab-ci.yml

variables:
  MAVEN_CLI_OPTS: "-s ci_settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

stages:
  - build
  - test
  - publish

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test
  coverage: '/Total.*?([0-9]{1,3})%/'

publish:
  stage: publish
  script:
    - mvn $MAVEN_CLI_OPTS deploy -DskipTests
  only:
    - tags
  artifacts:
    reports:
      dotenv: build.env

8.3 マイクロサービスでの共通ライブラリ利用

user-service/pom.xml

<project>
  <dependencies>
    <!-- GitLabパッケージレジストリから共通ライブラリを取得 -->
    <dependency>
      <groupId>com.mycompany</groupId>
      <artifactId>shared-libraries</artifactId>
      <version>1.2.0</version>
    </dependency>
  </dependencies>
  
  <repositories>
    <repository>
      <id>gitlab-maven</id>
      <url>https://gitlab.example.com/api/v4/projects/456/packages/maven</url>
    </repository>
  </repositories>
</project>

user-service/.gitlab-ci.yml

image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/maven:3.8-openjdk-17

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
  DOCKER_DRIVER: overlay2

stages:
  - build
  - test
  - package
  - deploy

build:
  stage: build
  script:
    - mvn clean compile
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .m2/repository

test:
  stage: test
  script:
    - mvn test
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .m2/repository
    policy: pull

package:
  stage: package
  image: docker:24-cli
  services:
    - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:24-dind
      alias: docker
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main

deploy:
  stage: deploy
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  script:
    - kubectl set image deployment/user-service user-service=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n production
  only:
    - main
  when: manual

8.4 インフラストラクチャのコード化

infrastructure/.gitlab-ci.yml

include:
  - template: Terraform-Module.gitlab-ci.yml

variables:
  TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR}/modules/vpc
  TERRAFORM_MODULE_NAME: terraform-aws-vpc
  TERRAFORM_MODULE_SYSTEM: aws
  TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG}

インフラストラクチャの適用

# production/main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# GitLabのTerraformモジュールレジストリから取得
module "vpc" {
  source = "gitlab.example.com/my-company/terraform-aws-vpc/aws"
  version = "1.0.0"
  
  cidr_block = "10.0.0.0/16"
  availability_zones = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  
  tags = {
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

module "eks" {
  source = "gitlab.example.com/my-company/terraform-aws-eks/aws"
  version = "2.1.0"
  
  cluster_name = "production-cluster"
  vpc_id = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnet_ids
}

9. パフォーマンス最適化とベストプラクティス

9.1 キャッシュ戦略

CI/CDキャッシュとの併用

# .gitlab-ci.yml
variables:
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

build:
  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/maven:3.8-openjdk-17
  script:
    - mvn clean package
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .m2/repository
      - target/

この設定により、以下の3層キャッシュが機能します。

  1. CI/CDキャッシュ: ブランチごとの依存関係
  2. 仮想レジストリ/依存関係プロキシ: グループレベルの共有キャッシュ
  3. ローカルビルド: 開発者のローカル環境

9.2 ネットワーク最適化

同一リージョン内でのレジストリ配置

GitLabインスタンス: ap-northeast-1
仮想レジストリのアップストリーム:
  1. 社内レジストリ(ap-northeast-1)
  2. AWS CodeArtifact(ap-northeast-1)
  3. Maven Central(グローバル)

地理的に近いレジストリを優先することで、ネットワーク遅延を最小化します。

9.3 ストレージ最適化

クリーンアップポリシーの設定

{
  "virtualRegistry": {
    "cleanupPolicy": {
      "cadence": "weekly",
      "retentionPeriod": 30
    }
  },
  "containerRegistry": {
    "cleanupPolicy": {
      "cadence": "daily",
      "keepN": 10,
      "olderThan": "90d",
      "nameRegex": ".*",
      "nameRegexKeep": "^(main|production)-.*"
    }
  }
}

ストレージ使用量の監視

# .gitlab-ci.yml
storage-report:
  stage: .post
  image: alpine:latest
  before_script:
    - apk add curl jq
  script:
    - |
      # グループのストレージ使用量を取得
      curl --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
        "https://gitlab.example.com/api/v4/groups/my-group/storage" | jq
  only:
    - schedules

10. セキュリティとコンプライアンス

10.1 脆弱性スキャン

コンテナイメージのスキャン

# .gitlab-ci.yml
include:
  - template: Security/Container-Scanning.gitlab-ci.yml
  - template: Security/Dependency-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

パッケージの脆弱性スキャン

# .gitlab-ci.yml
dependency_scanning:
  variables:
    DS_EXCLUDED_PATHS: "spec,test,tests,tmp"

10.2 アクセス制御

最小権限の原則

開発者(Developer):
  - パッケージの公開
  - コンテナイメージのプッシュ

レポーター(Reporter):
  - パッケージの取得
  - コンテナイメージのプル

メンテナー(Maintainer):
  - パッケージの削除
  - レジストリ設定の変更

オーナー(Owner):
  - 監査イベントの有効化
  - クリーンアップポリシーの設定

10.3 監査ログの活用

監査イベントのクエリ(GraphQL)

query {
  group(fullPath: "my-group") {
    auditEvents(first: 100, after: "2024-01-01") {
      nodes {
        id
        author {
          name
        }
        entity {
          ... on Package {
            name
            version
          }
        }
        action
        createdAt
        ipAddress
      }
    }
  }
}

11. 移行ガイド:既存環境からの移行

11.1 JFrog ArtifactoryからGitLabへの移行

ステップ1: パッケージのエクスポート

# JFrog CLIを使用してパッケージをエクスポート
jfrog rt download "libs-release-local/*" ./export/

ステップ2: GitLabへのインポート

# GitLab Package Importerを使用
for file in ./export/**/*.jar; do
  mvn deploy:deploy-file \
    -DgroupId=com.example \
    -DartifactId=$(basename $file .jar) \
    -Dversion=1.0.0 \
    -Dpackaging=jar \
    -Dfile=$file \
    -DrepositoryId=gitlab-maven \
    -Durl=https://gitlab.example.com/api/v4/projects/123/packages/maven
done

ステップ3: 段階的な移行

<!-- pom.xml -->
<repositories>
  <!-- 移行期間中は両方を設定 -->
  <repository>
    <id>artifactory</id>
    <url>https://artifactory.example.com/libs-release</url>
  </repository>
  <repository>
    <id>gitlab-maven</id>
    <url>https://gitlab.example.com/api/v4/projects/123/packages/maven</url>
  </repository>
</repositories>

11.2 Docker HubからGitLabコンテナレジストリへの移行

ステップ1: イメージのリスト取得

# Docker Hubからイメージリストを取得
curl -s "https://hub.docker.com/v2/repositories/mycompany/?page_size=100" | jq -r '.results[].name'

ステップ2: イメージの移行

#!/bin/bash
DOCKER_HUB_ORG="mycompany"
GITLAB_REGISTRY="registry.gitlab.com/my-group"

for image in $(cat image-list.txt); do
  # Docker Hubからプル
  docker pull $DOCKER_HUB_ORG/$image:latest
  
  # GitLabレジストリにタグ付け
  docker tag $DOCKER_HUB_ORG/$image:latest $GITLAB_REGISTRY/$image:latest
  
  # GitLabレジストリにプッシュ
  docker push $GITLAB_REGISTRY/$image:latest
done

ステップ3: CI/CDパイプラインの更新

# 移行前
image: mycompany/app:latest

# 移行後
image: ${CI_REGISTRY_IMAGE}:latest

12. トラブルシューティング

12.1 依存関係プロキシの認証エラー

エラー: HTTP Basic: Access Denied

原因: 2要素認証が有効になっている場合、パスワードではなくPersonal Access Tokenが必要です。

解決策:

# .gitlab-ci.yml
variables:
  # パスワードではなくPersonal Access Tokenを使用
  CI_DEPENDENCY_PROXY_PASSWORD: ${GITLAB_PAT}

12.2 仮想レジストリのキャッシュミス

症状: 同じパッケージを何度もダウンロードしている

原因: キャッシュ有効期間が短すぎる、またはアップストリームの優先順位が最適化されていない

解決策:

mutation {
  updateVirtualRegistryUpstream(input: {
    id: "gid://gitlab/VirtualRegistries::Packages::Maven::Upstream/1",
    cacheValidityHours: 0  # Maven Centralは無期限キャッシュ
  }) {
    upstream {
      cacheValidityHours
    }
  }
}

12.3 コンテナレジストリの容量不足

症状: insufficient storage エラー

解決策: クリーンアップポリシーの設定

# .gitlab-ci.yml
cleanup-old-images:
  stage: .post
  image: alpine:latest
  before_script:
    - apk add curl jq
  script:
    - |
      # 90日以上前のイメージを削除
      curl --request DELETE \
        --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
        "https://gitlab.example.com/api/v4/projects/$CI_PROJECT_ID/registry/repositories/$REPOSITORY_ID/tags?name_regex=.*&older_than=90d"
  only:
    - schedules

13. まとめ:次のステップ

GitLabのパッケージ管理機能は、以下の価値を提供します。

13.1 定量的な効果

ビルド時間の短縮

  • 依存関係プロキシ導入前: 平均5分
  • 導入後: 平均2分(60%削減)

コスト削減

  • Docker Hub Pro不要(年間$60/ユーザー × 50ユーザー = $3,000削減)
  • 外部レジストリのトラフィック削減(月間$500削減)

セキュリティ向上

  • 脆弱性検出率: 95%以上
  • 監査イベントによる完全なトレーサビリティ

13.2 推奨される導入順序

フェーズ1: 依存関係プロキシ(1週間)

  1. グループレベルで依存関係プロキシを有効化
  2. CI/CD変数を更新(CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIXの使用)
  3. Docker Hubレート制限の監視

フェーズ2: パッケージレジストリ(2週間)

  1. 共通ライブラリをパッケージレジストリに移行
  2. CI/CDパイプラインで自動公開を設定
  3. 監査イベントを有効化

フェーズ3: コンテナレジストリ(2週間)

  1. コンテナイメージをGitLabレジストリに移行
  2. Cosign署名の導入
  3. クリーンアップポリシーの設定

フェーズ4: 仮想レジストリ(3週間)

  1. アップストリームレジストリの洗い出し
  2. 仮想レジストリの作成と優先順位設定
  3. キャッシュ有効期間の最適化

13.3 継続的な改善

月次レビュー

  • ストレージ使用量の確認
  • キャッシュヒット率の分析
  • レート制限の監視

四半期レビュー

  • アップストリーム優先順位の見直し
  • クリーンアップポリシーの調整
  • セキュリティスキャン結果の分析

GitLabのパッケージ管理機能を活用することで、開発チームはインフラストラクチャの管理から解放され、本質的な開発作業に集中できます。まずは依存関係プロキシから始めて、段階的に機能を拡張していくことをお勧めします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?