LoginSignup
0
0

More than 1 year has passed since last update.

AWS ECS on Fargateを使ってコンテナ構築~コンテナレジストリ構築編~

Last updated at Posted at 2021-11-09

はじめに

機械学習モデルの推論結果を返す Web API を FastAPI で作成で作成したものを AWS 環境でデプロイする。Docker を用いた開発環境で作成したアプリであるため、そのままコンテナイメージを活用して AWS ECS on Fargate 上で稼働させる。AWSコンテナ設計・構築[本格]入門を参考にした。全体の流れは以下である。

  1. ネットワーク構築
  2. コンテナレジストリ構築
  3. オーケストレーション構築

構築はすべて AWS CloudFormation を用いて実行する。CloudFormation で使用するテンプレートファイルは、AWSコンテナ設計・構築[本格]入門で提供されているテンプレートファイルをベースにしている。
説明の流れに合わせてテンプレートファイルを network.yml, registry.yml, orchestration.yml の3つに分けるが、分け方として適切ではないので、実際には AWS CloudFormation ベストプラクティスなどを参考にファイルを分割した方がよい。
本記事ではコンテナレジストリ構築に関して述べるため、registry.yml のみ使用する。

ECR (Elastic Container Registry) リポジトリの作成

AWS マネジメントコンソール上でリポジトリを作成する。詳細は公式ドキュメントを参照。リポジトリ名は [test-image] とした。
ecr_top.png

コンテナレジストリへのネットワーク

前記事である AWS ECS on Fargateを使ってコンテナ構築~ネットワーク構築編~で作成したベースネットワークを、以下のように更新する。インターフェイス型 VPC エンドポイントが属するサブネットをアプリケーションから分離するために新しいサブネットを作成し、ECR 向けの VPC エンドポイントを作成。また S3 向けのゲートウェイ型 VPC エンドポイントを作成し、前記事で作成したルートテーブルに紐付けている。

AWSエンドポイント.drawio.png

サブネットの設定は以下のようにした。

用途 NW 区分 AZ CIDR サブネット名
Egress 用 Private 1a 10.0.248.0/24 test-subnet-private-egress-1a
Egress 用 Private 1c 10.0.249.0/24 test-subnet-private-egress-1c

CloudFormation テンプレートファイル

上記で説明したネットワークを構築するテンプレートファイルが以下となる。

registry.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Vpc endpoint template
Resources:
  # VPCエンドポイント周りの設定
  ## VPCエンドポイント(Egress通信)用のプライベートサブネット
  testSubnetPrivateEgress1A:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.248.0/24
      VpcId:
        !ImportValue testVpc
      AvailabilityZone:
        Fn::Select:
          - 0
          - Fn::GetAZs: ""
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: test-subnet-private-egress-1a
        - Key: Type
          Value: Isolated
  testSubnetPrivateEgress1C:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.249.0/24
      VpcId:
        !ImportValue testVpc
      AvailabilityZone:
        Fn::Select:
          - 1
          - Fn::GetAZs: ""
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: test-subnet-private-egress-1c
        - Key: Type
          Value: Isolated

  ## VPCエンドポイント用セキュリティグループの生成
  testSgEgress:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group of VPC Endpoint
      GroupName: egress
      SecurityGroupEgress:
        - CidrIp: 0.0.0.0/0
          Description: Allow all outbound traffic by default
          IpProtocol: "-1"
      Tags:
        - Key: Name
          Value: test-sg-vpce
      VpcId:
        !ImportValue testVpc

  ## Container -> VPC endpoint
  testSgVpceFromSgContainerTCP:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      IpProtocol: tcp
      Description: HTTPS for Container App
      FromPort: 443
      GroupId:
        Fn::GetAtt:
          - testSgEgress
          - GroupId
      SourceSecurityGroupId:
        !ImportValue testSgContainer
      ToPort: 443

  # VPCエンドポイントの作成
  ## ECR 向けインターフェイス型 VPCエンドポイント
  testEndpointEcr:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: True
      SecurityGroupIds:
        - !Ref testSgEgress
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .ecr.api
      SubnetIds:
        - !Ref testSubnetPrivateEgress1A
        - !Ref testSubnetPrivateEgress1C
      VpcEndpointType: Interface
      VpcId: !ImportValue testVpc
  testEndpointDkr:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: True
      SecurityGroupIds:
        - !Ref testSgEgress
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .ecr.dkr
      SubnetIds:
        - !Ref testSubnetPrivateEgress1A
        - !Ref testSubnetPrivateEgress1C
      VpcEndpointType: Interface
      VpcId: !ImportValue testVpc

  ## S3 向けゲートウェイ型 VPCエンドポイント
  testEndpointS3:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      RouteTableIds:
        - !ImportValue testRouteApp
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .s3
      VpcEndpointType: Gateway
      VpcId: !ImportValue testVpc

Outputs:
  # Subnet
  ## Egress private subnet
  testSubnetPrivateEgress1A:
    Value: !Ref testSubnetPrivateEgress1A
    Export:
      Name: testSubnetPrivateEgress1A
  testSubnetPrivateEgress1C:
    Value: !Ref testSubnetPrivateEgress1C
    Export:
      Name: testSubnetPrivateEgress1C

  # Security group
  ## Egress security group
  testSgEgress:
    Value: !Ref testSgEgress
    Export:
      Name: testSgEgress

サブネットなどと同様に VPC エンドポイントにもタグで Name を付与したかったが、AWS::EC2::VPCEndpoint - Tags #196 によると、VPCEndpoint では Tags がサポートされていないらしい。仕方ないので、今回作成した3つの VPC エンドポイントには AWS CLI を使って Name タグを付ける。

$ aws ec2 create-tags --resources [endpoint ID] --tags Key=Name,Value=[endpoint name]

コンテナイメージの登録

上記までで ECR にコンテナイメージを登録する準備が完了した。ここでは、アプリケーションのビルド処理を行い、作成されたコンテナイメージを ECR に登録する。(本記事では、AWS ECS on Fargate を使ってコンテナを構築することを主としているため、コンテナ上で動くアプリケーションはすでに存在している前提で話を進めている。)
まずコンテナイメージをビルドする。

$ docker image build -t test-image:0.0.1 .
$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID       REPOSITORY   TAG
opqrstuvwxyz   test-image   0.0.1

次に、Docker イメージをプッシュするを参考に上記で作成したイメージを ECR へプッシュしていく。
Docker イメージを ECR に登録するために、AWS アカウントが認識できるような形式にする。

$ AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
$ docker image tag test-image:0.0.1 ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image:0.0.1
$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID       REPOSITORY                                                  TAG
abcdefghijkl   123456789.dkr.ecr.ap-northeast-1.amazonaws.com/test-image   0.0.1

Amazon ECR レジストリに対して Docker クライアントを認証する。

$ aws ecr --region ap-northeast-1 get-login-password | docker login --username AWS --password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image
Login Succeeded

Docker イメージをプッシュする。

$ docker image push ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image:0.0.1
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-image]
2eb0dc7856ad: Pushed
0c668eb965fd: Pushed
...

以上で、ECR にコンテナイメージを登録することができた。

おわりに

AWS ECS on Fargate を使ってコンテナを構築する第2段階として、VPC エンドポイントを作成し、コンテナイメージを ECR に登録した。いよいよコンテナを構築していく。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0