これは、なにをしたくて書いたもの?
Amazon ECS CLIを使うと、Amazon ECSのタスク定義をローカルで実行できるらしいので、ちょっと試してみようかなと。
Amazon ECS CLI
Amazon ECS CLIは、ローカルからAmazon ECS上でのアプリケーションの構築、リリース、運用ができるとされているツールです。
Amazon ECS コマンドラインインターフェースの使用 - Amazon Elastic Container Service
このAmazon ECS CLIを使って、task-definition.json
またはdocker-compose.ecs-local.yml
からAmazon ECSタスク定義を実行できる
ようです。
ecs-cli local - Amazon Elastic Container Service
今回は、こちらを簡単に試してみましょう。
環境
今回の環境は、こちら。
$ docker version Client: Docker Engine - Community Version: 20.10.16 API version: 1.41 Go version: go1.17.10 Git commit: aa7e414 Built: Thu May 12 09:17:23 2022 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.16 API version: 1.41 (minimum version 1.12) Go version: go1.17.10 Git commit: f756502 Built: Thu May 12 09:15:28 2022 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.4 GitCommit: 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16 runc: Version: 1.1.1 GitCommit: v1.1.1-0-g52de29d docker-init: Version: 0.19.0 GitCommit: de40ad0
Docker Composeも使うようです。
$ docker compose version Docker Compose version v2.6.0
もっとも、この実行形態ではAmazon ECS CLIは使えなかったのですが…。後に少し細工をします。
Amazon ECS CLIをインストールする
Amazon ECS CLI をインストールします。 - Amazon Elastic Container Service
Windows、Linux、macOSに対応しているようです。
ダウンロード。
$ sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-linux-amd64-latest
実行権限の付与。
$ sudo chmod +x /usr/local/bin/ecs-cli
署名の検証についても書かれていますが、今回はパスしておきます。
タスク定義の用意
Amazon ECS CLIを使ってローカルでタスク定義を実行するには、タスク定義を記述したtask-definition.json
かDocker Composeの
構成ファイルが必要になるようです。
もっとも、task-definition.json
を使っても結局Docker Composeの構成ファイルを生成するようなのですが。
とりあえず、タスク定義としてこのようなものを用意。
task-definition.json
{ "containerDefinitions": [ { "name": "nginx", "image": "nginx:1.22.0", "essential": true, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "links": [ "mysql" ], "memory": 256 }, { "name": "mysql", "image": "mysql:8.0.29", "environment": [ { "name": "MYSQL_ROOT_PASSWORD", "value": "password" } ] } ], "family": "webdb" }
nginxとMySQLを含めていますが、特に関連はありません…。
Amazon ECS CLIを使って、ローカルでタスクを実行する
では、Amazon ECS CLIを使って、ローカルでAmazon ECSのタスク定義からコンテナを実行していきたいと思います。
手順的にはecs-cli local create
でtask-definition.json
からdocker-compose.ecs-local.yml
を生成するか、ecs-cli local up
で
task-definition.json
からdocker-compose.ecs-local.yml
を生成しつつ実行する方法があるようです。
とりあえず、ドキュメントとヘルプを見てみましょう。
ecs-cli local create
は、Amazon ECSタスク定義からDocker Composeの構成ファイルを作成するコマンドです。
ecs-cli local create - Amazon Elastic Container Service
$ ecs-cli local create --help NAME: ecs-cli local create - Creates a Compose file from an ECS task definition. USAGE: ecs-cli local create [command options] [arguments...] OPTIONS: --task-def-file value, -f value Specifies the filename value that contains the task definition JSON to convert to a Docker Compose file. If one is not specified, the ECS CLI will look for task-definition.json. --task-def-remote value, -t value Specifies the full Amazon Resource Name (ARN) or family:revision value of the task definition to convert to a Docker Compose file. If you specify a task definition family without a revision, the latest revision is used. --output value, -o value Specifies the local filename value to write the Docker Compose file to. If one is not specified, the default is docker-compose.ecs-local.yml. --force Overwrite output docker compose file if it exists. Default compose file is docker-compose.ecs-local.yml. --use-role Uses the task role ARN instead of temporary credentials.
ecs-cli local up
は、タスク定義からコンテナをローカルで実行するコマンドです。
ecs-cli local up - Amazon Elastic Container Service
$ ecs-cli local up --help NAME: ecs-cli local up - Runs containers locally from an ECS Task Definition. NOTE: Creates a docker-compose file in current directory and a ecs-local-network if one doesn't exist. USAGE: ecs-cli local up [command options] [arguments...] OPTIONS: --task-def-compose value, -c value Specifies the filename value that contains the Docker Compose content to run locally. --task-def-file value, -f value Specifies the filename value containing the task definition JSON to convert and run locally. If one is not specified, the ECS CLI will look for task-definition.json. --task-def-remote value, -t value Specifies the full Amazon Resource Name (ARN) or family:revision value of the task definition to convert and run locally. If you specify a task definition family without a revision, the latest revision is used. --output value, -o value Specifies the local filename value to write the Docker Compose file to. If one is not specified, the default is docker-compose.ecs-local.yml. --override value Specifies the local Docker Compose override filename value to use. --force Overwrite output docker compose file if it exists. Default compose file is docker-compose.ecs-local.yml.
まずはecs-cli local create
を実行してみます。特にファイル名を指定しない場合は、task-definition.json
を使うようです。
$ ecs-cli local create INFO[0000] Reading task definition from /path/to/task-definition.json INFO[0000] Successfully wrote docker-compose.ecs-local.yml INFO[0000] Successfully wrote docker-compose.ecs-local.override.yml
そして、Docker Composeの構成ファイルが作成されました。
docker-compose.ecs-local.yml
version: "3.4" services: mysql: environment: AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: /creds ECS_CONTAINER_METADATA_URI: http://169.254.170.2/v3 MYSQL_ROOT_PASSWORD: password image: mysql:8.0.29 labels: ecs-local.task-definition-input.type: local ecs-local.task-definition-input.value: /path/to/task-definition.json networks: ecs-local-network: null nginx: environment: AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: /creds ECS_CONTAINER_METADATA_URI: http://169.254.170.2/v3 image: nginx:1.22.0 labels: ecs-local.task-definition-input.type: local ecs-local.task-definition-input.value: /path/to/task-definition.json links: - mysql networks: ecs-local-network: null ports: - target: 80 published: 80 networks: ecs-local-network: external: true
docker-compose.ecs-local.override.yml
version: "3.4" services: mysql: logging: driver: json-file nginx: logging: driver: json-file
Amazon ECS CLIで使えるDocker Composeの構文は、こちらのようです。
Docker Compose ファイル構文の使用 - Amazon Elastic Container Service
続いて、ecs-cli local up
してみます。
$ ecs-cli local up
すると、docker-compose.ecs-local.yml
の上書きを聞かれます。
docker-compose.ecs-local.yml file already exists. Do you want to write over this file? [y/N]
結局のところ、必要なのはタスク定義というよりDocker Composeの構成ファイルなわけですね。
で、進めようとするとdocker-compose
がないということでエラーになりました。
FATA[0000] docker-compose up failed to start due to: exec: "docker-compose": executable file not found in $PATH
あくまでdocker-compose
が必要なようです…。
仕方がないので、こんなスクリプトを作成。
/usr/local/bin/docker-compose
#!/bin/bash docker compose "$@"
実行権限を付与。
$ sudo chmod a+x /usr/local/bin/docker-compose
気を取り直して、実行。
$ ecs-cli local up INFO[0000] Reading task definition from /path/to/task-definition.json INFO[0000] Successfully wrote docker-compose.ecs-local.yml INFO[0000] Successfully wrote docker-compose.ecs-local.override.yml INFO[0000] The network ecs-local-network already exists INFO[0000] The amazon-ecs-local-container-endpoints container already exists with ID fc9f664c8ea0c9b34f8782b47af7b1d51ff4c88799f54241fa37cdf16027cfea INFO[0000] Started container with ID fc9f664c8ea0c9b34f8782b47af7b1d51ff4c88799f54241fa37cdf16027cfea FATA[0000] Failed to create a SSM client to decrypt secrets due to failed to create a new AWS session due to Set a region using ecs-cli configure command with the --region flag or AWS_REGION environment variable or --profile flag: Set a region using ecs-cli configure command with the --region flag or AWS_REGION environment variable or --profile flag
リージョンの指定が必要みたいですね。
AWS_REGION
を指定して実行。
$ AWS_REGION=ap-northeast-1 ecs-cli local up
今度は、うまくいきました。
$ AWS_REGION=ap-northeast-1 ecs-cli local up INFO[0000] Reading task definition from /path/to/task-definition.json docker-compose.ecs-local.yml file already exists. Do you want to write over this file? [y/N] y INFO[0001] Successfully wrote docker-compose.ecs-local.yml INFO[0001] docker-compose.ecs-local.override.yml already exists, skipping write. INFO[0001] The network ecs-local-network already exists INFO[0001] The amazon-ecs-local-container-endpoints container already exists with ID fc9f664c8ea0c9b34f8782b47af7b1d51ff4c88799f54241fa37cdf16027cfea INFO[0001] Started container with ID fc9f664c8ea0c9b34f8782b47af7b1d51ff4c88799f54241fa37cdf16027cfea INFO[0001] Using docker-compose.ecs-local.yml, docker-compose.ecs-local.override.yml files to start containers [+] Running 2/2 ⠿ Container ecs-cli-local-mysql-1 Started 3.4s ⠿ Container ecs-cli-local-nginx-1 Started 2.1s
起動しているコンテナの確認。
$ ecs-cli local ps CONTAINER ID IMAGE STATUS PORTS NAMES TASKDEFINITION 779cd34ab1e5 nginx:1.22.0 Up 4 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp /ecs-cli-local-nginx-1 /path/to/task-definition.json e4bb51990b0a mysql:8.0.29 Up 4 minutes :0->3306/tcp, :0->33060/tcp /ecs-cli-local-mysql-1 /path/to/task-definition.json
nginxについては、ポートマッピングをしていたのでローカルポートでアクセスできます。
$ curl -i localhost HTTP/1.1 200 OK Server: nginx/1.22.0 Date: Thu, 02 Jun 2022 16:40:51 GMT Content-Type: text/html Content-Length: 615 Last-Modified: Mon, 23 May 2022 23:59:19 GMT Connection: keep-alive ETag: "628c1fd7-267" Accept-Ranges: bytes <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
ちなみに、docker container ps
で見るとamazon-ecs-local-container-endpointsというコンテナがあったりします。
$ docker container ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 779cd34ab1e5 nginx:1.22.0 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp ecs-cli-local-nginx-1 e4bb51990b0a mysql:8.0.29 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 3306/tcp, 33060/tcp ecs-cli-local-mysql-1 fc9f664c8ea0 amazon/amazon-ecs-local-container-endpoints "/local-container-en…" About an hour ago Up About an hour 80/tcp amazon-ecs-local-container-endpoints
コンテナを停止する時は、ecs-cli local down
。
ecs-cli local down - Amazon Elastic Container Service
$ ecs-cli local down
とりあえずはこんなところでしょうか。
だいぶ限定的ではありますが、タスク定義をローカルで試してみる手段のひとつとして把握していてもよいのかな、と思いました。