7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Gitlab CI Runner のジョブに AWS ECR のイメージを使う

Posted at

Gitlab Runner で実行するジョブのイメージを Amazon ECR から Pull する方法(ジョブの中で docker pull という話ではなく)。

要するに .gitlab-ci.yml で下記のように ECR のイメージを指定できるようにするということです。

test:
  stage: test
  image: 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/oreore:latest
  script:
    - make test

前提として Gitlab Runner が docker-credential-ecr-login (amazon-ecr-credential-helper) の Credentials store を使って ECR にログインできるようにする必要があるため、Gitlab Runner のイメージに docker-credential-ecr-login を追加したイメージを作成しました。

手順

# ディレクトリを準備
mkdir -p /opt/gitlab-runner/{ecr,runner}

# 環境変数で AWS 認証情報を指定
cat <<'EOS'> /opt/gitlab-runner/.env
AWS_ACCESS_KEY_ID=AKI...
AWS_SECRET_ACCESS_KEY=abc123...
EOS

# Gitlab Runner を開始
# --env-file で環境変数ファイルを指定
docker run --detach \
    --name gitlab-runner \
    --env-file /opt/gitlab-runner/.env \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --volume /opt/gitlab-runner/runner/:/etc/gitlab-runner/ \
    --volume /opt/gitlab-runner/ecr/:/root/.ecr/ \
    ngyuki/gitlab-runner:alpine

# Gitlab に Runner を登録
# DOCKER_AUTH_CONFIG で Credentials store を指定
docker exec gitlab-runner gitlab-runner register \
    --non-interactive \
    --url 'http://gitlab.example.com/' \
    --registration-token "${REGISTRATION_TOKEN:?}" \
    --name 'docker-runner-with-ecr' \
    --executor 'docker' \
    --docker-image 'alpine:latest' \
    --env 'DOCKER_AUTH_CONFIG={"credsStore":"ecr-login"}'

# docker-credential-ecr-login get で ECR 認証情報を `~/.ecr/cache.json` に保存
echo 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com | docker exec -i gitlab-runner docker-credential-ecr-login get

詳細

Docker の Credentials store の指定

Docker の Credentials store は Gitlab のプロジェクトの CI のDOCKER_AUTH_CONFIG 変数に以下のような JSON の内容をそのまま指定できます。

{
    "credsStore": "ecr-login"
}

もしくは gitlab-runner register--env 'DOCKER_AUTH_CONFIG={"credsStore":"ecr-login"}' のようにコマンドラインオプションを指定すれば、この Gitlab Runner が実行するすべてのジョブの変数に自動的に追加されるので、プロジェクトで個別に指定する必要はなくなります。

DOCKER_AUTH_CONFIG はもともとは次のようなプライベートレジストリの認証情報を指定するためのものですが、

{
    "auths": {
        "registry.example.com:5000": {
            "auth": "b3JlX25vX2hpbWl0dQo="
        }
    }
}

ECR の場合 aws ecr get-login で取得したトークンは12時間で有効期限切れになるため、上のようにベタで指定することはできません。

Add support for credentials store (!501) · Merge Requests で Gitlab Runner で Credentials store がサポートされるようになったので、前述のように ecr-login が指定できます。ただし、Docker CLI と同等ではないので下記のような credHelpers とかは対応していません。

{
    "credHelpers": {
        "999999999999.dkr.ecr.ap-northeast-1.amazonaws.com": "ecr-login"
    }
}

credsStore のみがベタで対応されているようです。

ただ、ひとつのプロジェクトで複数のレジストリで Credentials store を使い分けるとかでも無い限りは問題なさそうです。

なお、~/.docker/config.json に記述しても有効なので、DOCKER_AUTH_CONFIG の代わりに ~/.docker/config.json を作成しても OK です。

ECR 認証情報の取得

Gitlab Runner が Credentials store を使用するとき、list サブコマンドですべての認証情報を取得しようとします。

docker-credential-ecr-login list~/.ecr/cache.json に記録されている ECR の認証情報の一覧を返します。docker-credential-ecr-login get で認証情報を取得すると ~/.ecr/cache.json へキャッシュとして保存されるため、あらかじめ手動で認証情報を取得しておきます。

あるいは、~/.ecr/cache.json がなければ docker-credential-ecr-login listAWS_REGION 環境変数で指定されたリージョンの ECR の認証情報を返すので、docker-credential-ecr-login get を手で実行する代わりに AWS_REGION 環境変数を指定しておいても OK です。

# 環境変数でリージョンも指定
# (docker-credential-ecr-login get は不要)
cat <<'EOS'> /opt/gitlab-runner/.env
AWS_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=AKI...
AWS_SECRET_ACCESS_KEY=abc123...
EOS

もしくは、環境変数 AWS_SDK_LOAD_CONFIG=true があれば ~/.aws/config からでもリージョンを得られるので、AWS_REGION 環境変数の代わりに使用することもできます。

さいごに

Credentials store を使わなくても cron とかで定期的に $(aws ecr get-login --no-include-email) して ~/.docker/config.json の認証情報を更新すれば大丈夫だろうと思いますが、余分な処理が不要な分 docker-credential-ecr-login を使うほうがよいでしょう。

参考

7
8
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
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?