手元でECSが動く ECS Anywhereを試してみた


ECS AnywhereがGAされたということで試してみた。

https://aws.amazon.com/blogs/aws/getting-started-with-amazon-ecs-anywhere-now-generally-available/

ECS Anywhereとは

2020年のre:Inventで発表された、任意の環境(オンプレやデータセンタなど)でECSのタスクをデプロイできるもの。

2021年の前半にリリースされると聞いていて、発表時はけっこう盛り上った記憶があるが、 いざリリースされて数日、あまり話に聞かない気がする。

導入してみた

ローカルに仮想マシン(Ubuntu 20)を建てて、そこに導入してみた。

素のUbuntuを入れるだけで、特に追加のインストール物は無し。 唯一、curlが入ってなくてインストールコマンドのサンプルがcurlだったのでそれをインストールしたぐらい。

マネージメントコンソールでECSの画面にアクセスし、ECSインスタンスのタブを開いてみると、 Externalインスタンスの登録 というのが増えている。

これをクリックすると、アクティベーションキーの有効期間やインスタンス数、インスタンスロールを 選択する画面がでてきて、これを選ぶとインストール用のコマンドが表示されるようになっている。

インストールコマンドは、インストールスクリプトをダウンロードして実行する簡易なもの。 インストールスクリプトの中で、SSM agentやdockerなど必要なものは導入してくれる。

インストールが終わるとECS Agentが起動していることが確認できる。

# docker ps
CONTAINER ID   IMAGE                            COMMAND    CREATED         STATUS                   PORTS     NAMES
8ec251e819a2   amazon/amazon-ecs-agent:latest   "/agent"   3 minutes ago   Up 3 minutes (healthy)             ecs-agent

マネコンの方でも、インスタンスが登録されていることがわかる。

つまづいたポイント

インスタンスロールに、 AmazonSSMRoleForAutomationAssumeQuickSetup が出てきたので これでいいのかなと選んでしまったが、ECS周りのポリシーが不足しているのでインストールでこけた。 新しいロールを作成する、で作ってもらうか AmazonSSMManagedInstanceCore AmazonEC2ContainerServiceforEC2Role のポリシーがアタッチされたロールを作って設定するのが正解だったようだ。

/var/log/ecs/ecs-agent.logに以下のようなログが出るので問題がどこにあるかはすぐにわかる。

level=error time=2021-05-28T23:36:26Z msg=“Unable to register as a container instance with ECS: AccessDeniedException: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/AmazonSSMRoleForAutomationAssumeQuickSetup/mi-085ac36e8f491xxxx is not authorized to perform: ecs:RegisterContainerInstance on resource: arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:cluster/ecs-sandbox” module=client.go

サービスを起動する

サービス起動タイプに EXTERNAL というのが増えているので、 タスク定義の方も、 EXTERNAL 互換のTask Definitionを作成しておく必要がある。

当然だが、ECRのプライベートレジストリのコンテナイメージも利用することができた。

サービスの設定も基本的なところは変わらないが、注意点としてネットワークの設定やオートスケールの設定ができない。

ネットワークの設定ができないので、ELBから接続したり、ECSサービスディスカバリーでタスク間通信をすることはできないようだ。

単にコンテナIDを返してくれるテスト用のイメージを使って試してみたが、 サービスを作成すると、手元に作成したインスタンス側でコンテナが起動したことおよび動作が確認できた。

# docker ps
CONTAINER ID   IMAGE                                                        COMMAND                  CREATED          STATUS                    PORTS                                         NAMES
5a6dc5f7a402   123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/go-hello   "/bin/sh -c /bin/go-…"   29 seconds ago   Up 26 seconds             0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   ecs-go-hello-1-go-hello-e09cf6f5e6f3e895b901
a371576de001   123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/go-hello   "/bin/sh -c /bin/go-…"   29 seconds ago   Up 26 seconds             0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   ecs-go-hello-1-go-hello-d08094a6fb85aefc1400
8ec251e819a2   amazon/amazon-ecs-agent:latest                               "/agent"                 14 minutes ago   Up 14 minutes (healthy)                                                 ecs-agent
# curl localhost:49153
Hello, World! My name is 5a6dc5f7a402
# curl localhost:49154
Hello, World! My name is a371576de001

所感

想像以上に簡単にオンプレ側にコンテナインスタンスを作成することができた。

ただ、ロードバランサーが無いのでAWS側に用意したものと連携する手段が無いように見える。 AWS上以外で実行したいユースケースとしては、例えばコンプライアンス上の理由から、 DBをクラウドに持っていけずローカルに置くしか無い場合に、必要以上の情報がAWS側に流れるのを防ぐために APIゲートウェイ的に使うとか、そういったことが考えられると思うが、 AWS上のワークロードからの通信手段が無いと微妙と思った。

まあ、Direct ConnectやVPNで繋いでれば確保できるし、普通はそうやるのだろうけど。

あとはバッチ処理してS3に上げたいとかそういうことはできるのかな。

タスクへのインバウンド通信の手段が無いといろいろ不便な気がするので、 その辺は今後に期待なのかと思う。


関連記事