[AWS] Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第4回)

※本記事は Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル( [第1回](https://qiita.com/VA_nakatsu/items/c8a4b24b8cffd0e9047b) , [第2回](https://qiita.com/VA_nakatsu/items/555d75cd8a7ff8584eaf) , [第3回](https://qiita.com/VA_nakatsu/items/62a064c32f147efffe69) )の続きです。

前回までで、ECSの実行環境は一通り作成できました。今回はDockerイメージの更新手順を確認します。

これまで例としてnginxのコンテナを使っていましたが、それをapacheのコンテナに差し替えてみます。
図にするとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/d406661a-8071-4d5f-bee1-47d80366030c.png)

# インスタンスとサービスのスケール

第2回，第3回と同様に、作業前にインスタンスをスケールアウトしておきます。

最初にインスタンス数を2に増やし、
![100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/410a11ce-ef5f-170e-c279-638aeb9cd615.png)

その次に、サービスの更新でタスク数を2に変更しておきます。

|![sservice01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/7776bd6f-8925-28f9-7a73-f55f93051cc8.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/e0dfc1b4-0e78-c6d2-95df-1d9729564944.png)|
|:-:|


# 1) 更新用イメージの作成

apache2のイメージを作成し、ビルドします。第1回と同様に、テスト用のhtmlを追加しただけの簡単なものです。

```dockerfile:Dockerfile
FROM httpd
COPY demo.html /usr/local/apache2/htdocs/demo.html
```

```shell
# ls -l
total 8
-rw-r--r-- 1 root root 389 Aug  2 19:37 demo.html
-rw-r--r-- 1 root root  63 Aug  2 19:37 Dockerfile

# cat Dockerfile
FROM httpd
COPY demo.html /usr/local/apache2/htdocs/demo.html

# cat demo.html
<!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">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>ECS demo page</title>
  </head>
  <body>
    <div class="main_page">
      ECS Demo Page for httpd
    </div>
  </body>
</html>

## ※Dockerコンテナをビルドする※
# docker build -t apache-demo01 .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM httpd
latest: Pulling from library/httpd
f5d23c7fed46: Pull complete
b083c5fd185b: Pull complete
bf5100a89e78: Pull complete
98f47fcaa52f: Pull complete
622a9dd8cfed: Pull complete
Digest: sha256:dc4c86bc90593c6e4c5b06872a7a363fc7d4eec99c5d6bfac881f7371adcb2c4
Status: Downloaded newer image for httpd:latest
 ---> ee39f68eb241
Step 2/2 : COPY demo.html /usr/local/apache2/htdocs/demo.html
 ---> 81d38acb42a3
Removing intermediate container a653dd92bbd8
Successfully built 81d38acb42a3
Successfully tagged apache-demo01:latest

## ※動作確認のため実行してみる※
# docker run -itd --privileged -p8888:80 apache-demo01
1ca3fc48ee4de32a06edd1d8feeec959870e934f5d96194d2ab324e983721716

## ※起動したことを確認する※
# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
1ca3fc48ee4d        apache-demo01       "httpd-foreground"   21 minutes ago      Up 21 minutes       0.0.0.0:8888->80/tcp   cranky_goldwasser

## ※追加したdemo.htmlが参照できることを確認する※
# curl http://localhost:8888/demo.html
<!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">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>ECS demo page</title>
  </head>
  <body>
    <div class="main_page">
      ECS Demo Page for httpd
    </div>
  </body>
</html>

## ※動作確認したコンテナを停止しておく※
# docker stop 1ca3fc48ee4d
1ca3fc48ee4d
```

# 2) 更新手順(ECR)

ここも第1回とほぼ同様の手順となります。今回作成したイメージは"apachetest"というタグを付けておきます。

ECRへのログイン：profileオプションが他のコマンド同様に指定可能です。

```shell
# $(aws ecr get-login --no-include-email --region ap-northeast-1 --profile vatest)
Login Succeeded
```

タグ付け：ビルドしたイメージに、ECR形式でのタグを付与します。リポジトリ名に"nginx"を入れていたため少し違和感のある名称になってしまいましたが・・・"nginx-demo01(リポジトリ名)：apachetest(タグ名)" が付与した名称です。

```shell
# docker tag apache-demo01:latest <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01:apachetest
# docker images | grep nginx-demo01
<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01   apachetest   81d38acb42a3    25 minutes ago   154MB
<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01   latest       de6344632e81    7 weeks ago      109MB
nginx-demo01                                                         latest       de6344632e81    7 weeks ago      109MB
```

ECRへのプッシュ：先ほど付与したタグの通りに指定し、ECRにプッシュします。

```shell
# docker push <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01:apachetest
The push refers to a repository [<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01]
781884c43489: Pushed
635721fc6973: Pushed
bea448567d6c: Pushed
bfaa5f9c3b51: Pushed
9d542ac296cc: Pushed
d8a33133e477: Pushed
apachetest: digest: sha256:9fb40d7d1c0a9f28438bc997765518b55e735c242b3bacf7ad4fe6bf468c58ff size: 1574
```

最後に、コンソールでイメージが追加されたことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/065c85b2-bf7b-2728-7e06-20591db10ba4.png)


# 3) 更新手順(ECS)

タスク定義の更新、サービスの更新の順に実行して変更を反映します。第3回と同様の手順となります。

## 3-1) タスク定義の更新

タスク定義にチェックを入れ、「新しいリビジョンの作成」を選択します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/ce52cf38-fe81-9c3b-75f3-f4cf64f5fed4.png)|
|:-:|

