Cenário A: Redimensionando VMs Automaticamente

Configure o redimensionamento automático para máquinas virtuais (VMs) que excedem a memória usando os serviços Notifications, Functions e Monitoring.

Esse cenário envolve a gravação de uma função para redimensionar VMs e a criação de um alarme que envia uma mensagem para essa função. Quando o alarme é ativado, o serviço Notifications envia a mensagem de alarme para o tópico de destino, que, em seguida, é distribuído para as inscrições do tópico. Nesse cenário, as inscrições do tópico incluem a função, bem como seu endereço de e-mail e um número de telefone SMS. A função é chamada no recebimento da mensagem de alarme.

Observação

O serviço Notifications não tem informações sobre uma função após sua chamada. Para obter detalhes, consulte as informações de diagnóstico e solução de problemas em Função Não Chamada ou Executada.

Esta imagem mostra o serviço Notifications no contexto de um cenário que usa uma função para redimensionar VMs.

Política do Serviço IAM Obrigatória

Para usar o Oracle Cloud Infrastructure, um administrador deve ser membro de um grupo com acesso de segurança concedido em uma política por um administrador da tenancy. Esse acesso será necessário se você estiver usando a Console ou a API REST com um SDK, uma CLI ou outra ferramenta. Se você receber uma mensagem de que não tem permissão ou que não está autorizado, verifique com o administrador da tenancy qual tipo de acesso você tem e em qual compartimento seu acesso funciona.

Se você for membro do grupo Administradores, já terá o acesso necessário para executar esse cenário. Caso contrário, você precisará acessar os serviços Monitoring, Notifications e Functions. Você deve ter a permissão FN_INVOCATION na função para poder adicionar a função como uma inscrição em um tópico. Para redimensionar VMs, a função deve estar autorizada a atualizar instâncias de computação. Para autorizar sua função de acesso a outros recursos do Oracle Cloud Infrastructure, como instâncias de computação, inclua a função em um grupo dinâmico e crie uma política para conceder a esses recursos acesso ao grupo dinâmico. Para obter mais informações, consulte Acessando Outros Recursos do Oracle Cloud Infrastructure pelas Funções em Execução.

Tarefa 1: Criar e Autorizar Sua Função

Quando você cria sua função para redimensionar VMs usando seu SDK preferencial e autorizar sua função a acessar VMs (inclua a função em um grupo dinâmico e conceda acesso a esse grupo dinâmico), todas as outras etapas do cenário podem ser concluídas na Console. Como alternativa, você pode usar a CLI ou a API do Oracle Cloud Infrastructure, que permite que você mesmo execute as operações individuais.

Para obter mais informações sobre a autorização de funções para acessar outros recursos do Oracle Cloud Infrastructure, consulte Acessando Outros Recursos do Oracle Cloud Infrastructure pelas Funções em Execução.

Exemplo do código da função
Observação

Para esta amostra de código, recomendamos tratar a idempotência por meio de um banco de dados.

A amostra de código a seguir é para que uma função redimensione VMs. Para obter instruções sobre como criar e implantar funções, consulte Criando e Implantando Funções.

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"}
    )
Incluir sua função em um grupo dinâmico

Localize e anote seu OCID de função (o formato é ocid1.fnfunc.oc1.iad.exampleuniqueID). Em seguida, especifique a seguinte regra no grupo dinâmico relevante:

resource.id = '<function-ocid>'
Criar uma política para conceder ao grupo dinâmico acesso a VMs ( instâncias de computação)

Adicione a seguinte política:

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

Tarefa 2: Criar o Tópico

Para obter ajuda com o diagnóstico e a solução de problemas, consulte Diagnóstico e Solução de Problemas do Serviço Notifications.

  • Observação

    Outro workflow da Console para esse cenário envolve a criação de um novo tópico e da primeira assinatura quando você cria o alarme e, em seguida, cria assinaturas adicionais nesse tópico.
    1. Abra o painel Criar Tópico: Na página da lista Tópicos, selecione Criar Tópico. Se precisar de ajuda para localizar a página da lista, consulte Listando Tópicos.
    2. Para Nome, digite o seguinte: Tópico de Alarme
    3. Selecione Criar.
  • Use o comando oci ons topic create e os parâmetros necessários para criar um tópico:

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

    Exemplo:

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

    Para obter uma lista completa de parâmetros e valores para comandos da CLI, consulte a Referência de Linha de Comando para Notificações.

  • Execute a operação CreateTopic para criar um tópico.

    Exemplo:

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

Tarefa 3: Criar as Assinaturas

Sua função deve ser implantada antes de criar a assinatura da função.

