Amazon Web Services ブログ

Lightsail コンテナ: クラウドでコンテナを実行する簡単な方法

私は通常、デベロッパーに対し AWS クラウドの概要を説明するときには、Amazon Lightsail について話した上で、デモンストレーションのために少し時間を費やします。このサービスは、AWS の使用を開始するために極めて有効です。ユーザーはほんの数分の内に、自分の仮想サーバー上でアプリケーションを実行させることができるからです。これまでに当社では、Amazon Lightsail に対する、コンテナベースのワークロードのデプロイを可能にしてきました。Amazon Lightsail が仮想サーバーに提供しているのと同じシンプルさとバンドル料金により、今後は、コンテナーイメージをクラウドにデプロイできます。

Amazon Lightsail は、費用対効果が高く、わかりやすい月ごとのプランにより、使いやすいクラウドサービスとなっています。このサービスでは、アプリケーションやウェブサイトのデプロイに必要なすべてが提供されています。シンプルなワークロードやウェブサイトのデプロイ、あるいは、AWS の使用を開始するのに理想的です。Lightsail のお客様の一般的な範囲としては、クラウドと AWS の迅速な導入を検討しているデベロッパーから小規模企業、あるいはスタートアップ企業までが含まれます。このサービスで AWS クラウドに習熟した後は、さらに広範な AWS のサービスをいつでも導入できます。

Lightsail の機能を背後から支えているのは、Amazon Elastic Compute Cloud (EC2)Amazon Relational Database Service (RDS)Application Load Balancer、およびその他の AWS のサービスです。この構成により、AWS に期待されるレベルのセキュリティ、信頼性、およびスケーラビリティを提供しています。

Lightsail にデプロイしようとするユーザーは、6 つのオペレーティングシステム(4 つの Linux ディストリビューション、FreeBSD、または Windows)、7 つのアプリケーション(WordPressDrupalJoomlaPlesk その他)、および 7 つのスタック(Node.jsLampGitLabDjango その他)から選択して使用することが可能です。とは言え、Docker コンテナについてはどうでしょうか?

今回、Amazon Lightsail において、デベロッパーがコンテナをクラウドに簡単にデプロイできる手法が、提供されるようになりました。ユーザーが用意する必要があるのは、コンテナの Docker イメージだけで、このイメージは、サービスにより自動的にコンテナー化されます。クラウドコンテナでアプリケーションを実行するための準備ができた、HTTPS エンドポイントが Amazon Lightsail により提供されます。負荷分散された TLS エンドポイントも自動的にセットアップされ、TLS 証明書への対応も行われます。このサービスにより、応答しないコンテナは自動的に置き換えられ、エンドポイントには DNS 名が割り当てられます。また、新しいバージョンが正常に稼動する準備が完了するまで、古いバージョンの管理が継続されるなど、多くの機能が提供されます。

ここでは、コンテナとしてシンプルな Python ウェブアプリケーションをデプロイして、このサービスの仕組みを見てみましょう。今回、お客様のノート PC には、AWS コマンドラインインターフェイス(CLI)Docker がインストールされていることを前提とします。Python は、コンテナにのみインストールされるので必須ではありません。

まず最初に、シンプルな Flask のアプリケーションフレームワークを使用して、Python REST APIを作成します。さらに、コンテナ内で実行できるプログラミング言語やフレームワークも用意します。ここでは、シンプルかつエレガントな Python と Flask だけを選びました。

次のコマンドをコピー & 貼り付けして、そのまま使用できます。

mkdir helloworld-python
cd helloworld-python
# create a simple Flask application in helloworld.py
echo "

from flask import Flask, request
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class Greeting (Resource):
   def get(self):
      return { "message" : "Hello Flask API World!" }
api.add_resource(Greeting, '/') # Route_1

if __name__ == '__main__':
   app.run('0.0.0.0','8080')

"  > helloworld.py

次に、コンテナイメージを構築するために必要な手順と情報を含む、Dockerfile を作成します。

# create a Dockerfile
echo '
FROM python:3
ADD helloworld.py /
RUN pip install flask
RUN pip install flask_restful
EXPOSE 8080
CMD [ "python", "./helloworld.py"]
 '  > Dockerfile

これで、次のようにコンテナを構築できます。

docker build -t lightsail-hello-world .

build コマンドは、コンテナの構築中に多くの行を出力しますが、最終的に次のメッセージで終了します(実際のIDは異なります)。

Successfully built 7848e055edff
Successfully tagged lightsail-hello-world:latest

次のように、ノート PC でこのコンテナを起動してテストします。

docker run -it --rm -p 8080:8080 lightsail-hello-world

さらに、ブラウザを localhost:8080 に接続します。

コンテナ内の Flask API のテスト

アプリの動作に問題がなければ、コンテナを Docker Hub にプッシュします。

