こんにちは。FLINTERSでデータエンジニアをしている栗原です。今回の投稿はFLINTERSブログ祭りの記事です。テーマは #技術 です。
AWS ECRとは??
AWS Elastic Container Registry
の略で、柔軟性の高いDockerコンテナイメージの格納場所を提供します。簡単に言えば、AWSの提供するDockerイメージ用のリモートリポジトリです。
基本的にはDocker Hubのリポジトリと似たような機能を持っています。
項目 | AWS ECR | Docker Hub |
---|---|---|
開発者 | Amazon | Docker社 |
用途 | Dockerイメージのリモートリポジトリ | Dockerイメージのリモートリポジトリ |
このように、どちらもリモートでDockerイメージを管理するためのサービスですが、それぞれの提供者によって開発されています。AWS ECRはAmazonのエコシステムと統合されており、特にAWSを利用するプロジェクトでは便利です。
リモートリポジトリへログインする
上記ドキュメントにECRでの認証方法が記述されています。自分は以下のコマンドをよく使用しています。
aws ecr get-login-password | docker login --username AWS --password-stdin <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com
Publicリポジトリを対象にpushする場合は以下のコマンド。
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
ログインコマンド詳細
aws ecr get-login-password
このコマンドで、ECRリポジトリの認証用パスワードを取得しています。
この時、環境変数AWS_ACCESS_SECRET_KEY
とAWS_SECRET_ACCESS_KEY_ID
とAWS_DEFAULT_REGION
が認証のために必要になります。
export AWS_ACCESS_KEY_ID = <your_access_key_id>
export AWS_SECRET_ACCESS_KEY = <your_secret_accesss_key>
export AWS_DEFAULT_REGION = <your_region>
docker login --username AWS --password-stdin
先ほど取得した認証用パスワードを標準入力から受け取り、docker-cliを使用して認証を実行するコマンドです。認証に成功すると、ECRのプライベートリポジトリに対してpush
やpull
ができるようになります。
repository-url = <account_id>.dkr.ecr.<region>.amazonaws.com
Finchとdocker-cli
上記の説明ではdocker-cliのdocker login
コマンドを使用してログインしています。docker-cliはオープンソースであり、多くの開発者に広く使われているためです。
しかし、最近はDocker Desktopの有償化に伴い、他のCLIツールからDockerを使用する動きが増えています。特に注目されているのが、AWS製のFinchです。ECRはAWSのサービスであるため、AWS製ツールであるFinchを使用することで、よりシームレスな統合が可能となります。
Finchについて
最近、AWSはDocker Desktopの代替ツールとしてFinchを発表しました。2023年11月頃にMac版がGA、2024年2月頃にWindows版がGAされたようです。
Finchは軽量で効率的なコンテナ管理ツールであり、特にDocker Desktopの有償化に伴い注目を集めています。
- Finchの特徴
- 軽量で高性能
- AWSとシームレスに統合
- オープンソース
- 公式GitHubページ
今後はAWSとの連携機能等の向上も期待でき、ECRを利用する場合には導入を考えてみても良さそうです。
ECRからイメージをpullする
docker pull <your-aws-account-id>.dkr.ecr.<your-region>.amazonaws.com/<your-repository-name>:<tag>
ログインした後であれば、認証が通ったプライベートリポジトリからイメージをpullしてくることが可能になります。
Tips: Amazon ECR Publicからコンテナイメージをpullしてくる
ECRでは、Publicでもいくつかのコンテナイメージを公開しています。例えば、AmazonlinuxOSのコンテナイメージは以下の手順でPublic ECRからpullできます。
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
docker pull public.ecr.aws/amazonlinux/amazonlinux:latest
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/amazon_linux_container_image.html
ECRからpullしたイメージを拡張する
例として、ECR Publicで公開されているamazonlinux2に、python3.9をインストールしてみます。
# Dockerfile
FROM public.ecr.aws/amazonlinux/amazonlinux:2
# Install necessary packages
RUN yum update -y \
&& yum install -y gcc openssl-devel bzip2-devel libffi-devel wget tar gzip make \
&& yum clean all
# Set the Python version we want to install
ENV PYTHON_VERSION=3.9.13
# Download, compile, and install Python
# 参考: https://qiita.com/hiren/items/17984191da2ab8955174
RUN cd /opt \
&& wget https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz \
&& tar xzf Python-$PYTHON_VERSION.tgz \
&& cd Python-$PYTHON_VERSION \
&& ./configure --enable-optimizations \
&& make altinstall \
&& rm -f /opt/Python-$PYTHON_VERSION.tgz
RUN echo 'alias python=python3.9' >> ~/.bashrc
RUN source ~/.bashrc
# pipenv install
RUN pip3.9 install --upgrade pip \
&& pip3.9 install pipenv
# package install by pipenv
RUN pipenv install pytest==7.4.0
上記のDockerfileを作成後、docker build
コマンドでイメージを作成します。
この時、ベースとなるDockerイメージpublic.ecr.aws/amazonlinux/amazonlinux:2
がローカルに無い場合、自動でdocker pull
が動作しますが、認証を通していないとエラーになるため注意しましょう。
docker build -t <image_name>:<tag_name> .
タグ名を付け間違えた場合に、tagを付け替える際は以下のコマンド。(元のタグ名のイメージも残ります)
docker tag MISS_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Tips: Dockerコンテナ内に入りカスタマイズしたコンテナからイメージを作成する
Dockerコンテナ内に入り、カスタマイズした後でそのコンテナから新しいイメージを作成する方法もあります。以下の手順で実行できます。
1: コンテナを起動し、シェルに入る。
docker run -it --name my_custom_container public.ecr.aws/amazonlinux/amazonlinux:2 /bin/bash
2: 必要な変更を行う。例えば、パッケージのインストールなどを行う。
yum install -y python3.9
3: 変更が完了したら、別のターミナルを開き、カスタマイズしたコンテナから新しいイメージを作成する。
docker commit my_custom_container my_custom_image:latest
4: 必要に応じて、イメージにタグを付ける。
docker tag my_custom_image:latest my_custom_image:v1.0
※ ただし、この方法では何を変更したのかを追跡するのが難しいので、通常はDockerfileを使って新しいイメージを作成することが推奨されます。また、この方法では作成したイメージに含まれる変更点が明確に記録されないため、再現性や移植性に問題が生じる可能性があります。
作成したイメージの動作確認をする
以下コマンドでカレントディレクトリの<sample_file>.py
を実行し、コンテナが正しく動作するか確認します。
docker run -v $(pwd):/app --rm <image_name>:<tag_name> python /app/<sample_file>.py
作成したイメージをECRにpushする
※ あらかじめ、コンソールまたはCLIからECRリポジトリを作成する必要があります。
ECRにpushするためには、以下のようにイメージ名にaccount_id
などの情報も含めたイメージ名に変更しておく必要があります。
$ docker tag [target_image]:[target_tag] [account_id].dkr.ecr.[region].amazonaws.com/[upload_image]:[upload_tag]
docker tag pipeline-upd-newtag:3.9.0 183780520150.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository:new.tag.1.0
その後、docker push
します。
$ docker push [account_id].dkr.ecr.[region].amazonaws.com/[upload_image]:[upload_tag]