Azure Container Service の Windows Server Containers 対応が全然アクティブにならないので、先に EC2 Container Service で Windows Server Containers を体験することにします。
EC2 Container Service の Windows 対応は去年にベータがリリースされています。
Windows Containers (Beta) - Amazon EC2 Container Service
Getting Started with Windows Containers - Amazon EC2 Container Service
ドキュメントが用意されているので、この通りに進めていくと簡単に作れます。CloudFormation テンプレートが用意されているので、こっちを使うと一気に作れると思いますが、まずは手動で作ってみます。
クラスターを作成する
Windows 用に空のクラスターを作成します。チェックボックスを入れると作れるようになってます。
これで作成を選ぶと一瞬でクラスターが完成します。
当然ですが中身は空っぽです。Auto Scaling か EC2 インスタンスを作って追加しろとあります。
ECS インスタンスを追加しないと始まらないので、EC2 を使って作成します。
ECS インスタンスを作成する
使用する AMI は Windows Server 2016 Base with Containers です。Windows Server Containers のインストールと必要な設定が行われている AMI になります。
インスタンスサイズは m4.large を使いました。ECS のデフォルトが m4.large だったので、特に深い意味はありません。それなりのインスタンスを使わないと後で苦労します。
パブリック IP は RDP で簡単に接続したいので付けておきます。
IAM ロールは手動で作成する必要がありますが、AmazonEC2ContainerServiceforEC2Role ポリシーをアタッチするだけなので、簡単に作れると思います。
一番重要なのがユーザーデータの設定です。ドキュメントに記載されているスクリプトを貼り付けます。
EC2_CLUSTER という環境変数の値を、作成したクラスターの名前に書き換えておきます。
ストレージはデフォルトだと 30GB ぐらいですが、Windows Server の Docker Image はサイズが 9GB ぐらいあるので、増やしておかないと一瞬で埋まってしまいます。
ドキュメントには 200GB ぐらいとあったので、その通りにしておきました。
あとはキーペアを指定したり、セキュリティグループで 80 番を開けてインスタンスを作成します。
インスタンスの準備が完了すると、ECS インスタンスに表示されるようになります。
これで ECS インスタンスの作成は完了しました。本番で使う場合は Auto Scaling でインスタンスを作成した方がいいと思います。まだベータですけど。
タスク定義を追加する
詳しい説明は他のドキュメントなどに任せたいですが、タスク定義には使用するイメージの情報などを追加します。この定義に従って ECS が実際にコンテナを立ち上げることになります。
ドキュメントに microsoft/iis イメージを使う簡単な定義が用意されているので、まずはそれを使います。
JSON をそのまま貼り付けるだけなので、タスク定義の作成は簡単に終わります。
サービスを作成してタスクを実行する
これも詳しい説明は他のドキュメントに任せたいですが、サービスを使ってタスクを実行します。サービスを使うとタスクを落としても自動で立ち上げ直してくれたり、ロードバランシングを行ったり出来ます。
タスク定義とサービス名、そしてタスクの数を入力するだけで最低限のサービスは作成できます。
サービスを作成すると、自動的にタスクが実行されます。初回は必要なイメージをダウンロードして展開しているので非常に時間がかかります。
Azure の Windows Server 2016 with Containers イメージは microsoft/windowsservercore が既にダウンロードされた状態での提供なので、AWS も同じようにしてくれると捗りそうです。
実際にコンテナが実行されると表示が変わります。初回は 15 分ぐらいかかりました。
この状態で EC2 に割り当てられている IP にアクセスすると、以下のようなページが表示されます。
これで EC2 Container Service 上で Windows Server Containers の動作確認が出来ました。当然ながらこれだけでは面白くないので、ASP.NET アプリケーションを実行してみます。
ASP.NET MVC アプリケーションを実行する
公式の microsoft/aspnet イメージを使って、以前と同じように ASP.NET MVC アプリケーションのイメージを作成して、Docker Hub にプッシュしておきます。
shibayan/aspnet-demo というイメージを作成したので、タスク定義の JSON を修正します。
{ "family": "aspnet-demo", "containerDefinitions": [ { "name": "aspnet_demo_app", "image": "shibayan/aspnet-demo", "cpu": 100, "portMappings": [ { "protocol": "tcp", "containerPort": 80, "hostPort": 80 } ], "memory": 500, "essential": true } ] }
イメージだけで完結しているので entryPoint や command は必要ありません。
一度サービスとタスクを停止してから、新しいタスク定義を使ってサービスを作成すると、初回は数分かかりますが ASP.NET アプリケーションが立ち上がりました。
EC2 Container Service を使っていても、中身はこれまでの Windows Server Containers なので拍子抜けするぐらいあっさりと動作します。
本来なら複数アプリケーションをデプロイしたり、ロードバランシングを試したり、ローリングアップデートを試したりとやりたいことは多いですが、最初の一歩ということでこのぐらいにしておきます。
ECS 側にも少し問題があったので時間がかかるかもしれません。
現時点での制約
Windows Server Containers の制約という気もしますが、ネットワークモードが動いていないみたいです。
実際に 2 つ目のタスクを動かそうとすると network bridge が見つからないと言われてエラーになります。
1 つ目に起動したタスクは NAT で動いているので、ネットワークモードに NAT が指定できるようになれば、ある程度解決する気がします。今は検証で弾かれてしまうのでどうしようもないです。
ECS インスタンスにはリモートデスクトップで接続できるので、実際に動いてる様子を確認できます。
ドキュメントは複雑に見えましたが、思ったより簡単に Windows Server Containers を EC2 Container Service で使うことが出来て満足しました。