Como criar e iniciar uma instância de VM preemptiva

Nesta página, você aprenderá a criar e usar uma instância preemptiva de máquina virtual (VM, na sigla em inglês). Essa instância pode ser criada e executada a um preço muito mais baixo do que as instâncias normais. No entanto, ela pode ser encerrada no Compute Engine quando o acesso aos recursos para outras tarefas é necessário. As instâncias preemptivas sempre são encerradas após 24 horas. Para saber mais sobre elas, leia a documentação relativa a instâncias preemptivas.

As instâncias preemptivas são recomendadas apenas para aplicativos tolerantes a falhas que oferecem suporte a preempções de instância. Verifique se esse é o caso do seu aplicativo antes de criar uma instância. Leia a documentação sobre instâncias preemptivas para entender os riscos e o valor desse tipo de instância.

Antes de começar

Como criar uma instância preemptiva

Crie uma instância preemptiva por meio do Console do Google Cloud Platform, da ferramenta gcloud ou da API.

Console

Criar uma instância preemptiva é igual a criar uma instância normal, exceto pelo fato de você ativar a propriedade preemptible.

  1. No Console do GCP, acesse a página Instâncias de VM.

    Acessar a página "Instâncias da VM"

  2. Clique em Criar instância.
  3. Na página Criar uma nova instância, preencha as propriedades da sua instância.
  4. Clique em Gerenciamento, segurança, discos, rede, locatário individual.
  5. Em Política de disponibilidade, defina a opção Preempção como Ativada. Essa configuração desativa a reinicialização automática da instância e define a ação de manutenção do host como Encerrar.
  6. Clique em Criar para criar a instância.

gcloud

Com a ferramenta gcloud compute, use o mesmo comando instances create que você usaria para criar uma instância normal, mas adicione a sinalização --preemptible.

gcloud compute instances create [INSTANCE_NAME] --preemptible

em que [INSTANCE_NAME] é o nome da instância.

API

Na API, crie uma solicitação normal para criar uma instância, mas inclua a propriedade preemptible em scheduling e defina-a como true. Por exemplo:

POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances

{
  'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]',
  'name': '[INSTANCE_NAME]',
  'scheduling':
  {
    'preemptible': true
  },
  ...
}

Cotas de CPU preemptiva

Da mesma forma que as instâncias regulares, as instâncias preemptivas requerem cotas de CPU. Para evitar que as instâncias preemptivas consumam as cotas de CPU das instâncias regulares, solicite uma cota especial de "CPU preemptiva". Assim que essa cota é concedida para essa região no Compute Engine, todas as instâncias preemptivas são deduzidas dessa cota. As instâncias regulares continuam a ser deduzidas da cota de CPU normal.

Em regiões onde não há cotas de CPU preemptiva, use a cota de CPU regular para criar instâncias preemptivas. Também é preciso ter IP e cota de disco suficientes. A cota de CPU preemptiva não é visível na ferramenta gcloud ou nas páginas de cota do Console do GCP, a menos que essa cota tenha sido concedida no Compute Engine.

Para mais informações sobre cotas, visite a página Cotas de recurso.

Como processar a preempção com um script de desligamento

Quando sua instância passar por uma interrupção forçada, use um script de desligamento para executar ações de limpeza antes que ela pare. Por exemplo, é possível encerrar normalmente um processo em execução e copiar um arquivo de checkpoint para o Cloud Storage.

O script de desligamento a seguir pode ser adicionado a uma instância preemptiva em execução ou quando ela for criada. Esse script é executado quando a instância começa a ser encerrada, antes que o comando kill normal do sistema operacional encerre todos os processos restantes. Após o encerramento normal do programa desejado, o script faz o upload paralelo de um arquivo de checkpoint para um intervalo do Google Cloud Storage.

#!/bin/bash

MY_PROGRAM="[PROGRAM_NAME]" # For example, "apache2" or "nginx"
MY_USER="[LOCAL_USERNAME]"
CHECKPOINT="/home/$MY_USER/checkpoint.out"
GSUTIL_OPTS="-m -o GSUtil:parallel_composite_upload_threshold=32M"
BUCKET_NAME="[BUCKET_NAME]" # For example, "my-checkpoint-files" (without gs://)

echo "Shutting down!  Seeing if ${MY_PROGRAM} is running."

# Find the newest copy of $MY_PROGRAM
PID="$(pgrep -n "$MY_PROGRAM")"

if [[ "$?" -ne 0 ]]; then
  echo "${MY_PROGRAM} not running, shutting down immediately."
  exit 0
fi

echo "Sending SIGINT to $PID"
kill -2 "$PID"

# Portable waitpid equivalent
while kill -0 "$PID"; do
   sleep 1
done

