ECSでコンテナを作成するには?Dockerの環境構築から動作確認までを解説

前回はコンテナの基本とAmazon ECSの概要について解説をしました。
今回はDockerを動かすための環境構築とコンテナ作成、そして作成したコンテナをECS上で動かし、動作を確認するまでの手順を解説していきます。

Dockerの環境構築とコンテナ作成

コンテナの作成環境

コンテナを作成するためにはDockerがインストールされた環境が必要になります。今回はAWSのEC2インスタンスにDockerをインストールし、コンテナの作成をしていきます。
解説をするために作成したAWS環境はこのような形です。

リージョンはどこでも構いません。
VPCを作りDocker構築用のEC2インスタンスを作成しています。
SubnetはSSH用にグローバルIPを付与しているため、Public Subnetとして作成していますが、EC2 instance ConnectやAWS Session Manager(SSM)等を使う方法もありますので、接続方法はお好みの方法で構いません。
インターネット経由でSSH接続をする場合には、Security Groupで接続元を制限しましょう。

では、EC2インスタンスに接続ができたら、Dockerの実行環境を作成していきます。

・OS情報の確認
$ cat /etc/amazon-linux-release<br>
 Amazon Linux release 2023 (Amazon Linux)

・Dockerのインストールと実行
yumコマンドを使ってDockerをインストールします。
$ sudo yum install -y docker

インストールが終わりましたら、Dockerを起動します。
$ sudo systemctl start docker

念のため、起動していることを確認しましょう。
$ sudo docker info

・Dockerのバージョンは以下の通りです。
$ sudo docker -v

Docker version 20.10.25, build b82b9f3

コンテナの作成準備

Dockerではdockerfileというファイルでどんなコンテナを作成するかコンテナの中身を定義しています。今回は簡単なWebページを表示するためのコンテナを作成します。

・作業用のディレクトリを作成します。
$ sudo mkdir /docker
$ cd /docker

・dockerfileを作成します。
$ sudo vi dockerfile

FROM httpd:2.4
COPY index.html /usr/local/apache2/htdocs/index.html

