Azure Metadata Service: Linux VM の Scheduled Events

適用対象: ✔️ Linux VM ✔️ フレキシブルなスケール セット ✔️ 均一のスケール セット

スケジュールされたイベントとは、仮想マシン (VM) のメンテナンスに備えるための時間をアプリケーションに与える Azure Metadata Service です。 今後のメンテナンス イベント (再起動など) に関する情報を提供することで、アプリケーションがイベントの準備を行い、中断を制限できるようにします。 このサービスは、Windows および Linux の、PaaS と IaaS を含むすべての Azure Virtual Machine の種類で利用できます。

Windows のスケジュールされたイベントの詳細については、Windows VM のスケジュールされたイベントに関する記事をご覧ください。

注意

スケジュールされたイベントは、すべての Azure リージョンで一般公開されています。 最新リリースについては、「利用可能なバージョンとリージョン」をご覧ください。

スケジュールされたイベントを使用する理由

多くのアプリケーションに、VM のメンテナンスに備える時間が得られるメリットがあります。 この時間を使用して、可用性、信頼性、およびサービスを向上させる、次のようなアプリケーション固有のタスクを実行できます。

  • チェックポイントと復元
  • 接続のドレイン
  • プライマリ レプリカのフェールオーバー
  • ロード バランサー プールからの削除
  • イベント ログ
  • グレースフル シャットダウン

スケジュールされたイベントを使用すると、アプリケーションはメンテナンスが行われる時期を検出し、その影響を制限するタスクをトリガーできます。

スケジュールされたイベントは、次のユース ケースでイベントを提供します。

基本操作

Metadata Service では、VM 内部からアクセスできる REST エンドポイントを使用した VM の実行に関する情報が公開されます。 情報は、VM の外部に公開されないように、ルーティング不可能な IP 経由で提供されます。

Scope

スケジュールされたイベントの配信先は次のとおりです。

  • スタンドアロンの仮想マシン。
  • クラウド サービス内のすべての VM。
  • 可用性セット内のすべての VM。
  • 可用性ゾーン内のすべての VM。
  • スケール セットの配置グループすべての VM。

注意

可用性ゾーンの VM に固有ですが、スケジュール化されたイベントはゾーン内のシングル VM に進みます。 たとえば、ある可用性セット内に 100 の VM があるとき、そのうちの 1 つが更新されるなら、スケジュール化されたイベントは 100 すべてに進みます。一方で、あるゾーン内に 100 のシングル VM がある場合、イベントは、影響を受ける VM にのみ進みます。

そのため、イベント内の Resources フィールドをチェックして、影響を受ける VM を特定する必要があります。

エンドポイントの検出

VNET が有効な VM の場合は、静的でルーティング不可能な IP アドレス 169.254.169.254 から Metadata Service を利用できます。 スケジュールされたイベントの最新バージョンのフル エンドポイントは次のとおりです。

http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01

VM が仮想ネットワーク内で作成されていない場合 (クラウド サービスと従来の VM の既定のケース)、使用する IP アドレスを検出する追加のロジックが必要となります。 ホスト エンドポイントの検出方法の詳細については、このサンプルを参照してください。

利用可能なバージョンとリージョン

スケジュールされたイベントのサービスは、バージョンによって管理されています。 バージョンは必須で、現在のバージョンは 2020-07-01 です。

