【AWS】ECS構築の基礎 −クラスタ作成編−

#はじめに
業務で使っていない技術を勉強しよう月間ということで、7月はAWSまわりの学習をすることにしました。
Dockerについて以前何個か記事にしたので、関連技術として今回はAWS ECSを学んでみることにしました。

https://qiita.com/suzuki0430/items/b2527cfba7602f9fe3bc

https://qiita.com/suzuki0430/items/fcf57968365d15419601

https://qiita.com/suzuki0430/items/e07890c5d83596fe4787

https://qiita.com/suzuki0430/items/225eb66223298d704241

#ECSとは
ECS(Elastic Container Service)はクラウドでコンテナを本番環境で利⽤するためのサービスです。

単一または複数のコンテナをTaskと呼ばれる形で管理し、Schedulerを使用することでService定義に従いあらかじめ設定された数のTaskをコンテナインスタンスに自動配備することができます。

起動タイプにはEC2とFargateの2種類があります。

OSやエージェント類へのパッチ当て・更新や、実⾏中のコンテナ数に基づく最適なリソース使⽤率を保つためのインスタンス数のスケーリングなど、EC2インスタンスの運用業務を行う必要があるのがEC2起動タイプです。

Fargateはサーバレス(= EC2の管理が不要)な起動タイプとなるため、EC2インスタンスのOSやDocker Agent、ミドルウェアなどの構築や設定操作の手間を省くことができます。
また、インスタンスタイプやクラスタ管理も不要であるため、手軽に環境構築とインフラ管理を行うことができます。
コンテナ実行する際には、実行時に必要なCPUやRAMの組み合わせのみを意識するだけで大丈夫です。

#ECSクラスタとは
ECSクラスタはEC2インスタンスの論理グループのことをいいます。
EC2インスタンス上で実行されているECSエージェントが、ECSクラスタへインスタンスを登録します。
インスタンスではECS用のAMIを実行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/7c150eef-75e5-5605-2865-0b50700ebae6.png" width="500">

#① Webサーバの構築
nginxのコンテナイメージを利用して、試しにFargate起動タイプでWebサーバを構築してみます。

##IAMユーザの作成
AmazonECS_FullAccessとAdministratorAccess(VPCやサブネット作成用)のポリシーを付与したIAMユーザを作成します。

##ECSクラスタの作成
ECSのページを開き、"今すぐ始める"ボタンを押すと以下のページになります。
コンテナ、タスク、サービス、クラスタの設定をステップごとに行っていきます。

タスク定義に基づいて起動されるコンテナ群をタスクといいます。
タスク定義では、コンテナ定義(イメージ場所等)、要求CPU/RAM、タスクに割当てるIAMロールなどの設定を行います。
コンテナイメージにはnginxを選択し、その他の設定はデフォルトのままです。
![スクリーンショット 2021-06-22 7.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/3f925adb-efdb-1234-05cc-8cb89a794057.png)

次にサービスを定義します。
サービスでは、タスク実行コピー数(n個)や連携するELBの種類などの設定を行います。
今回はデフォルト設定のままです。
![スクリーンショット 2021-06-22 7.29.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/bac981f7-a2bc-52cc-26be-18026df113db.png)

最後にクラスタの設定を行います。
クラスタでは、実行環境の境界、IAM権限の境界(クラスタに対する操作)などを設定します。
こちらもデフォルト設定のままです。
![スクリーンショット 2021-06-22 7.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/c20fc2e9-3ab9-0907-3986-a174830a65cb.png)

クラスタの作成が完了するとECSのページに実行タスクが表示されます。
![スクリーンショット 2021-06-22 7.36.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/74d03b62-653d-89fd-3333-c07baa3df0fe.png)

パブリックIPにアクセスすると以下のようにnginxが実行されていることを確認できます。
![スクリーンショット 2021-06-22 7.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/1549865a-0950-0798-b56b-f2d660d8592c.png)

#② ECSクラスタの作成
Webサーバの構築時にもクラスタの設定を行いましたが、この部分についてもう少し深く踏み込んでみます。

##IAM作成
ECSクラスタの作成にあたり、複数のIAMロールを作成する必要があります。

- EC2Role: ECSエージェントにECSやECRとの接続、CloudWatch Logsへのログ送信を許可
- ECSRole: ECSにリソース管理を許可
- ECSTaskExecutionRole: ECSタスクの実行を許可
- AutoscalingRole: Autoscalingを許可

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/d2803d1d-ef7d-0414-579a-f7719c995d50.png" width="500">
 
###EC2Role
コンソールでIAMを開いてElastic Container Serviceを選択すると、以下のユースケースが表示されます。
![スクリーンショット 2021-06-22 21.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/35260da5-770f-8536-687d-19f8e10d9abc.png)

`EC2 Role for Elastic Container Service`を選択すると、必要なポリシーがすでに含まれています。
![スクリーンショット 2021-06-22 21.20.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/c768d8eb-ec3b-e887-0f05-88e0243f0070.png)

後はロール名をつければ作成完了です。
![スクリーンショット 2021-06-22 21.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/81d18dee-c428-c670-f7ff-5b2b03bc7b07.png)

