公開:2025年2月13日

6分で読めます

Amazon ECRからGitLabへ:移行の自動化

GitLabのCI/CD移行でコンテナイメージ移行を自動化し、遅延を防ぐ方法を解説します。

「Amazon Elastic Container Registry(ECR)からGitLabに数百ものコンテナイメージを移行する必要があるのですが、手伝ってもらえますか?」この質問はプラットフォームエンジニアとの会話で何度も出てきました。彼らはGitLabを使ってDevSecOpsツールチェーンをモダナイズしていましたが、コンテナイメージの移行でつまずいていたのです。個々のイメージ移行は簡単でも、数が膨大で手間がかかるため、ハードルが高く感じられていました。

あるプラットフォームエンジニアは的確にこう言いました。「やるべきことはわかっています。プルして、再タグ付けして、プッシュする。ただ、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アカウント番号
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. 検出

すべてのリポジトリ名を取得します。

```bash
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プラットフォームで

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