Version リリースの種類 リージョン リリース ノート
2020-07-01 一般公開 All
  • イベントの期間のサポートを追加しました
  • 2019-08-01 一般公開 All
  • イベント ソースのサポートを追加しました
  • 2019-04-01 一般公開 All
  • イベントの説明のサポートを追加しました
  • 2019-01-01 一般公開 All
  • 仮想マシン スケール セットの EventType "Terminate" のサポートが追加されました
  • 2017-11-01 一般公開 All
  • スポット VM 削除の EventType 「Preempt」のサポートを追加する
  • 2017-08-01 一般公開 All
  • IaaS VM のリソース名から先頭のアンダースコアを削除
  • すべての要求にメタデータ ヘッダー要件を適用
  • 2017-03-01 プレビュー All
  • 最初のリリース
  • 注意

    スケジュールされたイベントの前のプレビュー リリースでは、api-version として {latest} がサポートされていました。 この形式はサポートされなくなり、今後非推奨となる予定です。

    スケジュールされたイベントの有効化と無効化

    スケジュールされたイベントは、ユーザーが初めてイベントを要求したときに、サービスに対して有効になります。 最初の呼び出しでは、最大 2 分の応答遅延が発生すると予想されます。

    スケジュールされたイベントは、サービスが 24 時間要求を行わないと、サービスに対して無効になります。

    ユーザー開始メンテナンス

    ユーザーが Azure Portal、API、CLI または PowerShell を使用して開始した VM のメンテナンスによって、スケジュールされたイベントが発生します。 これによって、アプリケーションでメンテナンス準備ロジックをテストすることができ、アプリケーションでは、ユーザーが開始したメンテナンスの準備をすることができます。

    VM を再起動すると、型 Reboot のイベントがスケジュールされます。 VM を再デプロイすると、型 Redeploy のイベントがスケジュールされています。

    API の使用

    ヘッダー

    メタデータ サービスのクエリを実行するときには、要求が意図せずリダイレクトされないように、ヘッダー Metadata:true を指定する必要があります。 Metadata:true ヘッダーは、スケジュールされたイベントのすべての要求で必要です。 要求にヘッダーを含めないと、メタデータ サービスから Bad Request (無効な要求) という応答があります。

    イベントのクエリ

    次の呼び出しを行うと、スケジュールされたイベントのクエリを実行できます。

    Bash

    curl -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    応答には、スケジュールされたイベントの配列が含まれています。 空の配列は、現在スケジュールされているイベントがないことを意味します。 スケジュールされたイベントがある場合は、応答にイベントの配列が含まれます。

    {
        "DocumentIncarnation": {IncarnationID},
        "Events": [
            {
                "EventId": {eventID},
                "EventType": "Reboot" | "Redeploy" | "Freeze" | "Preempt" | "Terminate",
                "ResourceType": "VirtualMachine",
                "Resources": [{resourceName}],
                "EventStatus": "Scheduled" | "Started",
                "NotBefore": {timeInUTC},       
                "Description": {eventDescription},
                "EventSource" : "Platform" | "User",
                "DurationInSeconds" : {timeInSeconds},
            }
        ]
    }
    

    イベントのプロパティ

    プロパティ 説明
    EventId このイベントのグローバル一意識別子。

    例:
    • 602d9444-d2cd-49c7-8624-8643e7171297
    EventType このイベントによって発生する影響。

    値:
    • Freeze:仮想マシンは数秒間の一時停止がスケジュールされています。 CPU とネットワーク接続が中断する場合がありますが、メモリや開いているファイルへの影響はありません。
    • Reboot:Virtual Machine は再起動がスケジュールされています (非永続メモリは失われます)。
    • Redeploy:Virtual Machine は別のノードへの移動がスケジュールされています (一時ディスクは失われます)。
    • Preempt:スポット仮想マシンが削除されています(一時ディスクは失われています)。
    • Terminate:仮想マシンは削除がスケジュールされています。
    ResourceType このイベントが影響を与えるリソースの種類。

    値:
    • VirtualMachine
    リソース このイベントが影響を与えるリソースの一覧。 これには最大 1 つの更新ドメインのマシンが含まれることが保証されますが、更新ドメインの一部のマシンは含まれない場合があります。

    例:
    • ["FrontEnd_IN_0", "BackEnd_IN_0"]
    EventStatus このイベントの状態。

    値:
    • Scheduled:このイベントは、NotBefore プロパティに指定された時間が経過した後で開始するようにスケジュールされています。
    • Started:このイベントは開始されています。
    Completed や類似の状態が提供されることはありません。 イベントが完了すると、イベントは返されなくなります。
    NotBefore このイベントが開始される時間。

    例:
    • Mon, 19 Sep 2016 18:29:47 GMT
    説明 このイベントの説明。

    例:
    • ホスト サーバーのメンテナンス中です。
    EventSource イベントのイニシエーター。

    例:
    • Platform:このイベントは、プラットフォームによって開始されています。
    • User:このイベントは、ユーザーによって開始されています。
    DurationInSeconds イベントによって発生する中断の予想される期間。

    例:
    • 9: イベントによって発生する中断は 9 秒間続きます。
    • -1: 影響期間が不明な場合または適用されない場合に使用される既定値。

    イベントのスケジューリング

    各イベントは、スケジュールされているイベントの種類に基づいて、将来の最小値の時間でスケジュールされます。 この時間は、イベントの NotBefore プロパティに反映されます。

    EventType 最小値の通知
    Freeze 約 15 分
    再起動 約 15 分
    Redeploy 10 分
    Preempt 30 秒
    Terminate ユーザーが構成可能:5 から 15 分

    注意

    Azure では、劣化したハードウェアに起因するホストの故障を予測が可能になり、移行をスケジュールすることでサービスの中断を軽減しようとすることがあります。 影響を受ける仮想マシンには、スケジュールされているイベントと NotBefore が届きます。これは通常、2、3 日先になります。 実際の時間は、予測された故障のリスク評価によって異なります。 Azure では、可能であれば、7 日前に通知を行いますが、実際の時間はさまざまであり、ハードウェアが今にも故障する可能性が高い場合、7 日より短くなることがあります。 システムによって開始される移行の前にハードウェアで障害が発生した場合に備えて、サービスのリスクを最小限に抑えるために、できるだけ早く仮想マシンをご自身で再デプロイすることをお勧めします。

    ポーリング頻度

    更新のエンドポイントは、任意の頻度でポーリングできます。 ただし、要求間の間隔が長くなるほど、発生するイベントに対応するのが遅くなる可能性があります。 ほとんどのイベントは、5 - 15 分前に通知されますが、場合によっては、通知がわずか 30 秒前ということもあります。 対策を講じるための時間をできるだけ多く確保するために、1 秒に 1 回サービスをポーリングすることをお勧めします。

    イベントの開始

    今後予定されているイベントを確認し、グレースフル シャットダウンのロジックを完了すると、EventId を使用してメタデータ サービスに POST 呼び出しを行うことにより、未処理のイベントを承認できます。 この呼び出しは、通知の最小時間を短縮できる (可能な場合) ことが Azure に示されます。

    次に示すのは、POST 要求本文で求められている JSON のサンプルです。 要求には、StartRequests の一覧を含める必要があります。 各 StartRequest には、迅速に進める必要があるイベントの EventId が含まれます。

    {
        "StartRequests" : [
            {
                "EventId": {EventId}
            }
        ]
    }
    

    Bash のサンプル

    curl -H Metadata:true -X POST -d '{"StartRequests": [{"EventId": "f020ba2e-3bc0-4c40-a10b-86575a9eabd5"}]}' http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    注意

    イベントの受信確認により、イベントを受信確認した VM だけでなく、イベント内のすべての Resources でイベントが続行されます。 そのため、受信確認を調整するリーダーを選択できます。これは、Resources フィールド内の最初のマシンと同様に簡単です。

    Python のサンプル

    次のサンプルでは、スケジュールされたイベントのメタデータ サービスにクエリを実行し、未処理の各イベントを承認しています。

    #!/usr/bin/python
    
    import json
    import socket
    import urllib2
    
    metadata_url = "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01"
    this_host = socket.gethostname()
    
    
    def get_scheduled_events():
        req = urllib2.Request(metadata_url)
        req.add_header('Metadata', 'true')
        resp = urllib2.urlopen(req)
        data = json.loads(resp.read())
        return data
    
    
    def handle_scheduled_events(data):
        for evt in data['Events']:
            eventid = evt['EventId']
            status = evt['EventStatus']
            resources = evt['Resources']
            eventtype = evt['EventType']
            resourcetype = evt['ResourceType']
            notbefore = evt['NotBefore'].replace(" ", "_")
        description = evt['Description']
        eventSource = evt['EventSource']
            if this_host in resources:
                print("+ Scheduled Event. This host " + this_host +
                    " is scheduled for " + eventtype + 
            " by " + eventSource + 
            " with description " + description +
            " not before " + notbefore)
                # Add logic for handling events here
    
    
    def main():
        data = get_scheduled_events()
        handle_scheduled_events(data)
    
    
    if __name__ == '__main__':
        main()
    

    次のステップ