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.
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.
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.
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"}
)
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>'
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.- 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.
- Para Nome, digite o seguinte: Tópico de Alarme
- 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.
- 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.
-
Crie a assinatura da função.
-
Crie a assinatura de SMS.
-
Crie a assinatura de e-mail.
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.
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.
- Abra a página Criar Alarme.
- Abra o menu de navegação e selecione Observabilidade e Gerenciamento. Em Monitoramento, selecione Definições de Alarme.
-
Selecione Criar Alarme.
- Para Nome do alarme, digite o seguinte: Alarme de Memória da VM
-
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 -
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 - 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. -
Selecione Salvar alarme.
- Abra a página Criar 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 }