docker tag lightsail-hello-world sebsto/lightsail-hello-world
docker login
docker push sebsto/lightsail-hello-world

これで、Docker Hub でコンテナの準備が整いました。Lightsail コンテナサービスを作成していきましょう。

ブラウザで、Amazon Lightsail コンソールを開きます。ここでは、コンテナサービスが既にデプロイされているのを確認でき、管理することができます。[Create container service(コンテナサービスの作成)] をクリックし、新しいサービスを作成します。Lightsail コンテナコンソール

次の画面で、アプリケーションが必要とする vCPU とメモリ容量に応じて、使用するコンテナのサイズを選択します。また、高可用性またはスケーラビリティを実現するために、並行して実行するコンテナインスタンスの数を選択します。コンテナインスタンスの数、あるいは性能(vCPU と RAM)は、サービスを中断することなく任意のタイミングで変更できます。これらのパラメータはどちらも、AWS からの月ごとの請求料金に影響します。次の動画に示すように、価格は画面上に表示されるので、動的に調整できます。

Lightsail でのキャパシティーの選択

ここでは、画面のやや下から、デプロイ画面へスキップします。サービスに名前(“hello-world“)を付けます。[Create container service] をクリックします。

Lightsail のコンテナ名

サービスが作成されたら、[Create your first deployment(最初のデプロイを作成)] をクリックして、デプロイを実行します。デプロイには、ここで作成したサービスに配置される、特定のコンテナーでのイメージとバージョンが組み合わされています。

user/<my container name>:tag の形式を使用して、使用するイメージの名前と、Docker Hub での画像のアドレスを指定します。これには、環境変数、ポートマッピング、または起動コマンドを入力する場合もあります。

今回のコンテナは、ポート TCP 8080 でネットワークサービスを提供しているので、そのポートもデプロイの設定に追加します。[Open Ports(オープンなポート)] の設定では、コンテナのネットワーク内にある他のシステムに対して開く、ポートとプロトコルを指定しています。他のコンテナや仮想マシンは、ポートをコンソールから明示的に定義するか、DockerfileEXPOSE が指定された場合にのみ、このコンテナに接続できます。これらのポートのいずれも、パブリックインターネットには公開されません。

ただし、今回の例では、Lightsail でパブリックインターネットからこのコンテナにトラフィックをルーティングできるようにしたいと考えています。そこで、このコンテナを、先ほど作成した hello-world サービスのエンドポイントとして追加します。エンドポイントは TLS 用に自動的に構成されるので、証明書のインストールや管理の必要はありません。

1つのデプロイで、最大 10 個のコンテナを追加できます。準備ができたら、[Save and deploy(保存してデプロイ)] をクリックします。

Lightsail のデプロイ

しばらくすると、デプロイがアクティブ状態になり、エンドポイントのテストが可能になります。

アクティブな Lightsail のデプロイ

エンドポイント DNS アドレスは、コンソールの右上で確認できます。必要であれば、独自の DNS ドメイン名を設定することも可能です。

Lightsail エンドポイントの DNSブラウザで別のタブを開き、エンドポイントの https URL を開きます。

コンテナのデプロイのテスト新しいバージョンをデプロイする必要がある場合は、コンソールを再度使用して、デプロイの設定を変更します。ここでは、アプリケーションコードの詳細な修正や、構築、そして新しいバージョンのコンテナのプッシュなどの作業は割愛します。仮に、sebsto/lightsail-hello-world:v2 という名前で、2 番目のバージョンのコンテナイメージが用意されているとします。Amazon Lightsail コンソールに戻り、[Deployments]、[Modify your Deployments(デプロイの変更)] の順にクリックします。新しいバージョンのコンテナーイメージの完全な名前(タグを含む)を入力し、[Save and Deploy] をクリックします。

Lightsail の更新バージョンのデプロイしばらくすると、新しいバージョンがデプロイされ、自動的にアクティブ化されます。

成功した Lightsail のデプロイ

ブラウザで新しいタブを開き、Amazon Lightsail コンソールの右上隅に表示されている、エンドポイント URI を開きます。JSON のバージョンが異なっていることが確認できます。ここでは、バージョン属性の値が、2 になっています。

デプロイされた Lightsail v2

デプロイ中に何か問題が発生した場合には、Amazon Lightsail が自動的に前のデプロイをアクティブに保つので、サービスの中断を回避できます。また、前のデプロイのバージョンを手動でアクティブ化して、望ましくない変更を元に戻すこともできます。

今回は、最初のコンテナイメージのみを、Docker Hub からデプロイしています。AWS コマンドラインインターフェイス(CLI)を使用すれば、ノート PC から、サービスの管理やローカルコンテナイメージのデプロイを実行できます。コンテナイメージを、ノート PC から直接、Amazon Lightsail コンテナサービスにプッシュするには、LightSail Controler プラグインをインストールする必要があります。(細かい話になりますが、ここでは curlcpchmod が、非常に役立ちます。また私は、コンテナ内で CLI を使用するために、DockerFile も保持しています。)

