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


はじめに

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

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を実行します。

① Webサーバの構築

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

IAMユーザの作成

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

ECSクラスタの作成

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

タスク定義に基づいて起動されるコンテナ群をタスクといいます。
タスク定義では、コンテナ定義(イメージ場所等)、要求CPU/RAM、タスクに割当てるIAMロールなどの設定を行います。
コンテナイメージにはnginxを選択し、その他の設定はデフォルトのままです。

次にサービスを定義します。
サービスでは、タスク実行コピー数(n個)や連携するELBの種類などの設定を行います。
今回はデフォルト設定のままです。

最後にクラスタの設定を行います。
クラスタでは、実行環境の境界、IAM権限の境界(クラスタに対する操作)などを設定します。
こちらもデフォルト設定のままです。

クラスタの作成が完了するとECSのページに実行タスクが表示されます。

パブリックIPにアクセスすると以下のようにnginxが実行されていることを確認できます。

② ECSクラスタの作成

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

IAM作成

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

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

EC2Role

コンソールでIAMを開いてElastic Container Serviceを選択すると、以下のユースケースが表示されます。

EC2 Role for Elastic Container Serviceを選択すると、必要なポリシーがすでに含まれています。

後はロール名をつければ作成完了です。

ECSRole

ECSのリソース管理のためのロールになるので、EC2やELBへのアクセス許可に関するポリシーが含まれています。

ECSTaskExecutionRole

CloudWatch Logsへの書き込み権限とECRへの読み込み権限に関するポリシーが含まれています。

AutoscalingRole

CloudWatchとECSへのアクセス権限に関するポリシーが含まれています。

インフラ構築(VPC・サブネット・インターネットゲートウェイ)

クラスタを作成するインフラ環境を構築します。
2つのAZにそれぞれサブネットを構築します。

クラスタ作成がメインなので、インフラ部分については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"
}

クラスタ作成

EC2起動タイプとFargate起動タイプの両パターンでクラスタを作ってみます。

EC2起動タイプ

クラスターの作成画面でEC2 Linux + ネットワーキングを選択します。

クラスターの設定でクラスター名、インスタンスの設定(インスタンスタイプや数)、ネットワーキング(VPC、サブネット)、IAMロールの設定を行います。


作成ボタンを押すと起動ステータスの画面に移ります。

作成が完了するとECSのクラスタータブで起動しているコンテナインスタンスを確認することができます。

Fargate起動タイプ

Fargate起動タイプの場合はクラスターテンプレートにネットワーキングのみを選択します。

あとはクラスター名を書くだけで作成が完了します。
この時点ではタスク定義やサービスを作成していないので、コンテナインスタンスはまだありません。

CloudFormationを利用する場合

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

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"
}

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

参考資料