echo "$PID is done, copying ${CHECKPOINT} to gs://${BUCKET_NAME} as ${MY_USER}"

su "${MY_USER}" -c "gsutil $GSUTIL_OPTS cp $CHECKPOINT gs://${BUCKET_NAME}/"

echo "Done uploading, shutting down."

Para adicionar esse script a uma instância, configure-o para trabalhar com um aplicativo na sua instância e adicione-o aos metadados dela.

  1. Copie ou faça o download do script de desligamento na estação de trabalho local.
  2. Abra o arquivo para editá-lo e altere as seguintes variáveis:
    • [PROGRAM_NAME] é o nome do processo ou programa que você quer encerrar. Por exemplo, apache2 ou nginx.
    • [LOCAL_USER] é o nome de usuário que você usou para fazer login na máquina virtual.
    • [BUCKET_NAME] é o nome do intervalo do Cloud Storage em que você quer salvar o arquivo de checkpoint do programa. Observe que o nome do intervalo não começa com gs:// nesse caso.
  3. Salve as alterações.
  4. Adicione o script de encerramento a uma instância nova ou a uma instância atual.

Para esse script, presume-se que:

  • A instância tenha sido criada pelo menos com acesso de leitura e gravação ao Cloud Storage. Consulte a documentação de autenticação para instruções sobre como criar uma instância com os escopos apropriados.

  • Você tenha um intervalo do Cloud Storage e permissão para gravar nele.

Como verificar se uma instância é preemptiva

É possível verificar se uma instância está configurada para ser preemptiva usando o Console do GCP, a ferramenta gcloud ou a API.

Console


Verifique se uma instância é preemptiva consultando as propriedades dela.

  1. Acesse a página "Instâncias de VM".

    Acessar a página "Instâncias de VM"

  2. Selecione seu projeto e clique em Continuar.
  3. Clique no nome da instância que você quer verificar. A página de detalhes da instância será aberta.
  4. O status preemptivo é especificado na seção Políticas de disponibilidade dos detalhes da instância.

gcloud


Em gcloud compute, use instances describe para conseguir informações sobre uma instância; por exemplo, se ela é preemptiva.

gcloud compute instances describe [INSTANCE_NAME]

em que [INSTANCE_NAME] é o nome da instância.

As informações de resposta incluem o status preemptivo na seção de programação.

...
scheduling:
  automaticRestart: false
  onHostMaintenance: TERMINATE
  preemptible: true
...

API


Para verificar se uma instância é preemptiva, use a API para enviar uma solicitação GET para o URI da instância.

GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]

As informações de resposta incluem o status preemptivo em scheduling.

{
    "kind": "compute#instance",
    "id": "4468501694759003918",
    "creationTimestamp": "2015-04-15T15:40:59.004-07:00",
    "zone": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f",
    "status": "RUNNING",
    "name": "example-instance",
    "scheduling":
    {
       "preemptible": true
    },
    ...
 }

Também é possível determinar se uma instância é preemptiva a partir da própria instância. Basta verificar o valor scheduling/preemptible do servidor de metadados nos metadados de instância padrão da instância.

Por exemplo, use curl na instância para receber o valor de scheduling/preemptible:

curl "http://metadata.google.internal/computeMetadata/v1/instance/scheduling/preemptible" -H "Metadata-Flavor: Google"
TRUE

Se o valor for TRUE, significa que a instância é preemptiva.

Como detectar se uma instância passou por interrupção forçada

Determine se uma instância passou por interrupção forçada usando o Console do Google Cloud Platform, a ferramenta gcloud ou a API.

Console


Verifique se uma instância foi interrompida consultando os registros de atividades do sistema.

  1. Acesse a página "Registros".

    Acessar a página "Registros"

  2. Selecione seu projeto e clique em Continuar.
  3. Adicione compute.instances.preempted ao campo filtrar por rótulo ou pesquisa de texto.
  4. Outra opção é inserir o nome de uma instância caso você queira consultar operações de preempção de uma determinada instância.
  5. Pressione Enter para aplicar os filtros especificados. No Console do GCP, a lista de registros é atualizada para mostrar apenas as operações em que uma instância foi interrompida.
  6. Selecione uma operação na lista para ver detalhes sobre a instância que passou por interrupção forçada.

gcloud


Use o comando gcloud compute operations list com um parâmetro de filtro para receber uma lista de eventos de preempção no projeto.

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted"

É possível usar o parâmetro de filtro para ampliar ainda mais o escopo dos resultados. Por exemplo, para ver eventos de preempção apenas dentro de um grupo de instâncias gerenciadas:

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted AND targetLink:instances/[BASE_INSTANCE_NAME]"

gcloud retorna uma resposta semelhante a esta:

