Escenario A: Cambio de tamaño automático de las VM

Configure el cambio de tamaño automático para las máquinas virtuales (VM) que excedan la memoria mediante los servicios Notifications, Functions y Monitoring.

Este escenario implica escribir una función para cambiar el tamaño de las VM y crear una alarma  que envíe un mensaje a esa función. Cuando se activa la alarma, el servicio de notificaciones envía el mensaje de alarma al tema de destino, que a continuación distribuye las suscripciones del tema. En este escenario, las suscripciones del tema incluyen la función, así como su dirección de correo electrónico y un número de teléfono SMS. Al recibir el mensaje de alarma, se llama a la función.

Nota

El servicio de notificaciones no tiene información sobre una función una vez llamada. Para obtener detalles, consulte la información de solución de problemas en Función no llamada o no ejecutada.

En esta imagen se muestran las notificaciones en el contexto de un escenario que utiliza una función para cambiar el tamaño de las VM.

Política de IAM necesaria

Para utilizar Oracle Cloud Infrastructure, un administrador debe otorgarle acceso de seguridad en una política . Este acceso es necesario tanto si utiliza la Consola como la API de REST con un SDK, una CLI u otra herramienta. Si aparece un mensaje que le informa de que no tiene permiso o no tiene autorización, verifique con el administrador el tipo de acceso que tiene y en qué compartimento trabajar.

Si es miembro del grupo Administradores, ya tendrá el acceso necesario para ejecutar este escenario. De lo contrario, necesita acceso a los servicios de control, notificaciones y funciones. Debe tener el permiso FN_INVOCATION en la función para poder agregar la función como suscripción a un tema. Para cambiar el tamaño de las VM, la función debe estar autorizada para actualizar instancias informáticas. A fin de autorizar la función para que pueda acceder a otros recursos de Oracle Cloud Infrastructure, como instancias informáticas, incluya la función en un grupo dinámico y cree una política para otorgar acceso al grupo dinámico a esos recursos. Para obtener más información, consulte Acceso a otros recursos de Oracle Cloud Infrastructure desde funciones en ejecución.

Tarea 1: Creación y autorización de la función

Una vez creada la función para cambiar el tamaño de las VM con su SDK preferido y autorizada su función para acceder a las VM (incluir la función en un grupo dinámico y otorgar acceso a ese grupo dinámico), todos los demás pasos del escenario se pueden completar en la consola. También puede utilizar la CLI o API de Oracle Cloud Infrastructure, que le permite ejecutar las operaciones individuales.

Para obtener más información sobre la autorización de funciones para acceder a otros recursos de Oracle Cloud Infrastructure, consulte Acceso a otros recursos de Oracle Cloud Infrastructure desde funciones en ejecución.

Ejemplo de código de función
Nota

Para este ejemplo de código, recomendamos gestionar idempotency mediante una base de datos.

El siguiente ejemplo de código es para que una función cambie el tamaño de las VM. Para obtener instrucciones sobre la creación y el despliegue de funciones, consulte Creación y despliegue de funciones.

import io
import json
import oci

from fdk import response

def increase_compute_shape(instance_id, alarm_msg_shape):
    signer = oci.auth.signers.get_resource_principals_signer()
    compute_client = oci.core.ComputeClient(config={}, signer=signer)
    current_shape = compute_client.get_instance(instance_id).data.shape
    print("INFO: current shape for Instance {0}: {1}".format(instance_id,current_shape), flush=True)
    if current_shape != alarm_msg_shape:
        return "The shape of Instance {} differs from the Alarm message".format(instance_id)
    # improve the logic below to handle more scenarios, make sure the shapes you select are available in the region and AD
    if  current_shape == "VM.Standard1.1":
        new_shape = "VM.Standard2.1"
    elif current_shape == "VM.Standard2.1":
        new_shape = "VM.Standard2.2"
    else:
        return "Instance {0} cannot get a bigger shape than its current shape {1}".format(instance_id,current_shape)
    print("INFO: new shape for Instance {0}: {1}".format(instance_id,new_shape), flush=True)
    try:
        update_instance_details = oci.core.models.UpdateInstanceDetails(shape=new_shape)
        resp = compute_client.update_instance(instance_id=instance_id, update_instance_details=update_instance_details)
        print(resp, flush=True)
    except Exception as ex:
        print('ERROR: cannot update instance {}'.format(instance_id), flush=True)
        raise
    return "The shape of Instance {} is updated, the instance is rebooting...".format(instance_id)