Dockerではコンテナの元となるコンテナイメージを、Docker Hubなどのレジストリ(コンテナの置き場所)からダウンロードすることができます。今回はDockerの公式レジストリであるDocker hubを使用しています。
(Docker hub:https://hub.docker.com/
dockerfile内のFROMでコンテナのイメージを指定しています。
今回はApache HTTP サーバー用のイメージである「httpd:2.4」というイメージを使用します。COPYでカレントディレクトリにあるindex.htmlを、/usr/local/apache2/htdocs/index.htmlにコピーをしています。

・簡単なWEBページ用のhtmlを作成します。
sudo vi index.html

<html>
  <head>
    <title> Bare Test </title>
  </head>
  <body>
    <h1>Hello ECS !!</h1>
  </body>
</html>

これでコンテナの作成準備が完了しました。
少しだけ余談ですが、現時点ではまだコンテナのイメージを作成していません。コンテナの作成は次章で行いますが、事前に作成してみたいという方は下記のコマンドで作成・確認することが出来ます。

・コンテナの作成
dockerfile、index.htmlのあるディレクトリで下記のコマンドを実行してください。
sudo docker build –t <コンテナ名> .

※ドットまでがコマンドです。

http-testというコンテナを作成する場合は下記のようになります。
 sudo docker build –t http-test .

・コンテナの確認
sudo docker images

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
http-test    latest    2da76e3b831f   9 seconds ago   168MB
httpd        2.4       76e5ad98b58e   2 weeks ago     168MB

http-testとhttpdの2つのコンテナが作成されていることが分かります。httpdはdockerfileのFROMで指定した、http-testを作成した際に使用した元のコンテナイメージとなります。

・コンテナを実行する。
 docker run –d <IMAGEID>

※-dオプションでバックグラウンド実行

・コンテナの実行確認
sudo docker ps –a

CONTAINER ID   IMAGE          COMMAND              CREATED          STATUS                      PORTS     NAMES
fcf95ec68816   2da76e3b831f   "httpd-foreground"   13 seconds ago   Up 12 seconds               80/tcp    relaxed_hofstadter

STATUSがUpとなっているので、コンテナIDがfcf95ec68816として、実行されていることが分かります。

・コンテナの中(shell)に入る
sudo docker exec –it <CONTAINER ID> /bin/bash

root@fcf95ec68816:/usr/local/apache2#

無事にコンテナの中に入り、Shell(bash)が表示されました。

作ったコンテナをECRにPush

ECR(Elastic Container Registry)とはDockerのコンテナイメージを保存するためコンテナレジストリです。
ECSでコンテナを扱うためにはレジストリと呼ばれるコンテナ置き場に、コンテナを配置する必要があります。AWSではコンテナレジストリとしてECRを用意していますが、他にDucker HubやGoogle CloudのContainer Registryなどにも対応しています。
今回はECRのプライベートレジストリ(外部公開をしないレジストリ)を使用します。

ECRの作成

AWSマネジメントコンソールを使いECRを作成します。
AWSマネジメントコンソールからECSを検索し、左側のメニューから「Amazon ECR」を選択します。

右側にあるレポジトリの作成にある、「使用方法」をクリックします。

「レポジトリを作成」画面が表示されます。
①「プライベート」を選択します。
※パブリックを選択すると外部に公開されますのでご注意下さい。
②お好みのリポジトリ名を入力して下さい。
※本ブログ記事では「bare_test」として作成します。

今回は「イメージスキャンの設定」、「暗号化設定」は設定しませんので、入力が終わりましたら「リポジトリを作成」を選択します。

ECRにDockerイメージをPush

作成されたECRにチェックを入れて、「プッシュコマンドの表示」をクリックします。

Mac/Linux用のコマンドと、Windows用のコマンドが表示されますので、環境に合わせてコマンドを実行します。
基本的にはこの通りに実施すれば問題ありません。今回は用意したEC2インスタンスからPushしますので、Mac/Linux用のコマンドを実行していきます。
$ su -  // rootユーザーに切り替え
# aws ecr get-login-password --region ap-northeast-1 | docker login –username AWS --password-stdin 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

 Login Succeeded

「Login Succeeded」と表示されれば、認証成功です。
この時点でエラーが出る場合は、Linuxの実行権限、IAMロールなどの権限周りを確認して下さい。続いて、先程作成したdockerfileを使いイメージを構築(ビルド)します。

コンテナを作成(build)します。
# cd /docker   // dockerfileのあるディレクトリに移動します。
# docker build -t bare_test .

Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM httpd:2.4
---> ad303d7f80f9
Step 2/2 : ADD index.html /usr/local/apache2/htdocs/index.html
---> Using cache
---> c93ff0899b85
Successfully built c93ff0899b85
 Successfully tagged bare_test:latest

dockerイメージの構築に失敗する場合は、dockerfile中のスペルミスやファイル名が正しいかを確認してください。

続いてイメージにタグを付けて、ECRにdockerイメージをプッシュします。
// イメージにタグ付け
# docker tag bare_test:latest 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/bare_test:latest
// イメージのプッシュ
# docker push 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/bare_test:latest

The push refers to repository [000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/bare_test]
eace5d5fcece: Pushed
e3d394052b85: Pushed
afb2764e050a: Pushed
084ceb61a963: Pushed
85322d06f709: Pushed
ac4d164fef90: Pushed
latest: digest: sha256:9ef8846da22d766fe0583e20ec889dac18c412176fcc02921b3bebf97a99da2a size: 1573

これでECRにイメージをプッシュすることが出来ました。
この後、必要となりますので、URIをメモしておきましょう。
ecr_create06

ECSでコンテナを動かしてみよう

ここからはECSのクラスターとタスクを作成し、実際にコンテナを実行していきます。
図の赤枠の部分となります。

実行準備

ECSの構成要素であるクラスターを作成します。

クラスターの作成

AWSマネジメントコンソールからECSへ移動し、「クラスター」、「クラスターの作成」を選択します。
ecs_cluster01

「クラスターの作成」画面で、任意の「クラスター名」、「ネットワーク」を入力・選択し「作成」を実行します。
ecs_cluster02

実行すると「作成が進行中です」と表示され、

完了すると、「正常に作成されました」と表示されます。

・タスク定義

ECSの画面から「タスク定義」を選択し、「新しいタスク定義の作成」を実行します。「新しいタスク定義の作成」と「JSONを使用した新しいタスク定義の作成」がリストに出てきますので、「新しいタスク定義の作成」を選択します。

「タスク定義とコンテナの設定」画面ではコンテナ(タスク)を定義するための具体的な設定をしていきます。
①任意のタスク定義名を記入します。
②コンテナの名前を記入します。
③先程メモしたECRのURIを記入します。
④どのポートに対してアクセスをするのかを設定します。
⑤今回はhttpプロトコルを使ったWEBページへのアクセスとなりますので、80を入力します。

入力が終わりましたら、下部にある「次へ」を選択します。

「環境、ストレージ、モニタリング、タグの設定」画面で起動タイプ、コンテナのCPU/メモリなどの細かい設定をしてきます。今回はほぼデフォルト構成で実行していきます。
①ECSの起動タイプを選択します。今回はFargateを選びました。
②コンテナ(タスク)の実行サイズを指定します。お好みのサイズを指定して下さい。性能が高いほど利用料は上がります。
③入力が終わりましたら、下部にある「次へ」を選択します。

「確認して作成」画面で設定に問題がないか確認をして、下部の「作成」を選択します。

ECSでコンテナ実行

3.2.1 実行(タスクの実行)

タスクの実行はクラスターから行います。ECSのクラスターから、先程作成したクラスターを選択します。

クラスターの画面から、「タスク」、「新しいタスクの実行」の順に選択します。

「作成」画面で実行するタスクの設定をしていきます。
ecs_cluster07

デプロイ設定ではタスク定義のファミリーで、作成したタスク定義を指定します。
ecs_cluster08

「ネットワーキング」ではVPC、サブネット、セキュリティグループを設定します。今回はWEBページにアクセスするために、セキュリティグループで80ポートを開放しています。
また、必要に応じてパブリックIP(グローバルIP)をオンにしてください。
外部ネットワークからアクセスさせる場合、パブリックIPが必要となります。

設定が終わりましたら、下部の「完了」を選択します。
新しいタスクが実行されると、ステータスが「プロビジョニング」になり、少し待ってから更新すると「実行中」に変わります。

動作確認

ECSを使ったWEBサーバーの公開が完了したので、早速ECSにアクセスしてみましょう。
実行したタスクを選択し、パブリックIPを確認します。

確認したパブリックIPにブラウザでアクセスすると… ちゃんと表示できました!

便利なコンテナの使い方

今回はシンプルなWebページを表示する方法を解説して行きましたが、ECSの具体的な活用シーンには以下のようなものがあります。

活用方法その①:定期実行バッチとして使う

AWS内でバッチ処理をするならFargateの他に「EC2」や「Lambda」や「AWS Batch」が挙げられます。例えば、S3に格納された大量のデータを定期的に処理したいとします。
Lambdaでは起動時間が15分までという制限があり、処理時間に制限時間を超えるような時間のかかる処理には向いていません。

EC2ですと常時起動状態にしたままだと時間分の費用が発生しますし、定時に起動させると言ったアクションをさせるにも手間がかかります。
また、「AWS Batch」は内部的にECSタスクを使用しているため、ECSにできてAWS Batchに出来ないことは基本的にはありませんが、デフォルトでは定期実行機能がないため、毎日○時に実行という場合は実装にCloud Watch Eventsを使用するなどの工夫が必要です。

ECSであれば、コンピューティングリーソースの自由度が高く、稼働時間の制限もないため、Lambdaの制限時間内では実行できないような時間のかかる処理を定期的に実行したい、という用途には向いていると言えます。

活用方法その②:サーバーレスシステムの構築

EC2を使用せずにECS Fargateを構築することで、サーバーの管理・維持を意識せずにシステムを構築することが可能です。
例えば、基盤となる部分をFargateで構築し、コンテンツをS3やEFSなどに配置することで、基盤の更新とコンテンツの更新を明確に分けることが出来ます。
また、コンテナはコードベース(dockerfile)で管理することができますので、ローカルでのテストや、その後のデプロイまでサーバー構成に依存せずに行えます。

活用方法その③:Kubernetes(EKS)

AWSにはECSの他にコンテナを扱うサービスとしてEKS(Elastic Kubernetes Service)というサービスがあります。
コンテナ化は便利な技術ではありますが、コンテナが増加してしまうと、結果としてコンテナ自体の管理・運用に手間がかかるようになり、また煩雑になってしまいやすいといったデメリットも存在しています。Kubernetesはそうしたコンテナのデメリットを解決するために、コンテナの運用管理や自動化を行うための、ECSのようなコンテナオーケストレーションツールの一つです。

EKSとはAWSでKubernetesを扱うためのマネージドサービスとなります。
ECSとの主な違いは、ECSはAWSのオリジナルソフトウェアをベースに開発されたクローズドソフトウェアであり、一方でEKSはオープンソースがベースであるという点です。
EKSの元となっているKubernetesはオープンソースとして世界中で開発されており、豊富な機能を持ち、頻繁なアップデートが実施されています。しかし、機能が豊富で便利な半面、使いこなすには相応の学習コストが必要なので、開発規模や使用目的に応じて使い分けることが大切です。

ともあれ、コンテナは便利で楽しい技術です。
この記事が少しでも皆様のお役に立ってくれれば嬉しい限りです。