コンテナサービスを作成、一覧表示、または削除するには、次のように入力します。

aws lightsail create-container-service --service-name myservice --power nano --scale 1

aws lightsail get-container-services
{
   "containerServices": [{
      "containerServiceName": "myservice",
      "arn": "arn:aws:lightsail:us-west-2:012345678901:ContainerService/1b50c121-eac7-4ee2-9078-425b0665b3d7",
      "createdAt": "2020-07-31T09:36:48.226999998Z",
      "location": {
         "availabilityZone": "all",
         "regionName": "us-west-2"
      },
      "resourceType": "ContainerService",
      "power": "nano",
      "powerId": "",
      "state": "READY",
      "scale": 1,
      "privateDomainName": "",
      "isDisabled": false,
      "roleArn": ""
   }]
}

aws lightsail delete-container-service --service myservice

CLI を使用すれば、ノート PC から直接コンテナイメージをデプロイすることもできます。先に必ず、lightsailctlインストールしておきます。

# Build the new version of my image (v3)
docker build -t sebsto/lightsail-hello-world:v3 .

# Push the new image.
aws lightsail push-container-image --service-name hello-world --label hello-world --image sebsto/lightsail-hello-world:v3

しばらくすると、次のように出力が表示されます。

Image "sebsto/lightsail-hello-world:v3" registered.
Refer to this image as ":hello-world.hello-world.1" in deployments.

デプロイ設定の詳細を保持するために、lc.json というファイルを作成します。このファイルの内容は、コンソールに表示されるオプションと揃えておきます。前出のコマンドにより image プロパティに表示された名前を、次のように登録します。

{
  "serviceName": "hello-world",
  "containers": {
     "hello-world": {
        "image": ":hello-world.hello-world.1",
        "ports": {
           "8080": "HTTP"
        }
     }
  },
  "publicEndpoint": {
     "containerName": "hello-world",
     "containerPort": 8080
  }
}

最後に、新しいサービスバージョンを次のように作成します。
aws lightsail create-container-service-deployment --cli-input-json file://lc.json

デプロイのステータスは、次のようにクエリすることができます。
aws lightsail get-container-services

...
"nextDeployment": {
   "version": 4,
   "state": "ACTIVATING",
   "containers": {
      "hello-world": {
      "image": ":hello-world.hello-world.1",
      "command": [],
      "environment": {},
      "ports": {
         "8080": "HTTP"
      }
     }
},
...

しばらくすると、ステータスが  ACTIVE になり、エンドポイントをテストできます。

curl https://hello-world.nxxxxxxxxxxx.lightsail.ec2.aws.dev/
{"message": "Hello Flask API World!", "version": 3}

後に、Amazon ECS またはAmazon Elastic Kubernetes Service にコンテナをデプロイする場合にも、特に変更は必要ありません。Amazon Lightsail と同様の方法で、リポジトリからコンテナーイメージをプルできます。

Lightsail でのコンテナのデプロイは、Amazon Lightsail が利用可能なすべての AWS リージョンで行うことができます。本稿の執筆時点で利用可能なリージョンは以下の通りです。米国東部(オハイオ)米国東部(バージニア北部)米国西部(オレゴン)アジアパシフィック(ムンバイ)アジアパシフィック(ソウル)アジアパシフィック(シンガポール)アジアパシフィック(シドニー)アジアパシフィック(東京)カナダ(中部)欧州(フランクフルト)欧州(アイルランド)欧州(ロンドン)欧州(パリ)

他のサービスと同様に、Amazon Lightsailの使用にも、わかりやすく想定しやすい料金体系が設定されています。Amazon Lightsail コンテナには、コンテナのサイズ(使用している vCPU とメモリの組み合わせ)に応じて、コンテナ単位で月ごとの固定価格が適用されます。お客様が、サービスを稼働させるために割り当てた時間に対し、料金が請求されます。月あたりの料金は、24 時間 365 日のサービスを実行した場合に請求される、上限の価格です。この料金は、すべての AWS リージョンで同じです。料金の範囲は、Nano コンテナ(512 MB のメモリと 0.25 vCPU)の 7 USD/月から、X-Large コンテナ(8 GB のメモリと 4 つの vCPU コア)の 160 USD/月までとなっています。この価格には、コンテナ自体だけでなく、ロードバランサー、DNS、および豊富なデータ転送枠も含まれています。他の AWS リージョンでの詳細と料金については、Amazon Lightsail 料金表のページを参照してください。

皆様が、どのようなソリューションを構築し、Amazon Lightsail コンテナにデプロイしているかを見られる日が、非常に楽しみです。

— Seb