def handler(ctx, data: io.BytesIO=None):
    alarm_msg = {}
    message_id = func_response = ""
    try:
        headers = ctx.Headers()
        message_id = headers["x-oci-ns-messageid"]
    except Exception as ex:
        print('ERROR: Missing Message ID in the header', ex, flush=True)
        raise
    print("INFO: Message ID = ", message_id, flush=True)
    # the Message Id can be stored in a database and be used to check for duplicate messages
    try:
        alarm_msg = json.loads(data.getvalue())
        print("INFO: Alarm message: ")
        print(alarm_msg, flush=True)
    except (Exception, ValueError) as ex:
        print(str(ex), flush=True)

    if alarm_msg["type"] == "OK_TO_FIRING":
        if alarm_msg["alarmMetaData"][0]["dimensions"]:
            alarm_metric_dimension = alarm_msg["alarmMetaData"][0]["dimensions"][0]   #assuming the first dimension matches the instance to resize
            print("INFO: Instance to resize: ", alarm_metric_dimension["resourceId"], flush=True)
            func_response = increase_compute_shape(alarm_metric_dimension["resourceId"], alarm_metric_dimension["shape"])
            print("INFO: ", func_response, flush=True)
        else:
            print('ERROR: There is no metric dimension in this alarm message', flush=True)
            func_response = "There is no metric dimension in this alarm message"
    else:
        print('INFO: Nothing to do, alarm is not FIRING', flush=True)
        func_response = "Nothing to do, alarm is not FIRING"

    return response.Response(
        ctx, 
        response_data=func_response,
        headers={"Content-Type": "application/json"}
    )
Inclusión de la función en un grupo dinámico

Busque y anote el OCID  de función (el formato es ocid1.fnfunc.oc1.iad.exampleuniqueID); a continuación, especifique la siguiente regla en el grupo dinámico  relevante:

resource.id = '<function-ocid>'
Creación de una política para otorgar acceso al grupo dinámico a las VM

Agregue la siguiente política :

allow dynamic-group <dynamic-group-name> to use instances in tenancy

Tarea 2: Crear el tema

Para obtener ayuda con la resolución de problemas, consulte Resolución de problemas de notificaciones.

  • Nota

    Otro flujo de trabajo de la consola de este escenario implica la creación de un nuevo tema y la primera suscripción al crear la alarma y, a continuación, la creación de suscripciones adicionales en ese tema.
    1. Abra el panel Crear Tema: en la página de lista Temas, seleccione Crear Tema. Si necesita ayuda para buscar la página de lista, consulte Lista de temas.
    2. Para Nombre, escriba lo siguiente: Tema de alarma
    3. Haga clic en Crear.
  • Utilice el comando oci ons topic create y los parámetros necesarios para crear un tema:

    oci ons topic create --name <name> --compartment-id <compartment_OCID>

    Ejemplo:

    oci ons topic create --name "Alarm Topic" --compartment-id "<compartment_OCID>"

    Para obtener una lista completa de parámetros y valores para los comandos de la CLI, consulte la Command Line Reference for Notifications.

  • Ejecute la operación CreateTopic para crear un tema.

    Ejemplo:

    POST /20181201/topics
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "name": "Alarm Topic",
      "compartmentId": "<compartment_OCID>"
    }

Tarea 3: Creación de suscripciones

La función se debe desplegar antes de crear la suscripción a la función.

