技術1課の櫻井です。 自分の勉強も兼ねてECSでコンテナをデプロイするハンズオンを行ってみました。 といっても最初からECSに触れるのではなく、自分でコンテナイメージを作成するところから行ってみようと思います。
今回の目標
今回の最終目標は、ECSを用いてコンテナをデプロイ&インターネットからそのコンテナにアクセスするというものになります。 下の画像のような簡単なWebページを作成していきます。 構成としては以下のような形となります。
初めに自分の環境でコンテナイメージを作成、作成したイメージをECRにアップロード、アップロードしたイメージをECSにデプロイといった流れで進めて行きます。
コンテナイメージの作成
コンテナイメージとは簡単にまとめると、「コンテナの内容を記したテンプレート」になります。コンテナそのものと混同するかもしれませんが、コンテナはこのコンテナイメージを基に作成されます。CloudFormationテンプレートがある環境の構成情報をまとめているようなもので、コンテナイメージにはコンテナのOSやミドルウェアの情報が含まれます。まずは自分でこれを作成してみましょう。作成する環境はCloud9を利用します。
Cloud9の準備
①Cloud9のコンソール画面に移動して以下の設定でCloud9を作成 Cloud9の作成完了まで2~3分待ちます。
②Cloud9の作成が完了したら実際に環境に入ってみる Cloud9のコンソールから先ほど作成したものの[開く]を選択してください。
するとIDEが表示されます。次はこのIDEの画面下のターミナルから実際にコンテナイメージを作成してみます。
自分でコンテナイメージを作成してみる
コンテナイメージの作成には後述するDockerfile利用して自動化するのが一般ですが、その利点を理解するためにもまずは手動でコンテナイメージを作成してみましょう。
① docker pullコマンドでUbuntuのコンテナイメージをダウンロード まずはUbuntuのOS情報が含まれる必要最低限のコンテナイメージをダウンロードします。
administrator:~/environment $ docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu 6b851dcae6ca: Pull complete Digest: sha256:6120be6a2b7ce665d0cbddc3ce6eae60fe94637c6a66985312d1f02f63cc0bcd Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latest
② docker images コマンドを実行 先ほどダウンロードしたイメージが確認できます。 必要最低限の情報なのでイメージのサイズは非常に小さいです。
administrator:~/environment $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 99284ca6cea0 3 weeks ago 77.8MB
③ docker psコマンドで現在起動しているコンテナを確認 まだコンテナを起動していないので何も表示されません。
administrator:~/environment $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
④ docker run コマンドでコンテナを起動 プロンプトが $ から # に変更しています。# 表記のプロンプトで実行するコマンドはコンテナ内で実行されるので、 これでコンテナの中に入ったことがわかります。
administrator:~/environment $ docker run -it --name apache ubuntu root@ec13f9e3fee4:/#
⑤ コンテナにApache をインストール Ubuntuのコンテナが起動しましたがこのままでは何も入っていないのでApacheを入れます。
はじめにパッケージリストを更新します。
root@ec13f9e3fee4:/# apt-get update Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB] (略)
次にApacheをインストールします。
root@ec13f9e3fee4:/# apt-get install apache2 -y Reading package lists... Done Building dependency tree... Done Reading state information... Done (略)
⑥ Apacheの動作確認
Apacheを起動してみます。
root@ec13f9e3fee4:/# service apache2 start * Starting Apache httpd web server apache2 (略) root@ec13f9e3fee4:/# service apache2 status * apache2 is running
起動できたので、curlコマンドでサンプルページをみてみます。
root@ec13f9e3fee4:/# curl localhost <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <!-- Modified from the Debian original for Ubuntu Last updated: 2022-03-22 See: https://launchpad.net/bugs/1966004 --> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Apache2 Ubuntu Default Page: It works</title> <style type="text/css" media="screen"> (略) </body> </html>
サンプルページのHTMLが表示されました。
⑦ コンテナイメージとして保存する。 Apacheが入っている状態のコンテナをイメージとして保存してみます。
まずコンテナから抜けます。
root@ec13f9e3fee4:/# exit exit administrator:~/environment $
次にdocker commit コマンドで先ほど操作していたコンテナ apcaheをコンテナイメージapache_imageとして保存します。
administrator:~/environment $ docker commit apache apache_image sha256:299f7daead4567cde187653c38f17ef1056eed031108850b8ac25f4d9b14fc01
docker imagesコマンドを使用するとapache_imageというコンテナイメージが作成されていることがわかります。
administrator:~/environment $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE apache_image latest 299f7daead45 9 seconds ago 227MB ubuntu latest 99284ca6cea0 3 weeks ago 77.8MB
これでapacheが含まれるコンテナイメージが作成できました。 今回はApacheのインストールのみだったため簡単でしたが、 実際にコンテナの中に入ってカスタマイズするのは手間が多いです。 そこで次はDockerfileを使用して簡単にコンテナイメージを作成してみます。
Dockerfileからコンテナイメージを作成
Dockerfileとは、コンテナイメージの設計図のようなものです。 新規にコンテナイメージを作成する際の手順を記したテキストファイルになります。 このDockerfileを使用することで、Dockerfileに記述された指示を基にコンテナイメージが作成され、先ほど手動で行っていたApacheのインストールなどを自動化することが可能となります。
①Dockerfileの作成 Cloud9上にてそのままDockerfileという名称でファイルを作成します。 (ファイル一覧を右クリックしてNew fileを選択するとファイルが作成されます。)
②Dockerfileの編集
以下の内容を先程作成したDockerfileへ貼り付けて保存します。
FROM ubuntu:18.04 # Install dependencies RUN apt-get update && \ apt-get -y install apache2 # Install apache and write hello world message 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 EXPOSE 80 CMD /root/run_apache.sh
参考 AWS Document : https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html
Dockerfileの内容は以下のとおりです。
- 作成するコンテナイメージの基となるベースイメージは DockerHub で公開されている Ubuntu 18.04
- Web サーバーとして Apache HTTP Server をインストール
- 実際の Web ページに表示するために index.html を作成
- EXPOSE で、このコンテナは 80 ポート(HTTP) を利用することを宣言
HTML ファイルから Dockerfile の文字列を張り付ける際は、ノーブレークスペースが入ることがあるとのことなので、以下のコマンドでノーブレークスペースを削除します。
administrator:~/environment $ sed -i "s/$(echo -ne '\u200b')//g" Dockerfile
③Dockerfileからコンテナイメージを作成 docker buildコマンドで実際にDockerfileで定義した情報を元にコンテナイメージを作成します。 -t オプションでイメージ名を指定します。
administrator:~/environment $ docker build -t apache_image2 . Sending build context to Docker daemon 14.79MB Step 1/6 : FROM ubuntu:18.04 18.04: Pulling from library/ubuntu 7c457f213c76: Pull complete Digest: sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 Status: Downloaded newer image for ubuntu:18.04 ---> f9a80a55f492 (略)
docker imagesコマンドを実行すると作成したコンテナイメージを確認できます。
administrator:~/environment $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE apache_image2 latest b250d012635e 31 seconds ago 205MB apache_image latest 299f7daead45 39 minutes ago 227MB ubuntu 18.04 f9a80a55f492 4 weeks ago 63.2MB
コンテナイメージをECRへアップロード
これでコンテナイメージを作成することができましたが、このままではCloud9上でしかコンテナが動作しません。 ECSにデプロイできるようにまずはECRへコンテナイメージをアップロードしましょう。
ECRとは
ECRとはElastic Container Registry の略で名前の通り、コンテナイメージを保存・管理するためのレジストリとなります。
リポジトリの作成とアップロード
①ECRのコンソール画面に移動して画面左のナビゲーションペインから「Repositories」→「リポジトリを作成」を選択
②以下の設定でリポジトリを作成
③リポジトリが作成されたらURIを控えておく
④Cloud9 に戻り、再度 docker build を実行
先程作成したDockerfileを元にECRアップロード用のイメージを作成します。
書式
docker build -t <ECR の URL>:<イメージのバージョン Tag> .
実行例
administrator:~/environment $ docker build -t 566122949358.dkr.ecr.ap-northeast-1.amazonaws.com/container-handson:0.0.1 . Sending build context to Docker daemon 14.79MB Step 1/6 : FROM ubuntu:18.04 ---> f9a80a55f492 Step 2/6 : RUN apt-get update && apt-get -y install apache2 ---> Using cache ---> bec10f9cc722 Step 3/6 : RUN echo 'Hello World!' > /var/www/html/index.html ---> Using cache ---> 2520ef532bff Step 4/6 : 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 ---> Using cache ---> 0a9365b176bc Step 5/6 : EXPOSE 80 ---> Using cache ---> 3fa15cd3ff6e Step 6/6 : CMD /root/run_apache.sh ---> Using cache ---> b250d012635e Successfully built b250d012635e Successfully tagged 566122949358.dkr.ecr.ap-northeast-1.amazonaws.com/container-handson:0.0.1
docker imagesを実行するとイメージが作成されているのがわかります。
administrator:~/environment $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE 566122949358.dkr.ecr.ap-northeast-1.amazonaws.com/container-handson 0.0.1 b250d012635e 2 hours ago 205MB apache_image2 latest b250d012635e 2 hours ago 205MB apache_image latest 299f7daead45 2 hours ago 227MB ubuntu latest 99284ca6cea0 3 weeks ago 77.8MB
⑤docker loginの実施
リポジトリに作成したイメージをアップロードするためdocker loginを行います。 --password-stdin には、コピーしてきた URI のうち、スラッシュ(/)より前の部分を指定してください。 Login Succeeded と表示されれば成功です。
administrator:~/environment $ aws ecr get-login-password | docker login --username AWS --password-stdin 566122949358.dkr.ecr.ap-northeast-1.amazonaws.com WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
⑥docker push で ECR に作成したコンテナイメージをアップロード
リポジトリのURIと先程指定したバージョンタグ0.0.1を指定してアップロードします。
administrator:~/environment $ docker push 566122949358.dkr.ecr.ap-northeast-1.amazonaws.com/container-handson:0.0.1 The push refers to repository [566122949358.dkr.ecr.ap-northeast-1.amazonaws.com/container-handson] 21403b370f4f: Pushed 3a2cae816da1: Pushed f0be3ae910c7: Pushed 548a79621a42: Pushed 0.0.1: digest: sha256:22942e66d3f431ae395fdf7e5d1227c90a6835850dfa555bf957f34af5d21950 size: 1155
リポジトリの詳細画面を確認するとイメージがアップロードされています。
ECRのコンテナイメージからECSでデプロイ
自分のコンテナイメージをECRに保存したので準備は完了しました。次にいよいよECSを用いてコンテナをデプロイします。
ECSとは
ECSとはAWS独自のコンテナオーケストレーションサービスです。 先ほどApacheを入れるためにコンテナを起動した際は、当然ですが一つだけコンテナが動いている形となっておりました。 ですが、アプリケーションの冗長化などでコンテナは複数起動されるのが一般的です。 複数台のコンテナを一括で管理するためのものがコンテナオーケストレーション、今回でいうところのECSとなります。
ECS用VPCの作成
ECSでコンテナを作成する前にECS用のVPCを用意します。
①以下の設定でVPCを作成
VPCのコンソール画面へ移動して以下の設定でVPCを作成します。
VPCが作成されたらVPC IDをコピーしてください。
②セキュリティーグループの編集
実際にコンテナに入ってWebページを見れるようにするため、セキュリティグループの変更を行いコンテナに HTTP アクセスを許可します。 セキュリティーグループ一覧に移動したら先ほどのIDを検索窓に入力してVPCのデフォルトセキュリティーグループを選択します。 セキュリティーグループを選択したら[アクション]→[インバウンドのルールを編集]の順に選択します。
以下の画像の通りにHTTPフルアクセスのルールを追加します。
以上で準備は完了です。次から実際にECSを使用していきます。
ECSでデプロイ
クラスターの作成
初めにクラスターを作成します。クラスターとはコンテナが動作する実行環境を定義するものです。 クラスターを別に作成することでコンテナ同士を干渉することなく実行できます。 ここで先ほど作成したVPCとサブネットを指定しましょう。
①ECSのコンソールから[クラスター]→[クラスターの作成]を選択
②クラスター名を指定し、先ほど作成したVPCとサブネットを選択して[作成]を選択(他設定値はデフォルト)
③クラスターが作成される
タスク定義の作成
タスク定義とは、コンテナに使用するコンテナイメージやコンテナが使用するCPU・メモリ・ストレージ容量などを指定します。 タスクとはこのタスク定義に基づいて作成される一つ以上のコンテナの集まりを指します。タスク≒コンテナ(ほぼ同義)と考えてください。 今回のタスク定義では一種類のコンテナしか定義していませんが、複数のイメージを選択して複数のコンテナを定義してタスクとしてまとめることも可能です。
①[タスク定義]→[新しいタスク定義の作成]を選択
②タスク定義ファミリー名を指定後、デプロイするコンテナの名前、とイメージURI、ポートを指定 この際のイメージURIは先ほどECRにアップロードしたものを選択(他設定値はデフォルト)
③今回はCPU・メモリ・ストレージ容量などの他設定値は全てデフォルト
④最後に設定値の確認画面が表示されるのでそのまま画面下の「作成」を選択
⑤タスク定義が作成される
サービスの作成
サービスとはALBやAutoScaling Groupに紐付けられたタスク群であり、実行中のタスクを管理するものとなっています。 タスクをそれ単体でデプロイすることも可能ですが、今回はサービスを作成してコンテナをALBに紐づけてみましょう。
①ECSのコンソールから[クラスター]→先ほど作成したクラスターを選択
②サービスの作成を選択
③「デプロイ設定」を以下の通りに設定
④「ロードバランシング」を以下の通りに設定
⑤他設定値はデフォルトで[作成]を選択 数分待つとコンテナのデプロイが完了する
作成したWebページにアクセス
これで完全にコンテナのデプロイが完了したので実際にWebページにアクセスしてみましょう。
①先ほど作成したサービスを選択
②[ネットワーキング]タブ→DNS名の[オープンアドレス]を選択
③Hello World! と表示されれば成功
実際にECSで稼働するコンテナにインターネット経由でアクセスすることができました。
後片付け
今回の記事の通りにハンズオンを行った方は終了後に、以下のリソースを上から順番に削除してください。
- ALB
- TargetGroup
- ECS Service の Task 数を 0 に変更
- ECS Service の削除
- クラスターの削除
- VPC の削除
- ECR の削除
- Cloud9 の削除
まとめ
今回は本当に基礎的な部分しか行いませんでしたが、そもそもコンテナがどのようなものか、そしてECSで動くコンテナがどんなものかイメージが少しでもつければ幸いです。ECSのサービスやタスクといった概念に関しては今回は省略気味に解説してしまいましたが、後ほど詳しく解説する記事も作成してみようと思います。