Служба метаданных Azure: подслужба "Запланированные события" для виртуальных машин Windows

Применимо к: ✔️ Виртуальные машины Windows ✔️ Гибкие масштабируемые наборы ✔️ Универсальные масштабируемые наборы

Запланированные события — это служба метаданных Azure, которая дает время вашему приложению для подготовки к обслуживанию виртуальной машины. Эта служба предоставляет сведения о предстоящем событии обслуживания (например, о перезагрузке), чтобы приложение могло подготовиться к ним и ограничить перебои в работе. Она доступна для всех типов виртуальных машин Azure, включая PaaS и IaaS (как для Windows, так и для Linux).

Сведения о запланированных событиях в Linux см. в статье Служба метаданных Azure. Запланированные события (предварительная версия) для виртуальных машин Linux.

Запланированные события предоставляют упреждающие уведомления о предстоящих событиях для реактивной информации о событиях, которые уже произошли, см . сведения о доступности виртуальных машин в Azure Resource Graph и правиле создания оповещений о доступности для виртуальной машины Azure.

Примечание.

Служба "Запланированные события" общедоступна во всех регионах Azure. В разделе Доступность версий в регионах вы найдете сведения о последних выпусках.

Почему необходимо использовать запланированные события?

Во многих приложениях время на подготовку к обслуживанию виртуальной машины может положительно повлиять на их работу. Его можно использовать для выполнения конкретных задач по повышению доступности, надежности и удобства обслуживания:

  • создание контрольных точек и восстановление;
  • фильтрация подключений;
  • отработка отказа первичной реплики;
  • удаление из пула подсистемы балансировки нагрузки;
  • ведение журнала событий;
  • нормальное завершение работы.

Используя запланированные события, приложение может учесть время, когда будет выполняться техническое обслуживание, и запустить задачи для ограничения его влияния.

Запланированные события предусматривают события в следующих случаях:

Основы

Служба метаданных предоставляет сведения о работающих виртуальных машинах с помощью конечной точки REST, которая доступна из виртуальной машины. Эта информация доступна через неизменяемый IP-адрес и не предоставляется за пределами виртуальной машины.

Область

Запланированные события доставляются и могут быть подтверждены следующими способами:

  • автономным виртуальным машинам;
  • Все виртуальные машины в облачной службе Azure (классическая модель).
  • всем виртуальным машинам в группе доступности;
  • всем виртуальным машинам в группе размещения масштабируемого набора.

Примечание.

Запланированные события для всех виртуальных машин (виртуальных машин) во всей группе доступности или группе размещения для масштабируемого набора виртуальных машин предоставляются всем остальным виртуальным машинам в одной группе или наборе независимо от использования зоны доступности.

Поэтому проверьте поле Resources в событии, чтобы определить, какие виртуальные машины затронуты.

Обнаружение конечной точки

Для виртуальных машин с поддержкой виртуальной сети служба метаданных доступна со статического немаршрутизируемого IP-адреса, 169.254.169.254. Полная конечная точка для последней версии службы "Запланированные события" выглядит так:

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

Если виртуальная машина не создана в виртуальная сеть, варианты по умолчанию для облачных служб и классических виртуальных машин требуют дополнительной логики для обнаружения ИСПОЛЬЗУЕМОго IP-адреса. Чтобы узнать, как выполнить обнаружение конечной точки узла, просмотрите этот пример.

Доступность версий и доступность в регионах

Служба запланированных событий имеет версии. Версии являются обязательными. Сейчас используется версия от 2020-07-01.