Para obtener ayuda con la resolución de problemas, consulte Resolución de problemas de notificaciones.

    1. Seleccione el tema que ha creado anteriormente (el nombre de ejemplo era Tema de alarma): en la página de lista Temas, seleccione el tema con el que desea trabajar. Si necesita ayuda para buscar la página de lista o el tema, consulte Lista de temas.
    2. Cree la suscripción de función.
      1. Abra el panel Crear suscripción: en la página de detalles del tema, haga clic en Crear suscripción.
        Se abrirá el panel Crear suscripción.
      2. En Protocolo, seleccione Función.
      3. Rellene los campos restantes.
        Campo Descripción
        Compartimento de función Seleccione el compartimento que contiene la función.
        Aplicación de función Seleccione la aplicación que contiene la función.
        Función Seleccione la función.
      4. Haga clic en Crear.
        No se necesita confirmación para las nuevas suscripciones a funciones.
    3. Cree la suscripción de SMS.
      1. Abra el panel Crear suscripción: en la página de detalles del tema, haga clic en Crear suscripción.
        Se abrirá el panel Crear suscripción.
      2. En Protocolo, seleccione SMS.
      3. Rellene los campos restantes.
        Campo Descripción
        País Seleccione el país para el número de teléfono. Consulte Antes de empezar.
        Número de teléfono Introduzca el número de teléfono con el formato E.164.
      4. Haga clic en Crear.
      5. Confirme la nueva suscripción de SMS: siga las instrucciones recibidas por teléfono.
    4. Cree la suscripción de correo electrónico.
      1. Abra el panel Crear suscripción: en la página de detalles del tema, haga clic en Crear suscripción.
        Se abrirá el panel Crear suscripción.
      2. En Protocolo, seleccione Correo electrónico.
      3. Rellene los campos restantes.
        Campo Descripción
        Correo electrónico Escriba una dirección de correo electrónico.
      4. Haga clic en Crear.
      5. Confirmar la nueva suscripción de correo electrónico: abra el correo electrónico y navegue a la URL de confirmación.
  • Nota

    Después de crear las suscripciones de SMS y correo electrónico, confírmelas.

    Utilice el comando oci ons subscription create y los parámetros necesarios para crear cada suscripción:

    oci ons subscription create --protocol <subscription_type> --subscription-endpoint <endpoint> --compartment-id <compartment_OCID> --topic-id <topic_OCID>

    Ejemplo de suscripción de función:

    oci ons subscription create --protocol "ORACLE_FUNCTIONS" --subscription-endpoint "<function-ocid>" --compartment-id "<compartment_OCID>" --topic-id "<topic_OCID>"

    Ejemplo de suscripción de SMS:

    oci ons subscription create --protocol "SMS" --subscription-endpoint "<sms-endpoint>" --compartment-id "<compartment_OCID>" --topic-id "<topic_OCID>"

    Ejemplo de suscripción de correo electrónico:

    oci ons subscription create --protocol "EMAIL" --subscription-endpoint "john.smith@example.com" --compartment-id "<compartment_OCID>" --topic-id "<topic_OCID>"

    Para obtener una lista completa de parámetros y valores para los comandos de la CLI, consulte la Command Line Reference for Notifications.

  • Nota

    Después de crear las suscripciones de SMS y correo electrónico, confírmelas.

    Ejecute la operación CreateSubscription para crear cada suscripción.

    Ejemplo de suscripción de función:

    POST /20181201/subscriptions
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "topicId": "<topic_OCID>",
      "compartmentId": "<compartment_OCID>",
      "protocol": "ORACLE_FUNCTIONS",
      "endpoint": "<function_OCID>"
    }

    Ejemplo de suscripción de SMS:

    POST /20181201/subscriptions
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "topicId": "<topic_OCID>",
      "compartmentId": "<compartment_OCID>",
      "protocol": "SMS",
      "endpoint": "<sms-endpoint>"
    }

    Ejemplo de suscripción de correo electrónico:

    POST /20181201/subscriptions
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "topicId": "<topic_OCID>",
      "compartmentId": "<compartment_OCID>",
      "protocol": "EMAIL",
      "endpoint": "john.smith@example.com"
    }

Tarea 4: Creación de la alarma

Para obtener ayuda con la resolución de problemas, consulte Resolución de problemas de notificaciones.

    1. Abra la página Crear alarma.
      1. Abra el menú de navegación y haga clic en Observación y gestión. En Supervisión, haga clic en Definiciones de alarma.
      2. Haga clic en Crear alarma.

    2. Para Nombre de alarma, escriba lo siguiente: Alarma de memoria de VM
    3. En Descripción de métrica, seleccione la métrica, el intervalo y la estadística.

      Campo Valor de ejemplo para este escenario
      Compartimento Seleccione el compartimento que contiene la VM cuyo tamaño desea cambiar automáticamente.
      Espacio de nombre de métrica oci_computeagent
      Nombre de la Métrica MemoryUtilization
      Intervalo 1m
      Estadística Máximo
    4. En Regla de disparador, configure el umbral de alarma.

      Campo Valor de ejemplo para este escenario
      Operador mayor que
      Valor 90
      Minutos de retraso del disparador 1
    5. En Notificaciones, Destinos, seleccione el tema que ha creado anteriormente.
      Campo Valor de ejemplo para este escenario
      Servicio de destino Servicio Notificaciones
      Compartimento Seleccione el compartimento que contiene el tema que ha creado anteriormente.
      Tema Seleccione el tema que ha creado anteriormente.
    6. Haga clic en Guardar alarma.

  • Utilice el comando oci monitoring alarm create y los parámetros necesarios para crear una alarma:

    oci monitoring alarm create --display-name <name> --compartment-id <compartment_OCID> --metric-compartment-id <compartment_OCID> --namespace <metric_namespace> --query-text <mql_expression> --severity <level> --destinations <file_or_text> --is-enabled <true_or_false>

    Ejemplo:

    oci monitoring alarm create --display-name "VM Memory Alarm" --compartment-id "<compartment_OCID>" --metric-compartment-id "<compartment_OCID>" --namespace "oci_computeagent" --query-text "MemoryUtilization[1m].max() > 90" --severity "CRITICAL" --destinations "<topic-ocid>" --is-enabled true

    Para obtener una lista completa de parámetros y valores para los comandos de la CLI, consulte la Command Line Reference for Monitoring.

  • Ejecute la operación CreateAlarm para crear una alarma.

    Ejemplo:

    POST /20180401/alarms
    Host: telemetry.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "displayName": "VM Memory Alarm",
      "compartmentId": "<compartment_OCID>",
      "metricCompartmentId": "<compartment_OCID>",
      "namespace": "oci_computeagent",
      "query": "MemoryUtilization[1m].max() > 90",
      "severity": "CRITICAL",
      "destinations":
      [
        "<topic_OCID>"
      ],
      "isEnabled": true
    }