公開:2025年2月13日

1分で読めます

Amazon ECRからGitLabへのコンテナイメージ移行の自動化

プラットフォームチームがCI/CDをGitLabに移行する際、コンテナイメージの移行がボトルネックになってはなりません。このガイドでは、パイプライン移行を自動化する方法を詳しく解説します。

「Amazon Elastic Container Registry(ECR)からGitLabに数百ものコンテナイメージを移行する必要があるのですが、手伝ってもらえますか?」これまでのプラットフォームエンジニアとの会話の中で、何度もこの質問が出てきました。彼らは、DevSecOpsツールチェーンをGitLabに統合してモダナイズしようとしていたものの、コンテナイメージの移行の箇所でつまずいていました。個々のイメージの移行は簡単でも、数が多すぎると、手作業で行うのは現実的ではありません。

まさに、あるエンジニアは「やるべきことはわかっています。プルして、再タグ付けして、プッシュするだけです。しかし、マイクロサービスが200個もあり、それぞれに複数のタグがあります。インフラストラクチャ関連の重要な仕事が山積みの中、この移行作業に何週間も費やすわけにはいきません」と話していました。

課題

この会話をきっかけに、プロセス全体を自動化できないかと考えました。CI/CDをGitLabに移行する際、コンテナイメージの移行がボトルネックになってはなりません。手作業はシンプルですが、繰り返しが多すぎます。各イメージをプルし、再タグ付けし、GitLabのコンテナレジストリにプッシュする…これを数十のリポジトリ、各イメージの何百ものタグに対して行うとなると、数日から数週間かかる途方もない作業になります。

解決策

そこで、こういった大変な作業を自動処理するGitLabパイプラインの作成に取り掛かりました。目標はシンプルです。プラットフォームエンジニアが数分でセットアップできて、一晩放置すればすべてのイメージの移行が完了している、そんなツールを作ることでした。

アクセス権の設定

まずはセキュリティです。チームが最小限のAWS権限でこの移行作業を実行できるようにすることを重視しました。以下の読み取り専用のアイデンティティおよびアクセス管理(IAM)ポリシーを用意しました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecr:DescribeImages",
                "ecr:BatchGetImage"
            ],
            "Resource": "*"
        }
    ]
}

GitLabの設定

セキュリティの次はGitLab側の設定です。最小限の構成で済むようにしました。CI/CD設定で以下の変数を設定します。

AWS_ACCOUNT_ID: AWSのアカウントID
AWS_DEFAULT_REGION: ECRのリージョン
AWS_ACCESS_KEY_ID: [マスク]
AWS_SECRET_ACCESS_KEY: [マスク]
BULK_MIGRATE: true

移行パイプライン

ここからが本番です。このパイプラインはDocker-in-Dockerを使って構築し、すべてのイメージ操作を安定して実行できるようにしました。

image: docker:20.10
services:
  - docker:20.10-dind

before_script:
  - apk add --no-cache aws-cli jq
  - aws sts get-caller-identity
  - aws ecr get-login-password | docker login --username AWS --password-stdin
  - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}

このパイプラインは3つのフェーズで構成され、それぞれが前のフェーズをベースにします。

  1. 検出

まず、すべてのECRリポジトリを取得します。

REPOS=$(aws ecr describe-repositories --query 'repositories[*].repositoryName' --output text)
  1. タグの列挙

次に、各リポジトリの全タグを取得します。

TAGS=$(aws ecr describe-images --repository-name $repo --query 'imageDetails[*].imageTags[]' --output text)
  1. 移行

最後に、実際にイメージ移行を実行します。

docker pull ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag}
docker tag ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag} ${CI_REGISTRY_IMAGE}/${repo}:${tag}
docker push ${CI_REGISTRY_IMAGE}/${repo}:${tag}

期待できる成果

移行に何週間もかける時間がないというプラットフォームエンジニアのために、このソリューションは次のような成果を提供します。

  • すべてのリポジトリとタグを自動的に検出・移行
  • ECRとGitLabのイメージ命名規則を統一
  • 転送失敗時のエラーハンドリング
  • 進捗を追跡できる明確なログ

移行スクリプトを書いたり、移行作業を監視したりする必要がなくなり、プラットフォームエンジニアは他の重要な作業に集中できるようになります。

使い方

手順はシンプルです。

  1. .gitlab-ci.ymlをリポジトリにコピー
  2. AWSとGitLabの変数を設定
  3. BULK_MIGRATEを「true」に設定して、移行を開始

ベストプラクティス

さまざまなチームの移行を支援する中で、いくつかの重要なポイントが見えてきました。

  • ピーク時以外に実行し、チームへの影響を最小限に抑える
  • パイプラインのログを確認し、必要な対応がないかチェックする
  • すべてのイメージが正常に転送されたことを確認するまで、ECRを廃止しない
  • 大規模な移行の場合、ネットワーク負荷を避けるためにレート制限の適用を検討する

このパイプラインは、GitLabの公開リポジトリでオープンソースとして提供しています。プラットフォームエンジニアがコンテナイメージの移行に時間を取られるのではなく、本来の業務に専念できるよう設計されています。ニーズに応じてカスタマイズしてお使いください。実装についてのご質問もお待ちしています。

このパッケージおよびその他のコンポーネントの詳細については、CI/CDカタログのドキュメントをご覧ください。

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成して、ご意見をお聞かせください。

フォーチュン100企業の50%以上がGitLabを信頼

より優れたソフトウェアをより速く提供

インテリジェントなDevSecOpsプラットフォームで

チームの可能性を広げましょう。