NAME                  TYPE                         TARGET                                   HTTP_STATUS STATUS TIMESTAMP
systemevent-xxxxxxxx  compute.instances.preempted  us-central1-f/instances/example-instance-xxx  200         DONE   2015-04-02T12:12:10.881-07:00

Um tipo de operação compute.instances.preempted indica que a instância passou por interrupção forçada. É possível usar o comando operations describe para mais informações sobre uma determinada operação de preempção.

gcloud compute operations describe \
    systemevent-xxxxxxxx

gcloud retorna uma resposta semelhante a esta:

...
operationType: compute.instances.preempted
progress: 100
selfLink: https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/operations/systemevent-xxxxxxxx
startTime: '2015-04-02T12:12:10.881-07:00'
status: DONE
statusMessage: Instance was preempted.
...

API


Para acessar uma lista das operações recentes do sistema, envie uma solicitação GET para o URI das operações da zona.

GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/operations

A resposta contém uma lista das operações recentes.

{
  "kind": "compute#operation",
  "id": "15041793718812375371",
  "name": "systemevent-xxxxxxxx",
  "zone": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f",
  "operationType": "compute.instances.preempted",
  "targetLink": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/instances/example-instance",
  "targetId": "12820389800990687210",
  "status": "DONE",
  "statusMessage": "Instance was preempted.",
  ...
}

Para que a resposta mostre apenas operações de preempção, adicione um filtro à solicitação de API: operationType="compute.instances.preempted". Para ver as operações de preempção de uma instância específica, adicione um parâmetro targetLink ao filtro: operationType="compute.instances.preempted" AND targetLink="https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]".

Outra opção é determinar se uma instância passou por interrupção forçada dentro da própria instância. Isso é útil quando você quer lidar com um desligamento decorrente de uma preempção do Compute Engine de maneira diferente de um desligamento normal em um script de desligamento. Para fazer isso, basta verificar o valor preempted do servidor de metadados nos metadados de instância padrão da instância.

Por exemplo, use curl na instância para receber o valor de preempted:

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google"
TRUE

Se esse valor for TRUE, significa que a instância passou por interrupção forçada no Compute Engine. Caso contrário, será FALSE.

Para usar isso fora de um script de encerramento, anexe ?wait_for_change=true ao URL. Será executada uma solicitação HTTP GET pendente que só retornará quando os metadados tiverem sido alterados e a instância tiver passado por interrupção forçada.

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted?wait_for_change=true" -H "Metadata-Flavor: Google"
TRUE

Práticas recomendadas

Estas são algumas práticas recomendadas para ajudar você a aproveitar ao máximo as instâncias preemptivas de VM.

Escolher formas menores de máquina

Os recursos para instâncias preemptivas de VM são provenientes da capacidade excedente e de backup do Google Cloud Platform. Normalmente, é mais fácil receber muita capacidade preemptiva com tipos de máquinas menores do que maiores. As taxas de preempção para tipos de máquinas menores com menos de 32 núcleos também são historicamente inferiores às dos tipos de máquinas maiores.

Também é possível receber mais capacidade disponível usando um tipo de máquina personalizado que esteja entre os tipos predefinidos. Por exemplo, provavelmente há mais capacidade para um tipo de máquina personalizado com 48 vCPUs do que em n1-standard-64s.

Executar grandes clusters de VM preemptiva fora dos horários de pico

A carga nos data centers do Google Cloud Platform varia de acordo com a localização e a hora do dia, mas geralmente é mais baixa à noite e nos fins de semana. Assim, o melhor momento para executar grandes clusters de VM preemptiva é durante esses períodos.

Desenvolver os aplicativos para serem tolerantes a falhas e preempção

É importante estar preparado para mudanças nos padrões de preempção em diferentes momentos. Por exemplo, no caso de uma interrupção parcial em uma zona, é possível que um grande número de instâncias preemptivas sejam rejeitadas para dar espaço a instâncias regulares que precisam ser movidas como parte da recuperação. Nesse pequeno período de tempo, a taxa de preempção é muito diferente de qualquer outro dia. Se seu aplicativo considera que as preempções sempre ocorrem em pequenos grupos, pode ser que você não esteja preparado para um evento desse tipo. Interrompa a instância de VM para testar o comportamento do seu aplicativo em um evento de preempção.

Tentar criar novamente as instâncias que passaram por interrupção forçada

Se a instância de VM tiver passado por interrupção forçada, tente criar novas instâncias preemptivas uma ou duas vezes antes de voltar às instâncias normais. Dependendo dos requisitos, combine instâncias regulares com preemptivas nos clusters para garantir que o trabalho ocorra em um ritmo adequado.

Usar scripts de desligamento

Gerencie avisos de desligamento e de preempção com um script de desligamento que salva o progresso de um job. Dessa forma, é possível continuar de onde você parou em vez de começar do zero.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Compute Engine