tl;dl
CloudWatch で ECS のメトリクスが取れるようになったとのことでどんな風に取れるのかをまずは確認してみた。
尚、あくまでも確認レベルなので毎度の如く薄っぺらい内容ですいません。
確認に際しては以下の教材を利用。
terraform apply
一発で 1 台のコンテナインスタンスに 3 つの Task definition と 3 つの Service が登録され、それぞれ yes
コマンドが起動するコンテナがトータル 4 台起動する。
参考
- What is Amazon EC2 Container Service? – Amazon EC2 Container Service
- aws/amazon-ecs-agent · GitHub
- docker/libcontainer · GitHub
メトリクス取得の前提条件
参考
- http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cloudwatch-metrics.html
- http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container_agent_versions.html
前提条件
- Amazon ECS container agent 1.4.0 以上(旧バージョンが動いている場合にはアップデートが必要)
- 最新の ECS-optimized AMI を利用を利用することで ECS container agent は 1.4.0 になる
ECS container agent のアップデート
バージョン確認
ECS agent が動作している状態で以下を実行。
$ curl -s 127.0.0.1:51678/v1/metadata | python -mjson.tool { "Cluster": "kappa-cluster", "ContainerInstanceArn": "arn:aws:ecs:ap-northeast-1:1234567890123:container-instance/92be2a6e-e09e-44a6-91b1-c127528b104d", "Version": "Amazon ECS Agent - v1.2.1 (5da1555)" }
ECS-optimized AMI の場合
以下の三パターンでアップデートを行う。
- Management Console より(試した)
- AWS CLI にて(試せてない)
- ecs-init の更新(試した)
今回は 3. の ecs-init のアップデートを行った際のメモ。尚、利用した terraform 教材では user-data でアップデートを行っている。
ecs-init の更新による ECS container agent のアップデート
以下の通り ecs-init を更新する。
$ sudo yum update -y ecs-init Failed to set locale, defaulting to C Loaded plugins: priorities, update-motd, upgrade-helper amzn-main/2015.03 | 2.1 kB 00:00 amzn-updates/2015.03 | 2.3 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package ecs-init.x86_64 0:1.2.1-2.amzn1 will be updated ---> Package ecs-init.x86_64 0:1.4.0-1.amzn1 will be an update --> Finished Dependency Resolution Dependencies Resolved ================================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================================= Updating: ecs-init x86_64 1.4.0-1.amzn1 amzn-updates 1.8 M Transaction Summary ================================================================================================================================================================================================= Upgrade 1 Package Total download size: 1.8 M Downloading packages: ecs-init-1.4.0-1.amzn1.x86_64.rpm | 1.8 MB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : ecs-init-1.4.0-1.amzn1.x86_64 1/2 Cleanup : ecs-init-1.2.1-2.amzn1.x86_64 2/2 Verifying : ecs-init-1.4.0-1.amzn1.x86_64 1/2 Verifying : ecs-init-1.2.1-2.amzn1.x86_64 2/2 Updated: ecs-init.x86_64 0:1.4.0-1.amzn1 Complete!
update 時の ecs-agent.log は以下の通り。
2015-08-18T22:37:13Z [INFO] Starting Agent: Amazon ECS Agent - v1.2.1 (5da1555) 2015-08-18T22:37:13Z [INFO] Loading configuration 2015-08-18T22:37:13Z [INFO] Checkpointing is enabled. Attempting to load state 2015-08-18T22:37:13Z [INFO] Loading state! module="statemanager" 2015-08-18T22:37:13Z [INFO] Registering Instance with ECS 2015-08-18T22:37:13Z [INFO] Registered! module="api client" 2015-08-18T22:37:13Z [INFO] Registration completed successfully. I am running as 'arn:aws:ecs:ap-northeast-1:1234567890123:container-instance/48bdc389-3272-44fb-8301-a7734da0c672' in cluster 'kappa-cluster' 2015-08-18T22:37:13Z [INFO] Saving state! module="statemanager" 2015-08-18T22:37:13Z [INFO] Beginning Polling for updates 2015-08-18T22:37:13Z [INFO] Creating poll dialer module="ws client" host="ecs-a-1.ap-northeast-1.amazonaws.com" 2015-08-18T22:37:23Z [INFO] Saving state! module="statemanager" 2015-08-18T22:39:13Z [INFO] Saving state! module="statemanager" 2015-08-18T22:39:22Z [INFO] Starting Agent: Amazon ECS Agent - v1.4.0 (4ab1051) 2015-08-18T22:39:22Z [INFO] Loading configuration 2015-08-18T22:39:22Z [INFO] Checkpointing is enabled. Attempting to load state 2015-08-18T22:39:22Z [INFO] Loading state! module="statemanager" 2015-08-18T22:39:22Z [INFO] Restored cluster 'kappa-cluster' 2015-08-18T22:39:22Z [INFO] Restored from checkpoint file. I am running as 'arn:aws:ecs:ap-northeast-1:1234567890123:container-instance/48bdc389-3272-44fb-8301-a7734da0c672' in cluster 'kappa-cluster'
改めてバージョン確認。
$ curl -s 127.0.0.1:51678/v1/metadata | python -mjson.tool { "Cluster": "sample-cluster", "ContainerInstanceArn": "arn:aws:ecs:ap-northeast-1:1234567890123:container-instance/72806f6a-34e1-40de-aca6-03c7286b7aa1", "Version": "Amazon ECS Agent - v1.4.0 (4ab1051)" }
メトリクス取得
取得されるメトリクス
以下のように Cluster と Service 毎のメトリクスが収集される。
CPU Utilization
- Cluster CPU Utilization
- Service CPU Utilization
Memory Utilization
- Cluster Memory Utilization
- Service Memory Utilization
Cluster CPU Utilization / Cluster Memory Utilization
概要
ドキュメントより抜粋とざっくり意訳。
Cluster CPU utilization (metrics that are filtered by ClusterName without ServiceName) is measured as the total CPU units in use by Amazon ECS tasks on the cluster, divided by the total CPU units that were registered for all of the container instances in the cluster.
Cluster 内の稼働中コンテナの CPU 使用ユニット数 x 100 をコンテナインスタンスに割り当てられている CPU ユニット数で割った数値(単位は%)、以下は計算式。
(Total CPU units used by tasks in cluster) x 100 Cluster CPU utilization = -------------------------------------------------------------- (Total CPU units registered by container instances in cluster)
Cluster memory utilization (metrics that are filtered by ClusterName without ServiceName) is measured as the total memory in use by Amazon ECS tasks on the cluster, divided by the total amount of memory that was registered for all of the container instances in the cluster.
Cluster 内の稼働中コンテナのメモリ使用量 x 100 をコンテナインスタンスに割り当てられているメモリ使用量で割った数値(単位は%)、以下は計算式。
(Total MiB of memory used by tasks in cluster x 100) Cluster memory utilization = ------------------------------------------------------------------ (Total MiB of memory registered by container instances in cluster)
メトリクス
- ECS コンソールから確認
- CloudWatch コンソールから確認
Service CPU Utilization / Service Memory Utilization
概要
これまた…ドキュメントより抜粋とざっくり意訳。
Service CPU utilization (metrics that are filtered by ClusterName and ServiceName) is measured as the total CPU units in use by the tasks that belong to the service, divided by the total number of CPU units that are reserved for the tasks that belong to the service.
以下、計算式(の方が解りやすい)。
(Total CPU units used by tasks in service) x 100 Service CPU utilization = ---------------------------------------------------------------------------- (Total CPU units reserved in task definition) x (number of tasks in service)
サービス内 Task の CPU ユニット数 ✕ 100 を definition で確保している CPU ユニット数 ✕ サービス内のコンテナ数で割った数値(単位は%)。
Service memory utilization (metrics that are filtered by ClusterName and ServiceName) is measured as the total memory in use by the tasks that belong to the service, divided by the total memory that is reserved for the tasks that belong to the service.
以下、計算式。
(Total MiB of memory used by tasks in service) x 100 Service memory utilization = -------------------------------------------------------------------------------- (Total MiB of memory reserved in task definition) x (number of tasks in service)
サービス内メモリ使用量 ✕ 100 を Task definition で確保しているメモリ容量 ✕ サービス内のコンテナ数で割った数値(単位は%)。
メトリクス
- ECS コンソールから確認
- CloudWatch コンソールから確認
最後に
CloudWatch で取得出来るようになったのは
- サードパーティ製のツールに頼るしか無いのかなと思っていたので嬉しい
- Datadog や mackerel での監視と単純に比較出来ない部分がありそう(メトリクスの収集は cgroup から取得している部分は同じだと思う)
残っている疑問
ECS container agent は libcontainer 経由で cgroup からメトリクスの元となる情報を収集していそうなことは解ったが以下のような疑問が残っている。
- 根本的な見落としがあるかもしれないが Total CPU unit used の算出方法
- ECS container agent 分の CPU unit は計上されているのか
- Docker のドキュメントには CPU リソースに関しては cpuacct.stat の値を取得しているが ECS container agent でも同様か
ドキュメントをちゃんと読み込めていないだけかもしれないが、引き続き調べたい。
ドキュメントの抜粋が多くて
すいません。
その他
yes コマンドの出力は /dev/null に捨てた方が良さそう
yes
を使えば簡単にコンテナに負荷を掛けることが出来るが、yes
だけ実行していると以下のようなログを吐いて Docker プロセスもろとも落ちてしまう現象に遭遇…(※ Docker 1.6.2 にて確認)
fatal error: runtime: out of memory goroutine 495 [running]: runtime.throw(0x11abaf7) /usr/lib/golang/src/pkg/runtime/panic.c:520 +0x69 fp=0x7f0d7077ab08 sp=0x7f0d7077aaf0 runtime.SysMap(0xc233000000, 0x10000000, 0x416e00, 0x11cee98) /usr/lib/golang/src/pkg/runtime/mem_linux.c:147 +0x93 fp=0x7f0d7077ab38 sp=0x7f0d7077ab08 runtime.MHeap_SysAlloc(0x11dae80, 0x10000000)
多分、こちらの issue に類似の現象。--log-driver=none
とする対処方法も掲示されているが、ECS の Task definition で docker run
のオプションを渡す方法が解らなかったので yes > /dev/null
で。