web-dev-qa-db-ja.com

ネットワークリクエストからAWSEC2インスタンスを自動的に開始します(wake-on-LAN)

EC2インスタンスをオンデマンドで開始し、一定期間アイドル状態になったときに停止したいのですが(たとえば、1時間以上ネットワークアクティビティがない場合)、標準的な方法がわかりません。 AWSがwake-on-LANをサポートしていないことを考えると、AWSでこれを行うことは次のようになります。

実行する予定のサービスには、永続的なネットワーク接続が必要です。 ssh。

私が目指しているユーザーエクスペリエンスは次のようになります。

  • ユーザーが接続しようとしたときにサービスが起動している場合、ユーザーはサービスにすぐにアクセスできます。
  • ユーザーが接続しようとしたときにサービスがダウンしている場合、ユーザーは「サービスを開始しています」という応答を受け取ります(そして接続は閉じられます)。ユーザーは数分後に再試行し、正常に接続します(または、再試行が早すぎる場合は、「開始」メッセージを再度受信します)。最後のユーザーが切断した後、サービスは最大1時間稼働し続けます。

ここでの私の動機は、主にコスト削減です。需要は非常に予測不可能であり(したがって、スケジュールされたインスタンスは適切ではありません)、おそらく1日あたりのアクティブ時間は12時間未満であり、ユーザーはサービスが開始されるまで数分待つことをいとわないでしょう。また、リザーブドインスタンスの価格設定で1年以上の期間に縛られたくありません。

私はまた、これをどのように達成するかについていくつかの野蛮な刺し傷を持っています、そしてそれらがどれほどもっともらしい/賢明であるかについてのフィードバックをいただければ幸いです:

  1. サービスを0から最大1インスタンスまで「スケーリング」する自動スケーリンググループを使用します。しかし、実行中のインスタンスがない場合に「サービスを開始しています」という応答を発行する方法がわかりません。
  2. 接続の試行をキャッチすることを唯一の目的とするサービスがダウンしているときにt2.microインスタンスを実行し、「開始」応答を発行し、実際のサービスインスタンスの開始をトリガーしてから終了します。非アクティブのためにサービスインスタンスがダウンした場合、t2.microインスタンスを再起動する必要があります。

ありがとう!

3
koschei

Lambdaはこのように機能しますが、代わりにアプリを起動するまでユーザーを待機させます。 Lambdaでは、管理するインスタンスはありませんが、すべて内部で実行されます。

また、LambdaとRoute53フェイルオーバーチェックを含む何かを実行できるかどうかを確認します。たとえば、インスタンスがダウンしている場合はユーザーがLambdaをヒットし、アップしている場合はインスタンスをヒットします。ただし、これはLambdaでは機能しない可能性があります。特定のホストヘッダーが必要です。

または、R53フェイルオーバーを再度使用して、予約済みインスタンスt2.nanoを実行して「待合室」を実行し、起動したら別のインスタンスにプロキシまたはリダイレクトします。

3
Jason Martin

他のサービスを使用せずに、次のようなことを行うことができます。

import boto3
import json

def lambda_handler(event, context):

    ec2 = boto3.resource('ec2')
    instance = ec2.Instance(event['instance_id'])

    if instance.state['Code'] == 16:
        # Instance is running, do what you want
    Elif instance.state['Code'] == 80:
        # Instance is stopped, start it
        instance.start()
        return { 'status': 'instance-unavailable' }
    else
        # Instance is in another state

この場合、instance_idはパラメーターによって受信されますが、もちろん、ハードコーディングすることもできます。

1
fsinisi90