コンテナをクリックして出てくるダイアログ内で、イメージのタグ名を変更します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/d6a6fe2a-7584-c315-8326-6cbdde96901c.png)|
|:-:|

保存して、新しいリビジョン(2)が作成されたことを確認します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/3684f8a7-9235-7cfa-fc96-d8e75cbf4af1.png)|
|:-:|


## 3-2) サービスの更新

サービスを表示し、「更新」ボタンを押します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/18100df5-466b-1066-9afd-525e7e86e195.png)|
|:-:|

サービスの設定で、タスク定義の新しいリビジョン(2)を選択します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/67721d85-7a55-6199-8c4a-9849dfb55695.png)|
|:-:|

保存し、更新されたことを確認します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/3d0c9fdc-30dd-dde6-3550-0e3ebfd090ee.png)|
|:-:|

## 3-3) 動作確認

少し待ってブラウザで `http://<ELBのDNS名>:8080/index.html` にアクセスし、apacheのデフォルトページに変更になったことを確認します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/ac924c47-e473-db77-93ab-4d4bf2ae4f58.png)|
|:-:|

`http://<ELBのDNS名>:8080/demo.html` にアクセスし、テスト用に追加したhtmlも更新されたことを確認します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/a532f27a-bd8b-1361-8e71-83a13c100c73.png)|
|:-:|

インスタンスにログインし、Dockerコマンドでも更新されたことが確認できます。

```shell
## ※イメージの確認※
# docker images
REPOSITORY                                                           TAG         IMAGE ID      CREATED            SIZE
<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01   apachetest  81d38acb42a3  About an hour ago  154MB
amazon/amazon-ecs-agent                                              latest      b5b4bfd5a2aa  3 weeks ago       57.1MB
amazon/amazon-ecs-pause                                              0.1.0       c5d9a481de06  3 weeks ago        954kB
<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01   latest      de6344632e81  7 weeks ago        109MB

## ※Dockerプロセスの確認※
# docker ps
CONTAINER ID        IMAGE                                                                       COMMAND              CREATED             STATUS              PORTS                  NAMES
5613cf288fbd        <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-demo01:apachetest   "httpd-foreground"   11 minutes ago      Up 11 minutes       0.0.0.0:8080->80/tcp   ecs-va-ecs-task-definition01-2-nginx-demo01-b4fcfb81e5de8c89a401
5ecdc50a96f7        amazon/amazon-ecs-agent:latest                                                  "/agent"             25 minutes ago      Up 25 minutes                              ecs-agent
```

以上でDockerイメージの更新が確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/e2b3d212-e384-785b-513c-94c9dfcb227a.png)

# コマンドでスケールインしておく

作業後はいつものようにタスクとインスタンス数を0にしておきますが、今回からCLIで実行してみます。インスタンスの方のスケールはawsコマンドではなくecs-cliコマンドでの実行となるため、先にインストールします。

## ecs-cliコマンドのインストール

```shell
$ which ecs-cli
$ sudo curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-linux-amd64-latest
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 29.9M  100 29.9M    0     0  8826k      0  0:00:03  0:00:03 --:--:-- 8826k
$ sudo chmod +x /usr/local/bin/ecs-cli
$ which ecs-cli
/usr/local/bin/ecs-cli
```

## サービスのスケールイン(タスク数を0にする)

サービスの方はawsコマンドで実行可能です。
`aws ecs update-service --cluster <クラスタ名> --service <サービス名> --desired-count <変更後のタスク数> --profile <awsプロファイル>`

```shell
$ aws ecs update-service --cluster va-ecs-demo-cluster01 --service va-ecs-service01 --desired-count 0 --profile vatest
※サービス定義が出力されるが長いので省略※
```

## インスタンスのスケールイン

インスタンスはecs-cliコマンドで変更します。先にecs-cli configureコマンドを実行する必要があるのですが、ここでのポイントは<font color="red"> --cfn-stack-name オプションで、<b>"EC2ContainerService-"＋クラスタ名</b> を指定する </font> 必要があります。これは [CLIでクラスタを作成した場合とデフォルトのプレフィックスが違うため、](https://github.com/aws/amazon-ecs-cli/issues/580)その差によるエラーが出ないようにする設定です。

```shell
## ecs-cli configure --cluster <クラスタ名> --cfn-stack-name "EC2ContainerService-"<クラスタ名> --region <リージョン> --config-name <Config名(何でもよい)>
$ ecs-cli configure --cluster va-ecs-demo-cluster01 --cfn-stack-name EC2ContainerService-va-ecs-demo-cluster01 --region ap-northeast-1 --config-name vapractice-ecs
INFO[0000] Saved ECS CLI cluster configuration vapractice-ecs.

## ecs-cli scale --capability-iam --size <変更後のインスタンス数> --cluster <クラスタ名> --region <リージョン> --aws-profile <awsプロファイル>
$ ecs-cli scale --capability-iam --size 0 --cluster va-ecs-demo-cluster01 --region ap-northeast-1 --aws-profile vatest
INFO[0000] Waiting for your cluster resources to be updated...
INFO[0000] Cloudformation stack status                   stackStatus=UPDATE_IN_PROGRESS
```

以上で実行インスタンス数を0にできました。

# Link

- [Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第1回)](https://qiita.com/VA_nakatsu/items/c8a4b24b8cffd0e9047b)
- [Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第2回)](https://qiita.com/VA_nakatsu/items/555d75cd8a7ff8584eaf)
- [Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第3回)](https://qiita.com/VA_nakatsu/items/62a064c32f147efffe69)
- [Can't scale cluster: CloudFormation stack not found](https://github.com/aws/amazon-ecs-cli/issues/580)