Версия Тип выпуска Регионы Заметки о выпуске
01.07.2020 Общая доступность Все
  • Добавлена поддержка длительности события.
  • 01.08.2019 Общая доступность Все
  • Включена поддержка EventSource.
  • 01.04.2019 Общая доступность Все
  • Включена поддержка описания события.
  • 2019-01-01 Общая доступность Все
  • Добавлена поддержка Масштабируемые наборы виртуальных машин EventType "Terminate"
  • 2017-11-01 Общая доступность Все
  • Добавлена поддержка типа события "Выгрузка" для исключения точечных виртуальных машин
  • 2017-08-01 Общая доступность Все
  • Удалено подчеркивание перед именами ресурсов для виртуальных машин IaaS.
  • Требование заголовка метаданных принудительно применяется для всех запросов.
  • 2017-03-01 "Предварительная версия" Все
  • Первый выпуск
  • Примечание.

    В предыдущих выпусках предварительной версии в качестве версии API поддерживалось значение {latest}. Этот формат больше не поддерживается и в дальнейшем будет считаться устаревшим.

    Включение и отключение Запланированных событий

    Служба "Запланированные события" включается для вашей службы, когда вы впервые запрашиваете события. При первом вызове возможна задержка ответа до двух минут. Запланированные события отключены для службы, если он не выполняет запрос к конечной точке в течение 24 часов.

    Обслуживание, инициированное пользователем

    Обслуживание виртуальных машин, инициированное пользователем на портале Azure, в API, Azure CLI или PowerShell, приведет к созданию запланированных событий. Затем можно протестировать логику подготовки обслуживания в вашем приложении, а также его можно подготовить к обслуживанию, инициированному пользователем.

    При перезагрузке виртуальной машины событие с типом Reboot добавляется в расписание. При повторном развертывании виртуальной машины событие с типом Redeploy добавляется в расписание. Как правило, события с источником событий пользователя можно немедленно утвердить, чтобы избежать задержки инициированных пользователем действий. Мы советуем взаимодействовать с первичной и вторичной виртуальной машиной и утверждать созданные пользователем запланированные события, если основная виртуальная машина не отвечает. Немедленное утверждение событий предотвращает задержки при восстановлении приложения обратно в хорошее состояние.

    Запланированные события для обновлений гостевой ОС VMSS или повторного просмотра поддерживаются для размеров виртуальных машин общего назначения, поддерживающих только сохранение обновлений в памяти. Оно не работает для серий G, M, N и H. Запланированные события для обновлений гостевой ОС VMSS и повторного создания образов отключены по умолчанию. Чтобы включить запланированные события для этих операций с поддерживаемыми размерами виртуальных машин, сначала включите их с помощью OSImageNotificationProfile.

    Использование API

    Общие сведения о высоком уровне

    Существует два основных компонента для обработки запланированных событий, подготовки и восстановления. Все текущие запланированные события, влияющие на виртуальную машину, доступны для чтения через конечную точку запланированных событий IMDS. Когда событие достигло состояния терминала, оно удаляется из списка событий. На следующей схеме показаны различные переходы состояния, которые могут выполняться одним запланированным событием:

    State diagram showing the various transitions a scheduled event can take.

    Для событий в состоянии EventStatus:"Scheduled" необходимо выполнить действия по подготовке рабочей нагрузки. После завершения подготовки необходимо утвердить событие с помощью API запланированных событий. В противном случае событие автоматически утверждается при достижении времени NotBefore. Если виртуальная машина находится в общей инфраструктуре, система будет ожидать, пока все остальные клиенты на одном оборудовании также утверждают задание или время ожидания. После сбора утверждений со всех затронутых виртуальных машин или времени NotBefore Azure создает новую полезные данные запланированного события с помощью EventStatus:"Started" и запускает начало события обслуживания. Когда событие достигло состояния терминала, оно удаляется из списка событий. Это служит сигналом для клиента для восстановления виртуальных машин.

    Ниже приведен код psudeo, демонстрирующий процесс чтения и управления запланированными событиями в приложении:

    current_list_of_scheduled_events = get_latest_from_se_endpoint()
    #prepare for new events
    for each event in current_list_of_scheduled_events:
      if event not in previous_list_of_scheduled_events:
        prepare_for_event(event)
    #recover from completed events
    for each event in previous_list_of_scheduled_events:
      if event not in current_list_of_scheduled_events:
        receover_from_event(event)
    #prepare for future jobs
    previous_list_of_scheduled_events = current_list_of_scheduled_events
    

    Так как запланированные события часто используются для приложений с высокими требованиями к доступности, существует несколько исключительных случаев, которые следует учитывать:

    1. После завершения запланированного события и удаления из массива никаких дополнительных последствий без нового события, включая другое событие EventStatus:"Scheduled"
    2. Azure Monitor выполняет операции обслуживания во всем флоте и в редких случаях определяет, что операция обслуживания слишком высока, чтобы применить. В этом случае запланированное событие переходит непосредственно из "Scheduled" для удаления из массива событий
    3. В случае сбоя оборудования Azure проходит состояние "Запланировано" и немедленно переходит в состояние EventStatus:"Started".
    4. Хотя событие по-прежнему находится в состоянии EventStatus:"Started", может оказаться еще одним воздействием меньшей длительности, чем то, что было объявлено в запланированном событии.

    В рамках гарантии доступности Azure виртуальные машины в разных доменах сбоя не будут влиять на обычные операции обслуживания одновременно. Однако они могут иметь сериализованные операции друг за другом. Виртуальные машины в одном домене сбоя могут получать запланированные события с помощью EventStatus:"Scheduled" вскоре после завершения обслуживания другого домена сбоя. Независимо от выбранной архитектуры всегда сохраняйте проверка для новых событий, ожидающих от виртуальных машин.

    Хотя точные сроки событий зависят, на следующей схеме представлено грубое руководство по тому, как выполняется обычная операция обслуживания:

    • EventStatus:"Scheduled" to Approval Timeout: 15 минут
    • Длительность воздействия: 7 секунд
    • EventStatus:"Started" to Completed (событие удалено из массива событий): 10 минут

    Diagram of a timeline showing the flow of a scheduled event.

    Заголовки

    При запросе службы метаданных необходимо указать заголовок Metadata:true, чтобы удостовериться, что он не был случайно перенаправлен. Заголовок Metadata:true является обязательным для всех запросов запланированных событий. Невозможность включить заголовок в запрос приведет к ответу службы метаданных "Ошибка запроса".

    Запрос сведений о событиях

    Чтобы получить сведения о запланированных событиях, выполните следующий вызов.

    Пример Bash

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

    Пример для PowerShell

    Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01" | ConvertTo-Json -Depth 64
    

    Пример для Python

    import json
    import requests
    
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    header = {'Metadata' : 'true'}
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    

    Ответ содержит массив запланированных событий. Пустой массив означает, что сейчас запланированных событий нет. Если передаются запланированные события, массив событий в ответе выглядит так:

    {
        "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},
            }
        ]
    }
    

    Свойства событий

    Свойство Description
    Document Incarnation Целое число, которое увеличивается при изменениях массива событий. Документы с одной инкарнацией содержат одинаковые сведения о событии, а при изменении события номер инкарнации будет увеличен.
    EventId Глобальный уникальный идентификатор этого события.

    Пример:
    • 602d9444-d2cd-49c7-8624-8643e7171297
    EventType Ожидаемое влияние этого события приведет к возникновению.

    Значения:
    • Freeze: виртуальная машина планируется приостановить в течение нескольких секунд. Подключение к ЦП и сети может быть приостановлено, но не влияет на память или открытые файлы.
    • Reboot. Планирование перезагрузки виртуальной машины (временная память будет потеряна). В редких случаях виртуальная машина, запланированная для EventType:"Перезагрузка", может столкнуться с событием замораживания вместо перезагрузки. Следуйте приведенным выше инструкциям, чтобы узнать, завершено ли событие и безопасно восстановить рабочую нагрузку.
    • Redeploy. Виртуальная машина будет перемещена на другой узел с потерей данных на временных дисках.
    • Preempt: удалена точечные виртуальные машины (временные диски теряются). Это событие становится доступным на основе лучших усилий
    • Terminate: виртуальная машина планируется удалить.
    ResourceType Тип ресурса, который затрагивает это событие.

    Значения:
    • VirtualMachine
    Ресурсы Список ресурсов, на которые влияет это событие.

    Пример:
    • ["FrontEnd_IN_0", "BackEnd_IN_0"]
    EventStatus Состояние этого события.

    Значения:
    • Scheduled. Это запланированное событие состоится по истечении времени, указанного в свойстве NotBefore.
    • Started. Это событие запущено.
    Состояние Completed (или аналогичное) никогда не предоставляется. После завершения событие не повторяется.
    NotBefore Время, после которого это событие может состояться. Это событие гарантированно не запустится до этого времени. Будет пустым, если событие уже запущено

    Пример:
    • Пн, 19 сентября 2016 г., 18:29:47 (GMT)
    Description Описание этого события.

    Пример:
    • На сервере узла выполняется обслуживание.
    EventSource Инициатор события.

    Пример:
    • Platform: это событие инициировано платформой.
    • User: это событие инициировано пользователем.
    DurationInSeconds Ожидаемая длительность прерывания, вызванного событием.

    Пример:
    • 9: прерывание, вызванное событием, продлится 9 секунд.
    • 0: событие не прерывает виртуальную машину или не влияет на ее доступность (например, обновление в сети)
    • -1: значение по умолчанию, используемое, если длительность воздействия неизвестна или неприменима.

    Планирование события

    В зависимости от типа каждое будущее событие будет выполняться минимальное количество времени. Это время отражается в свойстве события NotBefore.

    EventType Минимальное время уведомления
    Блокировка 15 минут
    Перезагрузка 15 минут
    Повторное развертывание 10 минут
    Увольнение Настраиваемый пользователь: 5–15 минут

    Это означает, что вы можете определить будущее расписание события по крайней мере по минимальному времени уведомления до возникновения события. После запланированного события он перейдет в Started состояние после его утверждения или NotBefore времени. Однако в редких случаях операция будет отменена Azure перед началом работы. В этом случае событие будет удалено из массива событий, и влияние не будет происходить как ранее запланированное.

    Примечание.

    В некоторых случаях Azure может предсказать сбой узла на основе снижения производительности оборудования и попытаться предотвратить перерыв в обслуживании, запланировав миграцию. Для затронутых виртуальный машин задается запланированное событие с NotBefore, которое обычно должно происходить через несколько дней. Фактическое время зависит от оценки риска прогнозируемого сбоя. Azure пытается сообщить о предварительном уведомлении за 7 дней, но фактическое время меняется и может быть меньше, если прогноз заключается в том, что существует высокая вероятность сбоя оборудования неизбежно. Чтобы снизить риск для службы в случае сбоя оборудования до выполнения миграции системой, рекомендуется как можно скорее развернуть виртуальную машину самостоятельно.

    Примечание.

    Если на главном узле возник аппаратный сбой, Azure проигнорирует минимальный период уведомления и немедленно начнет процесс восстановления для затронутых виртуальных машин. Это сокращает время восстановления в тех случаях, если затронутые виртуальные машины не могут ответить. Во время процесса восстановления будет создано событие для всех затронутых виртуальных машин с EventType = Reboot и EventStatus = Started.

    Периодичность опроса

    Вы можете опрашивать конечную точку на предмет наличия обновлений с любой частотой. Но чем больше время между запросами, тем меньше времени у вас может остаться для реагирования на предстоящее событие. Для большинства событий оповещения отправляются в диапазоне от 5 до 15 минут до начала события, но в некоторых случаях уведомление может поступить всего за 30 секунд. Чтобы обеспечить максимально возможный запас времени для выполнения действий по устранению рисков, мы рекомендуем опрашивать службу каждую секунду.

    Запуск события

    После того, как вы узнали о предстоящем событии и завершили все действия для корректного завершения работы, вы можете утвердить ожидающее событие, выполнив вызов POST к службе метаданных Azure с помощью EventId. Этот вызов указывает службе Azure, что она может сократить минимальное время уведомления (если возможно). Событие может не начинаться сразу после утверждения, в некоторых случаях Azure требует утверждения всех виртуальных машин, размещенных на узле, прежде чем продолжить работу с событием.

    Следующий пример кода JSON ожидается в тексте запроса POST. Запрос должен содержать список StartRequests. Каждый StartRequest содержит EventId для события, которое нужно ускорить:

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

    Служба всегда возвращает код успешного выполнения 200, если он передает допустимый идентификатор события, даже если другая виртуальная машина уже одобрила событие. Код ошибки 400 указывает, что заголовок запроса или полезные данные были неправильно сформированы.

    Примечание.

    События не будут продолжаться, если только они не утверждены через сообщение POST или время NotBefore истекает. К ним относятся события, активированные пользователем, например перезапуск виртуальной машины из портал Azure.

    Пример 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
    

    Пример для PowerShell

    Invoke-RestMethod -Headers @{"Metadata" = "true"} -Method POST -body '{"StartRequests": [{"EventId": "5DD55B64-45AD-49D3-BBC9-F57D4EA97BD7"}]}' -Uri http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01 | ConvertTo-Json -Depth 64
    

    Пример для Python

    import json
    import requests
    
    def confirm_scheduled_event(event_id):  
       # This payload confirms a single event with id event_id
       payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
       response = requests.post("http://169.254.169.254/metadata/scheduledevents", 
                                headers =  {'Metadata' : 'true'}, 
                                params = {'api-version':'2020-07-01'}, 
                                data = payload)    
       return response.status_code
    

    Примечание.

    Подтверждение событий позволяет выполнить событие для всех ресурсов Resources в событии, а не только для виртуальной машины, которая подтверждает событие. Таким образом, можно выбрать "лидера" для координации подтверждения, например первую виртуальную машину в поле Resources.

    Примеры ответов

    Ниже приведен пример, который был замечен двумя виртуальными машинами, которые были перенесены в другой узел.

    Изменение DocumentIncarnation происходит каждый раз, когда в Events появляется новая информация. Утверждение события позволит выполнить заморозку как для WestNO_0, так и для WestNO_1. Значение DurationInSeconds -1 указывает, что платформа не знает, сколько времени займет операция.

    {
        "DocumentIncarnation":  1,
        "Events":  [
                   ]
    }
    
    {
        "DocumentIncarnation":  2,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Scheduled",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "Mon, 11 Apr 2022 22:26:58 GMT",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  3,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Started",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  4,
        "Events":  [
                   ]
    }
    
    

    Пример на Python

    В следующем примере выполняется запрос запланированных событий в службе метаданных, а затем утверждение каждого ожидающего события.

    #!/usr/bin/python
    import json
    import requests
    from time import sleep
    
    # The URL to access the metadata service
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    # This must be sent otherwise the request will be ignored
    header = {'Metadata' : 'true'}
    # Current version of the API
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    def confirm_scheduled_event(event_id):  
        # This payload confirms a single event with id event_id
        # You can confirm multiple events in a single request if needed      
        payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
        response = requests.post(metadata_url, 
                                headers= header,
                                params = query_params, 
                                data = payload)    
        return response.status_code
    
    def log(event): 
        # This is an optional placeholder for logging events to your system 
        print(event["Description"])
        return
    
    def advanced_sample(last_document_incarnation): 
        # Poll every second to see if there are new scheduled events to process
        # Since some events may have necessarily short warning periods, it is 
        # recommended to poll frequently
        found_document_incarnation = last_document_incarnation
        while (last_document_incarnation == found_document_incarnation):
            sleep(1)
            payload = get_scheduled_events()    
            found_document_incarnation = payload["DocumentIncarnation"]        
            
        # We recommend processing all events in a document together, 
        # even if you won't be actioning on them right away
        for event in payload["Events"]:
    
            # Events that have already started, logged for tracking
            if (event["EventStatus"] == "Started"):
                log(event)
                
            # Approve all user initiated events. These are typically created by an 
            # administrator and approving them immediately can help to avoid delays 
            # in admin actions
            elif (event["EventSource"] == "User"):
                confirm_scheduled_event(event["EventId"])            
                
            # For this application, freeze events less that 9 seconds are considered
            # no impact. This will immediately approve them
            elif (event["EventType"] == "Freeze" and 
                int(event["DurationInSeconds"]) >= 0  and 
                int(event["DurationInSeconds"]) < 9):
                confirm_scheduled_event(event["EventId"])
                
            # Events that may be impactful (for example reboot or redeploy) may need custom 
            # handling for your application
            else: 
                #TODO Custom handling for impactful events
                log(event)
        print("Processed events from document: " + str(found_document_incarnation))
        return found_document_incarnation
    
    def main():
        # This will track the last set of events seen 
        last_document_incarnation = "-1"
    
        input_text = "\
            Press 1 to poll for new events \n\
            Press 2 to exit \n "
        program_exit = False 
    
        while program_exit == False:
            user_input = input(input_text)    
            if (user_input == "1"):                        
                last_document_incarnation = advanced_sample(last_document_incarnation)
            elif (user_input == "2"):
                program_exit = True       
    
    if __name__ == '__main__':
        main()
    

    Следующие шаги