Para obter ajuda com o diagnóstico e a solução de problemas, consulte Diagnóstico e Solução de Problemas do Serviço Notifications.

    1. Selecione o tópico criado anteriormente (o nome do exemplo era Tópico de Alarme): Na página da lista Tópicos, selecione o tópico com o qual você deseja trabalhar. Se precisar de ajuda para encontrar a página da lista ou o tópico, consulte Listando Tópicos.
    2. Crie a assinatura da função.
      1. Abra o painel Criar Assinatura: na página de detalhes do tópico, selecione Criar Assinatura.
        O painel Criar Inscrição é aberto.
      2. Para Protocolo, selecione Função.
      3. Preencha os campos restantes.
        Campo Descrição
        Compartimento da Função Selecione o compartimento que contém a função.
        Aplicativo da Função Selecione o aplicativo que contém a função.
        Função Selecione a função.
      4. Selecione Criar.
        Nenhuma confirmação é necessária para novas assinaturas de função.
    3. Crie a assinatura de SMS.
      1. Abra o painel Criar Assinatura: na página de detalhes do tópico, selecione Criar Assinatura.
        O painel Criar Inscrição é aberto.
      2. Para Protocolo, selecione SMS.
      3. Preencha os campos restantes.
        Campo Descrição
        País Selecione o país do número de telefone. Consulte Antes de Começar.
        Número de Telefone Digite o número de telefone usando o formato E.164.
      4. Selecione Criar.
      5. Confirme a nova assinatura de SMS: siga as instruções recebidas no telefone.
    4. Crie a assinatura de e-mail.
      1. Abra o painel Criar Assinatura: na página de detalhes do tópico, selecione Criar Assinatura.
        O painel Criar Inscrição é aberto.
      2. Para Protocolo, selecione E-mail.
      3. Preencha os campos restantes.
        Campo Descrição
        E-mail Digite um endereço de e-mail.
      4. Selecione Criar.
      5. Confirmar a nova assinatura de e-mail: Abra o e-mail e navegue até o URL de confirmação.
  • Observação

    Depois de criar as assinaturas de SMS e e-mail, confirme-as.

    Use o comando oci ons subscription create e os parâmetros necessários para criar cada assinatura:

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

    Exemplo de assinatura da função:

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

    Exemplo de assinatura SMS:

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

    Exemplo de inscrição de e-mail:

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

    Para obter uma lista completa de parâmetros e valores para comandos da CLI, consulte a Referência de Linha de Comando para Notificações.

  • Observação

    Depois de criar as assinaturas de SMS e e-mail, confirme-as.

    Execute a operação CreateSubscription para criar cada assinatura.

    Exemplo de assinatura da função:

    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>"
    }

    Exemplo de assinatura 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>"
    }

    Exemplo de inscrição de e-mail:

    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"
    }

Tarefa 4: Criar o Alarme

Para obter ajuda com o diagnóstico e a solução de problemas, consulte Diagnóstico e Solução de Problemas do Serviço Notifications.

    1. Abra a página Criar Alarme.
      1. Abra o menu de navegação e selecione Observabilidade e Gerenciamento. Em Monitoramento, selecione Definições de Alarme.
      2. Selecione Criar Alarme.

    2. Para Nome do alarme, digite o seguinte: Alarme de Memória da VM
    3. Em Descrição da métrica, selecione a métrica, o intervalo e a estatística.

      Campo Valor de exemplo para este cenário
      Compartimento Selecione o compartimento que contém a VM que você deseja redimensionar automaticamente.
      Namespace da métrica oci_computeagent
      Nome da métrica MemoryUtilization
      Intervalo 1m
      Estatística Máximo
    4. Em Regra de acionamento, configure o limite de alarme.

      Campo Valor de exemplo para este cenário
      Operador superior a
      Valor 90
      Minutos de atraso do trigger 1
    5. Em Notificações, Destinos, selecione o tópico que você criou anteriormente.
      Campo Valor de exemplo para este cenário
      Serviço de Destino Notifications Service
      Compartimento Selecione o compartimento que contém o tópico que você criou anteriormente.
      Tópico Selecione o tópico que você criou anteriormente.
    6. Selecione Salvar alarme.

  • Use o comando oci monitoring alarm create e os parâmetros obrigatórios para criar um alarme:

    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>

    Por exemplo:

    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 obter uma lista completa de parâmetros e valores para comandos da CLI, consulte a Referência de Linha de Comando para o Serviço Monitoring.

  • Execute a operação CreateAlarm para criar um alarme.

    Por exemplo:

    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
    }