###ECSRole
ECSのリソース管理のためのロールになるので、EC2やELBへのアクセス許可に関するポリシーが含まれています。
![スクリーンショット 2021-06-22 21.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/ac4ad7f3-8cfb-175b-806c-9965034c8b80.png)

###ECSTaskExecutionRole
CloudWatch Logsへの書き込み権限とECRへの読み込み権限に関するポリシーが含まれています。
![スクリーンショット 2021-06-22 21.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/0aa3e211-9cde-74a6-319c-b2827779ec11.png)

###AutoscalingRole
CloudWatchとECSへのアクセス権限に関するポリシーが含まれています。
![スクリーンショット 2021-06-22 21.28.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/a3f962f4-7d67-0b9f-ce61-4cc2be81e2e8.png)

##インフラ構築(VPC・サブネット・インターネットゲートウェイ)
クラスタを作成するインフラ環境を構築します。
2つのAZにそれぞれサブネットを構築します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/1a6dc7a6-b63a-df46-7cb8-d64bf66e1496.png" width="500">

クラスタ作成がメインなので、インフラ部分についてはCloudFormationでパパっと構築します。

```
$ aws cloudformation create-stack --capabilities CAPABILITY_IAM --stack-name ecs-core-infrastructure --template-body file://./core-infrastructure-setup.yml
```
以下のようにスタックが作成されます。

```
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:338233790232:stack/ecs-core-infrastructure/17107770-d358-11eb-bb18-0ad12fe4a8a5"
}
```
![スクリーンショット 2021-06-22 21.50.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/32dae389-0047-ad02-77fa-9150473d0343.png)

![スクリーンショット 2021-06-22 21.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/e2c8ce12-300e-ae96-a186-8e381a97e58a.png)

##クラスタ作成
EC2起動タイプとFargate起動タイプの両パターンでクラスタを作ってみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/6ec22a08-5932-6a4b-5c3a-90d0a51f6ae8.png" width="700">

###EC2起動タイプ
クラスターの作成画面で`EC2 Linux + ネットワーキング`を選択します。
![スクリーンショット 2021-06-22 22.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/755a32c3-6143-d7f8-5e0f-393451e6b2c6.png)

クラスターの設定でクラスター名、インスタンスの設定(インスタンスタイプや数)、ネットワーキング(VPC、サブネット)、IAMロールの設定を行います。
![スクリーンショット 2021-06-22 22.09.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/6d057b4f-36cb-1fb0-6099-521ac843514d.png)
![スクリーンショット 2021-06-22 22.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/fd3a72f5-8200-d0b3-c55b-2601c53bce69.png)
![スクリーンショット 2021-06-22 22.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/56fdf034-2768-4b32-c2b7-bd4be7f1eb71.png)

作成ボタンを押すと起動ステータスの画面に移ります。
![スクリーンショット 2021-06-22 22.21.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/13742efb-6441-8417-47e9-74c3cf6b7e03.png)

作成が完了するとECSのクラスタータブで起動しているコンテナインスタンスを確認することができます。
![スクリーンショット 2021-06-22 22.25.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/8d40648d-ea53-fc58-eeb7-da3d59a52bfb.png)

###Fargate起動タイプ
Fargate起動タイプの場合はクラスターテンプレートに`ネットワーキングのみ`を選択します。
![スクリーンショット 2021-06-22 22.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/755a32c3-6143-d7f8-5e0f-393451e6b2c6.png)

あとはクラスター名を書くだけで作成が完了します。
この時点ではタスク定義やサービスを作成していないので、コンテナインスタンスはまだありません。
![スクリーンショット 2021-06-22 22.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/4c2c02bf-0626-3833-9864-8876602be7e1.png)

####CloudFormationを利用する場合
Resourcesの部分で、クラスタ`ECSCluster`とセキュリティグループ`ContainerSecurityGroup`を定義しています。

```yml:ecs-fargate-via-cloudformation.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: ECS cluster launchtype Fargate.
Parameters:
  EnvironmentName:
    Type: String
    Default: ecs-course
    Description: "A name that will be used for namespacing our cluster resources."
Resources:    
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub ${EnvironmentName}-fargate
  ContainerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the ECS hosts that run containers
      VpcId: 
        Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
Outputs:
  ClusterName:
    Description: The name of the ECS cluster
    Value: !Ref 'ECSCluster'
```
以下を実行します。

```
$ aws cloudformation create-stack --stack-name ecs-fargate --template-body file://./ecs-fargate-via-cloudformation.yml
```
すると以下のStackIdでスタックが構築されます。

```
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:338233790232:stack/ecs-fargate/72e19680-d360-11eb-a585-0659521679dd"
}
```
![スクリーンショット 2021-07-01 22.07.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/876b5a70-e40f-b3ee-b4fb-3db440d22e8a.png)

ここまでの手順でもかなりの分量になってしまいました。
タスク定義やサービスについては次の記事で書きます。

#参考資料
https://www.udemy.com/share/103fe82@PkdKZFlYTFYJcEBSOGJNfT1t/

https://business.ntt-east.co.jp/content/cloudsolution/column-171.html

https://d1.awsstatic.com/webinars/jp/pdf/services/20200422_BlackBelt_Amazon_ECS_Share.pdf

https://zenn.dev/yoshinori_satoh/articles/2021-02-13-eks-ecs-compare