概要
Dockerコンテナをローカルにつくり、ECRにプッシュ、ECS+ALBでロードバランスするところまでやってみます。
以前はECSをELBでロードバランスする際、EC2ホストとコンテナのポートを静的にマッピングする必要があり、1ホストに1コンテナしか実行できませんでした。ALBで実装された動的ポートマッピング機能を使い、EC2ホストの複数ポートをコンテナのポートと動的にマッピングすることで、1ホストに複数コンテナの環境をロードバランスすることができるようになりました。
環境はこんな感じです。
1. コンテナの作成
ローカルでDockerコンテナをビルドし、動かします。
環境
Docker for Mac
https://docs.docker.com/docker-for-mac/
Docker for Windows
https://docs.docker.com/docker-for-windows/
作成手順
- Dockerfileを作成
- コンテナイメージをビルド(docker build)
- コンテナを起動(docker run)
Dockerfileを作成
FROM centos:latest
RUN yum -y install httpd
ADD index.html /var/www/html
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
各行の説明です。
- FROM
- 基になるDockerイメージを指定します。ここではDockerHubからCentOSのLatestタグが付いているものをPullします。
- RUN
- コンテナイメージのビルド時に実行されるコマンドです。ここではhttpdをYUMインストールしています。
- ADD
- コンテナ上に置くファイルの指定です。ローカルの
index.html
をコンテナ上の/var/www/html
に保存しています。
- コンテナ上に置くファイルの指定です。ローカルの
- CMD
- コンテナ起動時に実行されるコマンドです。httpdをForegroundで起動しています。
<h1>Kumoben Test</h1>
コンテナイメージをビルド
$ docker build -t kumoben-apache .
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kumoben-apache latest aa1fc4c72c34 2 seconds ago 338.5 MB
centos latest 180e0e4c79ec 7 weeks ago 196.8 MB
コンテナを起動
$ docker run -p 80:80 kumoben-apache
2. コンテナの保存
ローカルで作成したコンテナイメージをECRにアップロードします。
マネージメントコンソールでECRリポジトリの作成
リポジトリの作成をクリックします。
リポジトリ名を入力し、次に進みます。
ログイン、コンテナのプッシュ方法が表示されます。
ECRのログイン情報を取得
マネージメントコンソールに表示されたコマンドを実行していきます。
$ aws ecr get-login --region ap-northeast-1
ECRにログイン
$ docker login -u AWS -p AQE~~~ -e none https://xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
Flag --email has been deprecated, will be removed in 1.13.
Login Succeeded
コンテナイメージにECRにアップするためのタグを付与
$ docker tag kumoben-apache:latest xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kumoben-apache:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xxxxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kumoben-apache latest 23016d00fed9 34 minutes ago 338.5 MB
kumoben-apache latest 23016d00fed9 34 minutes ago 338.5 MB
centos latest 980e0e4c79ec 7 weeks ago 196.8 MB
コンテナイメージをECRにプッシュ
$ docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kumoben-apache:latest
The push refers to a repository [xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kumoben-apache]
d72c7de6e1d2: Pushed
a758bd29dbba: Pushed
0aeb287b1ba9: Pushed
latest: digest: sha256:aaaa291c2c781be1f50b12b354e53faa46063a6ee156d0a2c8db76c6 size: 5104
3. コンテナの展開
ECSでコンテナを展開します。
クラスタを作成
クラスタにコンテナインスタンスを追加
EC2に割り当てるIAMロールを作成します。
AmazonEC2ContainerServiceforEC2Role
を有効にしたEC2用のIAMロールを作成します。
EC2インスタンスを起動します。
ECS用のAmazon Linux(amzn-ami-2016.09.a-amazon-ecs-optimized(ami-c8b016a9))を使用します。
Docker、ECSエージェントがセットアップされていれば、CoreOSやUbuntu等のOSも利用可能です。
ユーザーデータに下記を記載します。
/etc/ecs/ecs.config
にクラスタ名を記載することで、クラスタに登録されます。
#!/bin/bash
echo ECS_CLUSTER=<クラスタ名> >> /etc/ecs/ecs.config
マネージメントコンソールで登録されていることを確認します。
タスク定義を作成
コンテナの実行方法(タスク)を設定します。
新しいタスクの定義
をクリックします。
タスク定義名
を入力し、コンテナの追加
をクリックします。
下記を入力します。
- コンテナ名
- 任意の名前
- イメージ
- ECR上のパス
- メモリ制限
- コンテナに割り当てるメモリ量
- ポートマッピング
- 紐付けを行うEC2ホストのポートと、コンテナ側のポートを指定します。ホストポートを
0
にすることで、エフェメラルポートが動的に割り当てられます。
- 紐付けを行うEC2ホストのポートと、コンテナ側のポートを指定します。ホストポートを
サービスを作成
作成したタスク定義からサービスを作成し、コンテナの稼働状況を定義します。
ALBの作成
ロードバランサもサービスで定義する必要がなるので、先にALBを作成します。
ターゲットの登録
でインスタンスの登録は行いません。
ECSサービス用のIAMロールを作成
ロールタイプでAmazon EC2 Container Service Role
を選択します。
ポリシーもそのままAmazonEC2ContainerServiceRole
をアタッチします。
サービスの作成
クラスターの画面からサービス
タブを選択し、作成
をクリックします。
サービス名
とタスクの数
を入力します。
タスクの数
で指定した数のタスクが常時稼働することになります。
ここでは4
としています。
ELBの設定
をクリックし、作成したIAMロール、ELB名を選択し、コンテナの選択
でタスク定義で設定したコンテナを選択し、ELBへの追加
をクリックします。
リスナーポート
とALB作成時に設定したターゲットグループ名
を選択します。
最後に作成
をクリックします。
サービスの画面に戻ると、タスクが指定した数(4つ)実行されています。
ロードバランシングのターゲットグループを確認すると、ターゲットとして2台のインスタンスに2個ずつのターゲットが追加されています。
サービスの確認
サービスとして正常に動作しているかの確認のため、1台のインスタンスを停止してみます。
新たに同じインスタンスで稼働する2つのターゲットが追加されています。