ECS で GPU インスタンスを使うときに、以前は自分で NVIDIA ドライバを入れたり、ECS エージェントを入れたりする必要がありましたが、最近(といっても昨年2月ですが)ECS GPU に最適化された AMI が出たことで ECS で GPU が使いやすくなりました。
ECS で GPU を使う機運が高まってきたので試そうと思ったのですが、参考記事が意外と少なく、ドキュメントも質素なので情報が多く出回っていないようでした。
Amazon ECS での GPU の使用 - Amazon Elastic Container Service
そこで本記事は ECS GPU-optimized AMI で ECS クラスタを構築してみました。ECS サービスは作らずに nvidia-smi
コマンドを実行するだけの簡単な ECS タスクを実行するだけです。GPU というよりも ECS のチュートリアルに近い内容となっています。
コンテナインスタンスのインスタンスタイプを g4dn.xlarge にしました。G4 インスタンスは最新世代の GPU インスタンスでありながら時間あたりの料金も安いのでちょっとした個人利用に便利です。
- EC2 インスタンスの制限緩和申請
- AWS ネットワークの構築
- タスク定義の作成
- ECS クラスタの作成
- IAM ロールの作成
- コンテナインスタンスの起動
- ECS タスクの実行
- 後片付け
- まとめ
- 参考文献
EC2 インスタンスの制限緩和申請
AWS アカウントを作成した直後は制限によって GPU インスタンスが起動できないため、サポートに制限緩和を申請する必要があります。申請が通るのに時間がかかるため一番最初にやります。
申請するにあたり、必要な vCPU 数が求められますので、vCPU 制限から確認します。
上図の[制限緩和のリクエスト]のリンクからサポートケースを開き、下図のように入力します。
項目名 | 値 |
---|---|
リージョン | アジアパシフィック(東京) |
プライマリインスタンスタイプ | All G instances |
New limit value | 4 |
[Use case description] は利用用途(ECS クラスタで GPU インスタンスを試してみたいなど)を適宜入れてください。日本語で申請できます。申請後、数分で「担当部署に確認します」というレスポンスがきます。その後、7時間ぐらいして申請が通りました*1。
AWS ネットワークの構築
VPC、サブネットの作成は省略します。コンテナインスタンスはプライベートサブネットに配置します。このサブネットに以下の VPC エンドポイントを設定します。
ゲートウェイタイプ
- com.amazonaws.ap-northeast-1.s3
インタフェースタイプ
- com.amazonaws.ap-northeast-1.ec2messages
- com.amazonaws.ap-northeast-1.ecs
- com.amazonaws.ap-northeast-1.ecs-agent
- com.amazonaws.ap-northeast-1.ecs-telemetry
- com.amazonaws.ap-northeast-1.logs
- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
また、コンテナインスタンスが Docker リポジトリからイメージを取得するために、NAT Gateway を立てる必要があります。もし NAT Gateway を立てたくない場合は、ECR にイメージを置いて ECR への VPC エンドポイントを作成します。
タスク定義の作成
タスク定義のコンソールに行き、[新しいタスク定義の作成]をクリックします。
- [起動タイプの互換性の選択]は [EC2] を選択します
- [タスクとコンテナの定義の設定]で次のように各項目を入力します。
項目名 | 値 |
---|---|
タスク定義名 | gpu-test |
ネットワークモード | awsvpc |
タスク実行ロール | なし |
タスクメモリ (MiB) | 512 |
タスク CPU (単位) | 512 |
コンテナの定義
[コンテナの追加]をクリックし、次のように各項目を入力します。ここの設定でコンテナにおける GPU 数を設定することができます。
項目グループ | 項目名 | 値 |
---|---|---|
スタンダード | コンテナ名 | gpu |
イメージ | nvidia/cuda:9.0-base | |
プライベートレジストリの認証 | チェックしない | |
メモリ制限 (MiB) | ソフト制限、256 | |
ポートマッピング | 入力しない | |
ヘルスチェック | - | すべてデフォルト値 |
環境 | CPU ユニット数 | 100 |
GPU | 1 | |
基本 | チェックする | |
エントリポイント | 入力しない | |
コマンド | sh,-c,nvidia-smi | |
作業ディレクトリ | 入力しない | |
Environment Files | 入力しない | |
環境変数 | 入力しない | |
コンテナタイムアウト | - | すべてデフォルト値 |
ネットワーク設定 | - | すべてデフォルト値 |
ストレージとログ | ログ設定 | チェックする |
セキュリティ | - | すべてデフォルト値 |
リソースの制限 | - | すべてデフォルト値 |
DOCKER ラベル | - | すべてデフォルト値 |
ECS クラスタの作成
クラスタのコンソールに行き、[クラスターの作成]をクリックします。
[クラスターテンプレートの選択]は[EC2 Linux + ネットワーキング]を選択し[次のステップ]をクリックします。
[クラスターの設定]では次のように各項目を入力して空の ECS クラスタを作成します。
項目名 | 値 |
---|---|
クラスター名 | gpu-test-cluster |
空のクラスターの作成 | チェックを入れる |
Tags | 入力しない |
CloudWatch Container Insights | チェックする |
IAM ロールの作成
後で作成するコンテナインスタンスにアタッチするための IAM ロールを作成します。IAM ロールのコンソールに行き、[ロールの作成]をクリックします。
[ユースケースの選択]で[EC2]を選択し、[次のステップ:アクセス権限]をクリックします。[Attach アクセス権限ポリシー]において、次の IAM ポリシーをアタッチします。
- AmazonEC2ContainerServiceforEC2Role
- コンテナインスタンスを起動するために必要)
- AmazonSSMManagedInstanceCore
- System Manager のセッションマネージャによるログインをするために必要
次のタグ追加の画面をスキップし、IAM ロール名を myEcsInstanceRole
と適当に命名します。
コンテナインスタンスの起動
今回は ECS サービスをつかわずに一回かぎりの ECS タスクを実行するためにコンテナインスタンスを起動します。
EC2 インスタンスのコンソールに行き、[インスタンスの作成]をクリックします。
コミュニティ AMI から ECS GPU-optimized AMI(amzn2-ami-ecs-gpu-hvm
) を検索して最新の AMI を選択します。今回は amzn2-ami-ecs-gpu-hvm-2.0.20200430-x86_64-ebs
(ami-0206eeb7625e98a0f
)にしました。
設定値は次のようにします。
項目名 | 値 |
---|---|
インスタンスタイプ | g4dn.xlarge |
インスタンス数 | 1 |
ネットワーク | 事前に作成した VPC |
サブネット | 事前に作成したサブネット |
自動割り当てパブリック IP | 無効化 |
IAM ロール | 先ほど作成した IAM ロール(myEcsInstanceRole ) |
ユーザデータ | 後述 |
タグ(Name) | gpu-test-instance |
セキュリティグループ | 事前に作成したセキュリティグループ |
キーペア | キーペアなしで続行 |
ユーザデータでは次のように入力します。ECS エージェント起動時に ECS クラスタ(gpu-test-cluster
)のコンテナインスタンスとして登録されるようになります。
#!/bin/bash echo "ECS_CLUSTER=gpu-test-cluster" >> /etc/ecs/ecs.config
起動後、ECS クラスタの詳細の[ECS インスタンス]タブから EC2 インスタンスが表示されていることを確認します。
もし、表示されていない場合は、コンテナインスタンスにセッションマネージャでログインし、ECS エージェントのログ(/var/log/ecs/ecs-agent.log
)を見て原因を調査してください。
Amazon ECS ログファイルの場所 - Amazon Elastic Container Service
ECS タスクの実行
作成した ECS クラスタ(gpu-test-cluster
)からタスク実行します。
先ほど作成した gpu-test-cluster の詳細画面に行き、[タスク]タブを選択し[新しいタスクの実行]をクリックします。
タスクの実行画面で次のように入力します。
項目名 | 値 |
---|---|
起動タイプ | EC2 |
タスク定義 | gpu-test:1 |
クラスター | gpu-test-cluster |
タスクの数 | 1 |
タスクグループ | gpu-test-group |
クラスター VPC | 事前に作成した VPC |
サブネット | 事前に作成したサブネット |
セキュリティグループ | 事前に作成したセキュリティグループ |
パブリック IP の自動割り当て | DISABLED |
配置テンプレート | AZ バランススプレッド |
その他はデフォルトのまま[タスクの実行]をクリックします。
タスクのステータスが STOPPED (Essential container in task exited)
になっていることを確認します(今回はコマンド実行だけなので、終了したらタスクも停止します)。
CloudWatch Logs のコンソールにいき、ロググループ /ecs/gpu-test
をクリック、ログストリームをクリックすると、nvidia-smi
コマンドの実行結果が表示されていることが確認できます。
後片付け
ずっと残しておくと料金がかかりつづけるため、以下のリソースを削除します。ECS や VPC ネットワーク、IAM ロールは料金がかからないので残しても良いです。
- VPC エンドポイント(Privatelink)
- NAT Gateway
- EIP(NAT Gateway を作成したときにアタッチしたもの)
- EC2 インスタンス
- CloudWatch Logs
まとめ
ECS GPU に最適化された AMI で ECS クラスタおよびタスク定義を作成し、ECS タスクを実行してみました。コンテナ定義で GPU を設定すること以外は通常の ECS クラスタを作成するのとあまり変わりはありません。GPU を使う機会がある人は ECS で試されると良いかと思います。
参考文献
- Amazon ECS での GPU の使用 - Amazon Elastic Container Service
- Amazon ECS 最適化 AMI バージョン - Amazon Elastic Container Service
- Amazon ECS ログファイルの場所 - Amazon Elastic Container Service
*1:私の場合なのでタイミングよっては対応速度は変わると思います