前回、AWSの既存環境をIaC化するために、former2 を使用する環境をEC2上に作成しました。
Dockerfile で提供されているので、せっかくなので学習の意味も込めて、WebブラウザのGUIではなくAWS CLI を使用して、コンテナサービスであるECSを使用してにデプロイしてみます。
やること
- former2 の環境を、ECSでデプロイする
- AWS CLI を使用する
前提
- docker および AWS CLI が実行できる環境を用意します
- 今回はあらかじめEC2にdockerをインストールしたものを用意してます
- アクセスキーIDとシークレットアクセスキーがあるものとします
概要
大まかな流れは以下の通りです。
- AWS CLI にアクセスキー等を紐づける
- github から former2 のソース(Dockerfile)をダウンロードし、Dockerイメージにビルドする
- ビルドしたイメージをECRにアップロードする
- ECS にデプロイする
手順
1. AWS CLI にアクセスキー等を紐づける
既にAWS CLIがインストールされている環境で以下を実行します。
# AWS CLI の設定
$ aws configure
AWS Access Key ID [None]: <アクセスキーIDを入力>
AWS Secret Access Key [None]: <シークレットアクセスキーを入力>
Default region name [None]: ap-northeast-1
Default output format [None]:
2. github から former2 のソース(Dockerfile)をダウンロードし、Dockerイメージにビルドする
以下が former2 のリポジトリです。MITライセンスです。
ダウンロードしてDockerイメージにビルドします。
# former2 のリポジトリをダウンロード
$ git clone https://github.com/iann0036/former2.git
# former2 の Docker イメージをビルド
$ cd former2
$ docker build -t former2 .
以下を実行してイメージがビルドされたか確認できます。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
former2 latest fb4eb2102ea3 26 seconds ago 369MB
3. ビルドしたイメージをECRにアップロードする
ECS でデプロイするためには、コンテナイメージを ECR にアップロードする必要があるみたいです。たぶん・・・
まず、ECR リポジトリを作成します。
$aws ecr create-repository --repository-name former2
# 以下実行結果
{
"repository": {
"repositoryUri": "{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/former2",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
},
"registryId": "{アカウントID}",
"imageTagMutability": "MUTABLE",
"repositoryArn": "arn:aws:ecr:ap-northeast-1:{アカウントID}:repository/former2",
"repositoryName": "former2",
"createdAt": xxxxx.0
}
}
以下を実行し、作成したECRリポジトリに、Dockerイメージをアップロードします。
# ECRにログイン
$ aws ecr get-login-password | docker login --username AWS --password-stdin {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com
# ECRにアップロードする用にDockerイメージをタグ付け(ここでは、バージョンを日付20230504としています。任意の文字列でよいです)
$ docker tag former2:latest {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/former2:20230504
# ECRにアップロード
$ docker push {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/former2:20230504
4. ECS にデプロイする
ECSクラスター作成 → ECSタスク作成 → ECSサービス作成という流れでデプロイを実行できます。
まず、ECSクラスターを作成します。
$ aws ecs create-cluster --cluster-name {クラスター名}
次に、ECSタスクを作成します。
ここでは、コンテナ起動時の設定をJSONファイルで定義し、それをアップロードする方法で実行します。
// EcsTaskDefinition.json
{
"family": "{タスク名}",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"containerDefinitions": [
{
"name": "former2",
"image": "{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/former2:20230504",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
]
}
],
"memory": "1 GB",
"cpu": ".5 vCPU",
"executionRoleArn": "arn:aws:iam::{アカウントID}:role/ecsTaskExecutionRole"
}
# タスク定義をアップロードで作成
$ aws ecs register-task-definition --cli-input-json file://EcsTaskDefinition.json
次にECSサービスを作成します。
# 注:subnet-XXXXX や sg-XXXXX はあらかじめ作成したものを指定する必要があります
aws ecs create-service \
--cluster {クラスター名} \
--service-name {サービス名} \
--task-definition arn:aws:ecs:ap-northeast-1:{アカウントID}:task-definition/{タスク名} \
--launch-type FARGATE \
--desired-count 1 \
--network-configuration "awsvpcConfiguration={subnets=[subnet-XXXXX,subnet-XXXXX],securityGroups=[sg-XXXX],assignPublicIp=ENABLED}"
動作確認
上記まで実行すると、ECSが自動でサービスを起動します。
アクセスするためのIPアドレスは以下の手順で確認できます。
(結構面倒な手順ですが、これ以外なさそうです)
# タスクIDの取得
$ aws ecs list-tasks --cluster {クラスタ名} --service {サービス名} --desired-status RUNNING
{
"taskArns": [
"arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxxxxxxx/{ここに英数字文字列でタスクIDが表示される}"
]
}
# タスクIDからネットワークインターフェースIDを取得
aws ecs describe-tasks --cluster {クラスタ名} --tasks {上記で取得したタスクID} --query "tasks[].attachments[].details[?name=='networkInterfaceId'].value" --output text
# ネットワークインターフェースIDから、パブリックIPアドレスを取得
aws ec2 describe-network-interfaces --network-interface-ids {上記で取得したネットワークインターフェースID} --query "NetworkInterfaces[].Association.PublicIp" --output text
取得したIPアドレスを使用して、ブラウザに http://<IPアドレス>
を入力すると、アクセスできるはずです。
アクセスするためのIPアドレスですが、ECSタスクが起動するたびに変わるようです。
IPアドレスがコロコロ変わるのを防ぐためには、ALBを設置し、ALBにパブリックなDNSを設定する必要があるみたいです。
追記
と、さらに調べてみると、後からALBをくっつけるのはかなり厳しそう。少なくともマネジメントコンソールからは後付けできない仕様みたい・・・
とりあえず後からALBを設定する方法を端的にメモしておきます。
- AWS CLI を最新にバージョンアップする
- 古いCLIだとALBを後付けできない
- 以下を実行
$ aws ecs update-service \
--cluster {クラスタ名} \
--service {サービス名} \
--load-balancers targetGroupArn=}ターゲットグループのARN},containerName={タスクに割り当てているコンテナ名},containerPort=80
最新にしないといけなかったり、マネジメントコンソールでできなかったり。。。流石に個の仕様は糞過ぎる。
コメント