[祝GA!] ECS Anywhere を「M1 Mac」の仮想マシンを使って動かしてみた

お気軽お手軽デスクトップ環境で「ECS Anywhere」をサクッと試してみました。
2021.06.08

みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。

昨年の re:Invent 2020 で、Amazon ECS (Elastic Container Service) のワークロードをオンプレミスのサーバー (物理・仮想) 上で実行できる「Amazon ECS Anywhere」が発表されました。

この「ECS Anywhere」が先日GA (一般供用開始) となりましたので、試してみました。

Amazon Elastic Container Service Anywhere is now generally available

ECS Anywhere の仕組み

ECS Anywhere では、コンテナインスタンスとなるオンプレミスのサーバーを「Externalインスタンス」と呼んで管理します。

AWS外部のサーバーを管理するために、Systems Manager (SSM) の「マネージドインスタンス」の仕組みを利用しています。

SSMマネージドインスタンスの仕組みを使っているため、オンプレミスサーバーとAWSの間の通信要件としては「サーバーからAWS (SSMサービスエンドポイント) へHTTPS通信できること」のみです。 Direct ConnectやSite-to-Site VPNは不要ですし (もちろんあっても構いません)、サーバーへのインバウンド通信すら不要です。

SSMマネージドインスタンスとして登録した後は、ECSのコンテナインスタンスとして動作させるために「Docker」「ECSエージェント」のインストールを行います。(ECSエージェントはDocker上のコンテナとして動作します)

試してみた

仕組みが分かったところで、さっそく試してみます。

と言っても、「オンプレミスのサーバー」を用意するのはハードルが高いですよね・・・ (以前は、自宅にHPや富士通の安価なサーバーを購入して遊んでいたんですけどね。クラスメソッドでAWSに係わる仕事をするようになって、物理なサーバーは物置にしまってしまいましたw)

でも、前述の「仕組み」(通信要件) を見ると、PCの仮想マシンでも動かせそうな気がします。 ということで、MacBookの仮想化ソフトウェア「Parallels」を使ってチャレンジしてみました。

仮想マシンでUbuntu Linuxを起動する

今回は「M1プロセッサ (Apple Silicon)」搭載のMacを使用したため、Parallelsを起動すると以下のような画面になりました。

M1プロセッサ搭載Macでは、x86アーキテクチャの仮想マシンは動作せず、ARMアーキテクチャの仮想マシンのみ動作可能ということです。 ただ、ECS Anywhereでは「x86_64」「ARM64」いずれのアーキテクチャのサーバーもサポートしていますので、大丈夫そうです。

次に、インストール対象OSの選択画面になりました。

ECS Anywhereでは以下のOSがサポートされています。

  • CentOS 7/8
  • RHEL 7
  • Fedora 32/33
  • openSUSE Tumbleweed
  • Ubuntu 18/20
  • Debian 9/10
  • SUSE Enterprise Server 15

今回は「Ubuntu Linux」を選択してみました。

OSインストール済みイメージからの起動のため、すぐにUbuntuが起動しました。

よく見ると、インストールされたのは「Ubuntu Desktop」だったようです。 本来は「Ubuntu Server」を使うべきかと思いますが、最近のUbuntuはDesktopとServerでわりかしコンポーネントが共通であると聞くので、このまま進めましょう。

ECSクラスターを作成する

AWSマネジメントコンソールに移って、ECS側の準備を進めていきます。

まずは、ECSクラスターを作成します。

ECS Anywhereを利用する場合は、クラスターテンプレートの選択で「ネットワーキングのみ」を選択します。

設定するのは「クラスター名」のみです。 ECS AnywhereではVPCを使わないため「VPC」にはチェックを入れません。

Externalインスタンスの登録準備 (アクティベーションコードの払い出し)

ここからは、用意したオンプレミスサーバー (に見立てたParallels仮想マシン) をECSの「Externalインスタンス」として登録していきます。

Externalインスタンスの登録の流れは以下の通りです。

  1. Externalインスタンスの「アクティベーションキー」を払い出し、アクティベーションキーが埋め込まれたコマンドラインを入手する。
  2. オンプレミスサーバー上で「1」のコマンドラインを実行し、自身のサーバーをExternalインスタンスとしてECSへ登録する。

まず、「1」を行います。

作成したECSクラスターの画面で「ECSインスタンス」タブを選択します。

「Externalインスタンスの登録」ボタンをクリックします。

「Externalインスタンスの登録」画面が表示されます。

「アクティベーションキーの有効期限(日数)」と「インスタンス数」は、それぞれデフォルトの「1」のままにしておきます。

「インスタンスロール」は、Externalインスタンスに割り当てるIAMロールです。 初めてECS Anywhereを利用する場合 (Externalインスタンス用のインスタンスロールが作成されていない場合) は、AWSマネジメントコンソールが自動的に作成してくれますので、このまま続けます。

オンプレミスサーバー上で実行するコマンドラインが表示されます。 このコマンドラインにアクティベーションキー (「activation id」と「activation code」の組) が埋め込まれています。 画面をこのまま開いたままにするか、コマンドラインをテキストファイル等にコピーしておきます。

Externalインスタンスの登録 (オンプレミスサーバー上で登録コマンドを実行)

Parallels仮想マシンの画面に戻って、ターミナルを起動します。

ここで、前の手順で表示された「Externalインスタンス登録用のコマンドライン」を実行する訳ですが、コマンドはroot権限で実行する必要があるため、そのままコピーペーストするのではなく、少し手を加える必要があります。

