AWS Fargate
料金
Amazon ECS の場合、AWS Fargate の料金は、コンテナイメージのダウンロード (docker pull) を開始した時点から Amazon ECS タスク* が終了するまでに使用された vCPU およびメモリリソースに基づいて計算され、最も近い秒数に切り上げられます。1 分の最低料金が適用されます。
per vCPU per hour 0.05056USD
per GB per hour 0.00553USD
かなり安い
ECS とで2重に料金体系が発生するということもなさそう
ECS Fargate 環境のセットアップ
Fargate を使用した Amazon ECS の使用開始
構築時には下記を追加しておく、権限が強いため作成する人と、実際にアプリケーションをデプロイする人で権限は分けたほうが良さそう
ドキュメントで 管理者権限か~と言っているくらい要求する権限が多く大変
AmazonVPCFullAccess
AmazonECS_FullAccess
- App Mesh
- Application Auto Scaling
- Cloud Map
- CloudFormation
- CloudWatch
- CloudWatch Logs
- CodeDeploy
- EC2
- EC2 Auto Scaling
- Elastic Container Service
- ELB
- ELB v2
- EventBridge
- IAM
- Lambda
- Route 53
- SNS
- Systems Manager
AmazonECSTaskExecutionRolePolicy
- CloudWatch Logs
- Elastic Container Registry
IAM
AWSCloudFormationFullAccess
{
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy",
"iam:CreateRole",
"iam:PutRolePolicy"
],
"Resource": "*"
}
ECSのセットアップ
初期画面からチュートリアルをすすめるとデフォルトで Fargate を利用して ECS クラスターが作成される
作成には最大10分くらいかかる場合もあるらしい
作成後、サービス表示から ELB アクセスし
ELB の URL にアクセスするとサンプルのアプリケーションが表示される
CodeCommit からイメージの作成
Docker で動かすアプリケーションを用意して 作成した ECS にデプロイする
CodeCommitの準備
こちらを参考に既にあるものを利用するのでスキップ
Dockerファイルの用意
テスト用に Hugo アプリケーションを動かしてみる
リポジトリの TOP には Dcokerfile を用意してソースに含めておく
下記のは適当に Docker Hub か AWSのドキュメントから持ってきたやつ
FROM ubuntu:18.04
# Install dependencies
RUN apt-get update && \
apt-get -y install apache2
# Install apache and write hello world message
RUN echo 'Hello World!' > /var/www/html/index.html
# Configure apache
RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && \
echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh && \
echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh && \
echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh && \
chmod 755 /root/run_apache.sh
EXPOSE 80
CMD /root/run_apache.sh
CodeBuild 用ファイルの用意
こちらもリポジトリの TOP に配置しておく
CodeBuild の Docker サンプル
ビルドに利用するランタイムバージョンについては下記を参照
CodeBuild に用意されている Docker イメージ
version: 0.2
phases:
install:
runtime-versions:
docker: 18
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
ECR リポジトリの作成
操作するための権限はAmazonEC2ContainerRegistryFullAccess
が必要
Amazon ECR 管理ポリシー
CodeBuild
ビルドプロジェクトの作成
環境変数には bildspec.yml
に渡す変数を定義する
値は ECR のレポジトリ名
- AWS_ACCOUNT_ID
- AWS_DEFAULT_REGION
- IMAGE_REPO_NAME
- IMAGE_TAG
自動作成されたロールに ECR へのアクセス権限 AmazonEC2ContainerRegistryPowerUser
を追加しておき
ビルドしてみる
成功すれば ECR に イメージが登録される
ECRからECSへのリリース
ALB の作成
コンテナ用にALBを利用するのでターゲットグループ以外は作成しておく
クラスターサービスの作成
クラスターからサービスを追加
タスクの作成
タスク定義より作成したイメージでタスクを作成
ECS + ALB の構成上ターゲットグループはリスニングポート 80/443 でしか作成出来ないためコンテナ登録時は注意する
サービスの作成
タスクからサービスの作成を行う
サービス内にELBの設定を行う事ができるのは作成時のみのため注意
デプロイ方法の選択(Blue/Green Deploy)も初期作成時のみ設定可能
CodePipeline の設定
タスク定義
Amazon ECR ソースと、ECS と CodeDeploy 間のデプロイでパイプラインを作成する
ECS のクラスタータスクをtaskdef.json
ファイル形式でソースに入れておく
事前に作成してある ECSタスク定義のJSONから抜粋する
{
"executionRoleArn": "arn:aws:iam::194180380675:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "{コンテナ名}",
"image": "<IMAGE1_NAME>",
"essential": true,
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
]
}
],
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc",
"cpu": "{コンテナCPUサイズ}",
"memory": "{コンテナメモリサイズ}",
"family": "{タスク名}"
}
※デプロイ時に cpu や memory の 値を変えても反映はされてなかった、どこまで効いてるんだろ?
Appspec定義
CodeDeployで利用する定義ファイルを作成
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
※LBの定義とか書かなくても問題ない、どこまで利用されてるんだろ?
buildspecファイルの定義
Did not find the image definition file imagedefinitions.json in the input artifacts ZIP file. Verify the file is stored in your pipeline’s Amazon S3 artifact bucket
Unable to access the artifact with Amazon S3 object key ‘codepip-ecr/BuildArtif/VkvHOBW’ located in the Amazon S3 artifact bucket ‘codepipeline-ap-northeast-1-****************’. The provided role does not have sufficient permissions.
Codepipeline でビルド時に利用される buildspec にアーティファクト定義とimagedefinitions.jsonの定義を追加する
イメージ定義ファイルのリファレンス
version: 0.2
phases:
install:
runtime-versions:
docker: 18
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
- $TASKDEF_FILE
CodePipelineの作成
CodeCommit に更新があったら CodeBuild に連携して Image をビルドするようにする
基本的な話は こちら をみておく
ビルドの設定はこんなかんじ
イメージビルド用の環境変数を定義し、イメージタグを変数から受け取るようにしておく
変数の操作
ここではローリングアップデートの手順になる
ビルドステージ
ここでは一つのブランチから2つの image を作成できるよう、 pipline を2つ作成し環境変数で定義を分けている
- AWS_ACCOUNT_ID
- AWS_DEFAULT_REGION
- IMAGE_REPO_NAME
- IMAGE_TAG
- CONTAINER_NAME
- TASKDEF_FILE
Pipeline で指定したロールに ECS への権限が無いため最初はコケる
ロールに AWSCodeDeployRoleForECS
権限を付与しておく
CodeDeployパターン
Codepipeline のデプロイフェーズを CodeDeploy で行うようにすると
Blue/Green デプロイが行えるようになるし
手動で ECR から Deploy したいなという時に ECS をいじらずに済むようになる
Blue/Green はここではやらない(理解できてない)
最終構成
課題
AutoScale考えられてない
作るのでいっぱいで本番のAutoScale設定が出来ていない
後でも作れるので利用状況みて考えよう
Blue/Green デプロイ
今回は出来なかったが、 Blue/Green デプロイを行うためには何を考えなければ行けないか
どういう構成にする必要があるか(環境別で ECS のサービスを分けては駄目なんだな)とかが少し見えてきた
同 Cluster 内に別で検証用 タスクとサービスを作ればいいだけなのでどこかで検証する
ただ本番と検証をどう LB で切り替えてるのかがよくわかってない
デプロイに時間がかかる
Dockerfile の中身によるが、git push から ECS へのデプロイ完了までは5分~10分かかる
かかりすぎ
イメージを軽くするとか、ビルド時間を短縮する検討が必要
本番手動デプロイの方法
あまりECS側の操作は行わせたくなく(IAM権限的に)
ポチっと CodeDeploy のボタンひとつでデプロイできるようになれればよかったが、そこまで出来てない
構成をあらかた作り終わった後に「あれ?これ本来の使い方の構成じゃない気がする」と気がついた
同様の定義が多すぎるbuildspec.yml
、appspec.yml
、taskdef.json
、`Dockerfile` など ポートや LB や コンテナ名やイメージ名や
記述の重複する箇所が多々あるため、既存の設定も含めどちらが優先されているのか?
どこまで定義の内容が反映されるのかわかりにくい
定義がなくてもすんなり行ったり、間違ってても既存の設定のまま上手く動いたりする