概要
- AWS ECSでのタスク定義を行う際のCPU、メモリについてメモ
- ECSでのCPU・メモリの設定と、Dockerコマンドの対応のメモ
公式ドキュメント
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definitions.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/memory-management.html
タスクサイズでの設定
CPU ユニット、メモリ共にハード制限の設定を行うことが可能。下記のようにFargateでは必須、EC2起動タイプではオプションとなっており、コンテナ定義での設定の省略が可能。
タスクサイズにより、タスクの固定サイズを指定できます。Fargate 起動タイプを使用したタスクにはタスクサイズが必須で、EC2 起動タイプではオプションです。タスクサイズが設定されている場合、コンテナレベルのメモリ設定はオプションです。
タスクメモリ
タスクに適用されるメモリのハード制限。コンテナ定義のハード制限と同義。
EC2 起動タイプを使用する場合、このフィールドはオプションです。クラスターに、リクエストされたメモリが利用できる登録されたコンテナインスタンスがない場合、タスクは失敗します。
タスクCPU
タスクに適用されるCPU ユニットのハード制限。 ドキュメント上ではハード制限と記述されているが、コンテナ定義のCPU ユニット数と同義か。
EC2 起動タイプを使用する場合、このフィールドはオプションです。クラスターに、リクエストされた CPU ユニットが利用できる登録されたコンテナインスタンスがない場合、タスクは失敗します。
コンテナ定義
メモリ制限:ソフト制限(memoryReservation)
--memory-reservation オプションを docker run にマッピングする。ホストのメモリに余裕がある時は制限以上のメモリを使用する場合もあり。制限を超過しないことを保証する訳ではない。ECSではこの値を見て、コンテナを追加できるか判断している。
コンテナ用に予約するメモリのソフト制限 (MiB 単位)。システムメモリが競合している場合、Docker はコンテナメモリをこのソフト制限に維持しようとします。ただし、コンテナは必要に応じて、memory パラメータで指定したハード制限 (該当する場合)、またはコンテナインスタンスの使用可能なメモリの、いずれか先に達するまで、追加のメモリを消費できます。このパラメータは、Docker Remote API の コンテナを作成する セクションの MemoryReservation にマッピングし、--memory-reservation オプションを docker run にマッピングします。
メモリ制限:ハード制限(memory)
--memory オプションを docker run にマッピングする。コンテナが指定した以上のメモリを使用する場合は OOMKiller が走り、コンテナが停止される。
コンテナに適用されるメモリの量 (MiB 単位)。コンテナは、ここで指定したメモリを超えようとすると、強制終了されます。タスク内のすべてのコンテナ用に予約されるメモリの合計量は、タスクの memory 値より小さくする必要があります (指定されている場合)。このパラメータは、Docker Remote API の コンテナを作成する セクションの Memory にマッピングし、--memory オプションを docker run にマッピングします。
コンテナが Fargate 起動タイプを使用したタスクの一部である場合、このフィールドはオプションです。
CPU ユニット数
--cpu-shares オプションを docker run にマッピングする。
Amazon ECS コンテナエージェントがコンテナ用に予約した cpu ユニットの数です。このパラメータは、Docker Remote API の コンテナを作成する セクションの CpuShares にマッピングし、--cpu-shares オプションを docker run にマッピングします。
Fargate 起動タイプを使用するタスクでは、このフィールドはオプションです。その場合、タスク内のすべてのコンテナ用に予約される CPU の合計量が、タスクレベルの cpu の値を下回ることが唯一の要件となります。
対応するDockerコマンド
ECSでのリソース制限では、docker run にオプションをマッピングしているので、そもそもdockerがどのようにリソースを管理しているか、dockerコマンドでメモリ制限・ハード制限を行うためのコマンドをメモ。
公式ドキュメント
CPU制限(--cpu-shares)
共有するCPUの割合を相対的な値として設定するもの。
デフォルトでは、全てのコンテナは同じ CPU サイクルの割合を持っています。この割合は変更可能なものであり、コンテナの CPU 共有ウエイトを、実行中の全てのコンテナに対する相対的な値として変更できます
例えば、3つのコンテナがあるとしましょう。1つめの CPU 共有は 1024 で、残り2つの CPU 共有は 512 とします。もし3つのコンテナが CPU を 100% 使用している状態になれば、1つめのコンテナが合計 CPU 時間の 50% を扱えます。4つめのコンテナを CPU 共有 1024 として追加したら、1つめのコンテナが得られるのは CPU の 33% になります。そして、残りの2つめ以降のコンテナが得られる CPU 時間は、それぞれ 16.5%(2つめ)、16.5%(3つめ)、33% (4つめ)となります。
docker run -–cpu-shares [CPU] [IMAGE]
その他CPUに関するオプション
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit CPU real-time period in microseconds
--cpu-rt-runtime int Limit CPU real-time runtime in microseconds
--cpu-shares int CPU shares (relative
--cpus decimal Number of --cpuset-cpus string CPUs in which to allow execution (0-3, --cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--cpu-period、 --cpu-quota 等は今のところECSのタスク定義では設定することができない。
メモリ制限
メモリ制限の種類は、ECSの項目にもあった通り、ハード制限とソフト制限が存在する。
ハード制限(memory) は ソフト制限(memoryReservation) より大きいことが必要。
ハード制限(--memory)
docker run --memory [メモリ] [IMAGE]
ソフト制限(--memoryReservation)
docker run --memory-reservation [メモリ] [IMAGE]
helpで確認できるメモリ関係のコマンドの一覧。memory は memoryReservation より大きいことが必要。
--memory bytes Memory limit
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--memory-swappiness int Tune container memory swappiness (0 to 100) (default -1)
実際にコマンドを実行してみる。ハード制限、ソフト制限でメモリを指定したコンテナをそれぞれ立ち上げてみる。
docker run -d --memory 4MB [IMAGE]
docker run -d --memory-reservation 4MB [IMAGE]
ハード制限での指定は、MEM USAGE / LIMIT で 設定されているのを確認できる。
ソフト制限を行った設定については、docker stats上では確認することができない・・・?
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
2468e6dbc5c6 beautiful_heyrovsky 0.00% 1.449MiB / 4MiB 36.23% 718B / 0B 0B / 0B 3
29acf48ef4d4 naughty_khorana 0.00% 1.492MiB / 3.855GiB 0.04% 928B / 0B 1.81MB / 0B 3
yes > /dev/null & 等で負荷を与えた時、ハード制限を行ったものに関して、制限以上のメモリを使用することはなかった。
ソフト制限をを行ったコンテナに関しては、ホストのメモリに余裕がある場合は、制限以上のメモリを使用する。
その他オプション
--oom-kill-disable
docker run のデフォルトでは、OOMエラーが発生したら、コンテナ内のプロセスを停止(kill)する。このオプションでコンテナを OOM killer による停止を無効化するかどうか指定することができる。
docker run --oom-kill-disable [IMAGE]
参考
https://aws.amazon.com/jp/premiumsupport/knowledge-center/allocate-ecs-memory-tasks/
https://knowledge.sakura.ad.jp/5118/
https://qiita.com/irotoris/items/944aba5e448a8e723ff6
https://dev.classmethod.jp/cloud/aws/ecs-resources-knowledge-for-ecs-with-ec2/
https://qiita.com/naomichi-y/items/d933867127f27524686a