AWSマネジメントコンソールに表示されたコマンドラインは、AWSが用意したスクリプトをダウンロードする「curlコマンド」と、ダウンロードしたスクリプトを実行する「bash ecs-anywhere-install.sh」コマンドを「&&」で連結したものになっています。

これを「curlコマンド」と「bash ecs-anywhere-install.sh」に分けて実行し、かつ、後者のbashコマンドには「sudo」を付けて実行します。

$ curl --proto "https" -o "/tmp/ecs-anywhere-install.sh" "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh"
$ sudo bash /tmp/ecs-anywhere-install.sh --region "ap-northeast-1" --cluster "ecs-anywhere-test" --activation-id "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" --activation-code "XXXXXXXXXXXXXXXXXXXX"

※ なお、今回使用したUbuntu Desktop環境ではcurlコマンドが標準でインストールされていなかったため、事前にsudo apt install -y curlを実行してインストールしています。

スクリプトを実行すると、どうやら以下の処理を順次行っているようです。

  • APTリポジトリのアップデート
  • SSMエージェントのインストール
  • SSMエージェントをSystems Managerへ登録
  • Dockerのインストール
  • ECSエージェントのインストール (Dockerコンテナとしてインストール)
  • ECSエージェントの起動

以下のメッセージが表示されれば、インストール処理は正常に完了しています。

##########################
This script installed three open source packages that all use Apache License 2.0.
You can view their license information here:
  - ECS Agent https://github.com/aws/amazon-ecs-agent/blob/master/LICENSE
  - SSM Agent https://github.com/aws/amazon-ssm-agent/blob/master/LICENSE
  - Docker engine https://github.com/moby/moby/blob/master/LICENSE
##########################

Externalインスタンスが登録されたことの確認

AWSマネジメントコンソールに戻って、ECSクラスター画面の「ECSインスタンス」タブを表示します。

オンプレミスサーバー (に見立てたParallels仮想マシン) がECSインスタンス一覧に表示されています!

「Externalインスタンス」欄が「true」になっていることに注目してください。 また、インスタンスのIDが「mi-」で始まっており、Systems Managerにおける「ハイブリッド環境」のマネージドインスタンスとして登録されていることも確認できます。

Systems Managerのマネジメントコンソールから「ノード管理」-「ハイブリッドアクティベーション」を選択すると、Systems Manager上で管理されているインスタンスとして表示されています。

ECSサービスを実行してみる

それでは、Externalインスタンスとして登録されたオンプレミスサーバー (に見立てたParallels仮想マシン) の上で、ECSサービスを実行してみましょう。

まずは、タスク定義を作成します。

「互換性」の選択は「EXTERNAL」を指定します。

Externalインスタンスでは「ネットワークモード」で選択可能な項目が「bridge」「host」「none」のみとなっています。「awsvpc」は選択することができません。(オンプレミスですからVPCネットワークにアタッチできないのは当然と言えば当然ですが)

ここでは「<default>」=「bridge」を選択します。

続いて、コンテナの設定を行います。

今回は必須項目のみ設定していきます。 コンテナイメージはDocker Hub公式リポジトリからnginxを指定します。 ポートマッピングの設定は必須ではありませんが、後ほど動作確認を行うために「80:80 TCP」を設定しておきます。

その他の項目はデフォルトのままにして、タスク定義を作成します。

次に、ECSサービスを作成します。

「起動タイプ」は「EXTERNAL」を選択して、さきほど作成したタスク定義を指定します。

「ネットワーク構成」「Auto Scaling」は、EXTERNAL起動タイプでは設定することができません。

ECSサービスを作成したら、正常に起動することを確認します。

起動タイプ「EXTERNAL」としてECSサービスが起動しました!

ECSサービスにアクセスしてみる

最後に、起動したECSサービスへアクセスしてみましょう。

ECSサービスとして起動したとは言え、ロードバランサーの設定を行っていないため、コンテナのポートに直接アクセスするしか手段がありません。

(※ EXTERNAL起動タイプでは「ネットワーク構成」の設定を行えない=ロードバランサーを使用することができません)

今回、Parallels仮想マシンのネットワークモードをデフォルトの「共有ネットワーク」にしていますので、仮想マシンのIPアドレスが分かればmacOS側からアクセスすることができます。

仮想マシン上でIPアドレスを確認します。

$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:1c:42:f3:f6:4b brd ff:ff:ff:ff:ff:ff
    inet 10.211.55.3/24 brd 10.211.55.255 scope global dynamic eth0

「10.211.55.3」だということが分かりましたので、macOS上のWebブラウザで、このIPアドレスにアクセスしてみます。

nginxコンテナへアクセスできました!

おわりに

ECS Anywhereが発表された時は「面白そう!だけど、実際に試す機会はそうそう無いかもかぁ~」と思っていましたが、仕組みを知るとデスクトップ仮想化環境でも試せることが分かりました。

今回はM1プロセッサ搭載Macで試しましたが、同様の手順でIntelプロセッサ搭載Macや、WindowsのHyper-V等でも動作させることができるのではないかと思います。

もちろん、デスクトップ仮想化環境でECS Anywhereを動かすことは実用的ではありませんが、今後オンプレミスサーバー、オンプレミスデータセンターへECS Anywhereを導入する予定があるという方は、イメージを掴むためにデスクトップ環境で試してみるのもよいのではないでしょうか。