ECS, ECRによるコンテナイメージ作成から、インターネットアクセスまで
概要
本ハンズオンでは、ECS / ECRによるコンテナイメージを作成しAWS上でコンテナを動かして、インターネットからアクセスするまでの流れを整理する。全体の流れは、以下の通り。
- AWS Cloud9でコンテナイメージを作成する。その際、Dockerfileを使用する
- ECRにより、作成したコンテナイメージをアップロードする
- ECSとFargateを使用して、コンテナを実行する。その際、ECSのタスク定義とサービス作成を行う。
- 動かしたコンテナイメージに対して、インターネットからアクセスする
- 最後に、ECSによるコンテナのスケジューリングとスケーリングを体験する
最終的なゴールを以下に示す。
Cloud9構築
下記パラメータで、cloud9を構築する。
- Environment type: Create a new EC2 instance for environment (direct access)
- Instance type: t3.small (2 GiB RAM + 2 vCPU)
- Platform: Amazon Linux 2 (recommended)
- Cost-saving setting: After 30 minutes (default)
cloud9構築後、AWS CLoud9環境のPublic IPアドレスを取得し、手元に残す
Admin:~/environment $ curl http://checkip.amazonaws.com
<AWS Cloud9 環境の Public IP アドレス>
コンテナイメージ作成
コンテナイメージ作成の流れを説明する。
- Dockerfileという、コンテナイメージ作成で使うファイルを用意
- docker buildコマンドにより実行
- AWS Cloud9のLinux環境上にコンテナイメージが作成される
まず、cloud9上でDockerfileを作成する。その後、下記ファイルをコピペする。下記コードは、Dockerコンテナ内で動作するApache Webサーバを構築するためのもので、Ubuntu 18.04ベースのDockerイメージを使用して、Apache Webサーバーをインストールしている。
# Ubuntu 18.04をベースとするDockerイメージを使用することを指定
FROM ubuntu:18.04
# コンテナ内でパッケージの更新を行い、Apache2をインストールするためのaptコマンドを実行
RUN apt-get update && \
apt-get -y install apache2
# /var/www/html/index.htmlというファイルに "Hello World!" というテキストを書き込むためのechoコマンドを実行
RUN echo 'Hello World!' > /var/www/html/index.html
# Configure apache
RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && \
echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh && \
echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh && \
echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh && \
chmod 755 /root/run_apache.sh
# コンテナが使用するポートを80で指定して、HTTP通信をしている
EXPOSE 80
# コンテナ実行時に動かすコマンドを指定、webサーバを起動するシェルスクリプトを指定している。
CMD /root/run_apache.sh
今回は、hello-worldと名前をつけて、イメージ作成する。docker imagesと入力することで、新たにコンテナイメージが作成されたか確認できる。
docker build -t hello-world .
次に、作成したコンテナをCloud9で動かす。下記の通り、docker runをすることでコンテナを動かせる。以下コマンドでは、ホスト側の8080ポートをコンテナがわの80ポートに割り当てて、h4b-local-runという名前でコンテナを動かしている。docker psと入力すると、コンテナが稼働していることを確認できる。
docker run -d -p 8080:80 --name h4b-local-run hello-world
また、8080:80と指定したので、localhost:80にリクエストを投げると、レスポンスが帰ってくることを確認できる。
curl localhost:8080
ECRにアップロード
Cloud9で作成したコンテナイメージをECRにアップロード(Push)する。まずECRでリポジトリを作成する。作成方法については、下記ページを参照すること。
次に作成したリポジトリに対して、コンテナイメージをアップロードする。cloud9上のコンテナイメージをリポジトリに紐づけるために、リポジトリの名前を使ったtagを付与する。このコマンドで、現在のディレクトリのDockerfileを使って、コンテナイメージをビルドする。コンテナイメージには、リポジトリの名前がタグづけされる。
docker build -t 638182392525.dkr.ecr.ap-northeast-1.amazonaws.com/h4b-ecs-helloworld:0.0.1 .
次にAWSのECRにログインする。
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 638182392525.dkr.ecr.ap-northeast-1.amazonaws.com
最後に、前のステップでビルドしたコンテナをECRにpushする。pushしたイメージは、その後ECSやEKSで使用できる。
docker push 638182392525.dkr.ecr.ap-northeast-1.amazonaws.com/h4b-ecs-helloworld:0.0.1
ECSの作成
VPCの作成
ECSクラスターを作成するために、新しくVPCを作成する。もしくは、既存のVPCを利用する形でも問題ない。詳しい内容は、下記リンクを参照すること。VPC内の二つのavailability zoneにて、二つのパブリックサブネットを構築する必要がある。
上記作成後、ECSで動かすコンテナに対して、インターネットからHTTPアクセスを受けるために、セキュリティグループの修正をする。ハンズオンではセキュリティを考慮して、ハンズオンをしている端末のIPアドレスのみ許可する。本番環境では、0.0.0.0/0のようにインターネット全体に公開する。こちらに加えて、AWS Cloud9のIPアドレスを許可する。
ECSクラスターの作成
ECSクラスターとは、コンテナを動かすための論理的なグループである。ECSを操作するために、まずはECSクラスタを作成する。作成手順は、以下の通り。
タスク定義
次に、アプリケーションを動かすために、どのようにコンテナを動かすか、コンテナの動作を定義する。例えば、コンテナイメージの種類、アプリケーションが使用するポート、コンテナが利用するデータボリュームを指定する。具体の作業手順は、以下を参照すること。
今回のハンズオンでは、使用するイメージURI、コンテナポートといったタスクを定義する。
サービスの作成
サービスとは、ECS上でコンテナを動かすときに利用する概念の一つである。サービスを利用する際、ECSクラスターで、指定した数のコンテナ群(タスク)を維持できる。たとえば、障害発生時にコンテナ群を再作成してくれるプロセスが走るため、長期間動かすアプリケーションが開発できる。必要なタスクを2とすることで、ロードバランサも自動的に作成される。詳しい作成手順は、以下を参照すること。
上記により、ECSとFargateを組み合わせたコンテナを稼働させて、インターネットからALB経由でアクセスできるようになった。
運用負担軽減を体験
自動復旧
今回のハンズオンでは、擬似的に障害を起こして、ECSサービスによりコンテナが再作成される様子を見る。動かすべきタスクの数を満たすように、自動的にECSサービスが再作成する。
それでは、1個目のタスクを停止して、自動復旧される様子を確認する。ECSクラスターのタスクから、タスクの停止をする。
タスクの停止をしたので、実際のタスクの数は2より少なくなっている。ECSはこれを検知して、自動的に新しいコンテナを立ち上げる。
スケール変更
サービス配下で動かしているタスク(コンテナ)の数を増減する内容である。
必要なタスクを2から3に変更し更新する。
そうすると、自動的にサービスで必要なタスクが作成される。
参考文献
Discussion