Compartilhar volumes de disco permanente entre VMs


É possível anexar um volume de disco permanente SSD no modo de vários gravadores com até duas instâncias de máquina virtual (VM, na sigla em inglês) N2 simultaneamente, para que ambas as VMs possam ler e gravar no disco. Para ativar o modo de vários gravadores em novos discos permanentes, crie um volume de disco permanente e especifique a sinalização --multi-writer na CLI gcloud ou a propriedade multiWriter na API Compute Engine.

Os volumes de discos permanentes no modo de vários gravadores fornecem um recurso de armazenamento em blocos compartilhado e apresentam uma base infraestruturada para criar sistemas de armazenamento distribuídos e serviços semelhantes altamente disponíveis. Ao usar volumes de discos permanentes no modo de vários gravadores, use um sistema de software de armazenamento de escalonamento horizontal com a capacidade de coordenar o acesso a dispositivos de disco permanente em várias VMs. Exemplos desses sistemas de armazenamento incluem Lustre e o IBM Spectrum Scale. A maioria dos sistemas de arquivos de VM única, como EXT4, XFS e NTFS, não foi projetada para ser usada com o armazenamento em blocos compartilhados. Para mais informações, consulte Práticas recomendadas neste documento. Se você precisar de um armazenamento de arquivos totalmente gerenciado, ative um compartilhamento de arquivos do Filestore nas VMs do Compute Engine.

Os volumes do Persistent Disk no modo de vários gravadores são compatíveis com um subconjunto de comandos do Persistent Reservations SCSI-3 (SCSI PR). Aplicativos de alta disponibilidade podem usar esses comandos para configurações de encapsulamento e failover de E/S.

Os seguintes comandos SCSI PR são compatíveis:

  • ENTRADA {REPORT CAPABILITIES, READ FULL STATUS, READ RESERVATION, READ KEYS}
  • SAÍDA {REGISTER, REGISTER AND IGNORE EXISTING KEY, RESERVE, PREEMPT, CLEAR, RELEASE}

Antes de começar

  • Configure a autenticação, caso ainda não tenha feito isso. A autenticação é o processo de verificação da sua identidade para acesso a serviços e APIs do Google Cloud. Para executar códigos ou amostras de um ambiente de desenvolvimento local, autentique-se no Compute Engine da seguinte maneira.

    Selecione a guia para como planeja usar as amostras nesta página:

    Console

    Quando você usa o console do Google Cloud para acessar os serviços e as APIs do Google Cloud, não é necessário configurar a autenticação.

    gcloud

    1. Instale a Google Cloud CLI e inicialize-a executando o seguinte comando:

      gcloud init
    2. Defina uma região e uma zona padrão.

    Java

    Para usar as amostras de Java nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

    Python

    Para usar as amostras de Python nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

    REST

    Para usar as amostras da API REST nesta página em um ambiente de desenvolvimento local, use as credenciais fornecidas para a CLI gcloud.

      Instale a Google Cloud CLI e inicialize-a executando o seguinte comando:

      gcloud init

Restrições

  • Disponível apenas para volumes de Persistent Disk do tipo SSD.
  • É possível criar um volume de disco permanente no modo de vários gravadores em qualquer zona, mas só é possível anexá-lo às VMs nos seguintes locais:
    • australia-southeast1
    • europe-west1
    • us-central1 (somente zonas us-central1-a e us-central1-c)
    • us-east1 (apenas para a zona us-east1-d)
    • us-west1 (somente zonas us-west1-b e us-west1-c)
  • As instâncias anexadas precisam ter um tipo de máquina N2.
  • Tamanho mínimo: 10 GB
  • Máximo de VMs anexadas: 2
  • Os volumes do Persistent Disk no modo com vários gravadores não são compatíveis com as métricas do Persistent Disk.
  • Não é possível mudar discos que estejam no modo de vários gravadores para o modo somente leitura.
  • Não é possível usar imagens de disco ou snapshots para criar volumes do Persistent Disk no modo de vários gravadores.
  • Não é possível criar snapshots ou imagens a partir de volumes do Persistent Disk no modo de vários gravadores.
  • Limites menores de IOPS. Consulte o desempenho do disco para saber detalhes.
  • Não é possível redimensionar um volume de disco permanente de vários gravadores.
  • Ao criar uma VM usando a Google Cloud CLI, não é possível criar um volume de disco permanente de vários gravadores com a sinalização --create-disk.

Práticas recomendadas

  • O encapsulamento de E/S usando os comandos de SCSI PR resulta em um estado consistente de falha dos dados do disco permanente. Alguns sistemas de arquivos não têm consistência de falhas e, portanto, poderão ficar corrompidos se você usar comandos SCSI PR.
  • Muitos sistemas de arquivos, como EXT4, XFS e NTFS, não são projetados para ser usados com armazenamento em blocos compartilhado e não têm mecanismos para sincronizar ou executar operações originadas de várias instâncias de VM.
  • Antes de usar os volumes do Persistent Disk no modo de vários gravadores, entenda o sistema de arquivos e como ele pode ser usado com segurança com armazenamento em blocos compartilhado e acesso simultâneo de várias VMs.

Performance

Os volumes de discos permanentes criados no modo de várias gravações têm limites de capacidade e de IOPS específicos.

Modo de vários gravadores para Discos permanentes SSD zonais
IOPS máximas sustentadas
IOPS de leitura por GB 30
IOPS de gravação por GB 30
IOPS de leitura por instância 15.000–100.000*
IOPS de gravação por instância 15.000–100.000*
Capacidade sustentada máxima (MB/s)
Capacidade de leitura por GB 0,48
Capacidade de gravação por GB 0,48
Capacidade de leitura por instância 240–1.200*
Capacidade de gravação por instância 240–1.200*
* O desempenho das IOPS e da capacidade do disco permanente depende do tamanho do disco, do número de vCPUs da instância e do tamanho do bloco de E/S, entre outros fatores.
A anexação de um disco de vários gravadores a várias instâncias de máquina virtual não afeta o desempenho ou o custo agregado. Cada máquina recebe uma parcela do limite de desempenho por disco.

Para saber como compartilhar discos permanentes entre várias VMs, consulte Compartilhar discos permanentes entre VMs.

Compartilhar um volume de disco permanente zonal entre instâncias de VM

Nesta seção, explicamos os diferentes métodos para compartilhar volumes de discos permanentes zonais entre várias VMs.

Compartilhar um disco no modo somente leitura entre várias instâncias

É possível anexar um volume de disco permanente que não seja de inicialização a mais de uma VM no modo somente leitura. Isso permite o compartilhamento de dados estáticos entre várias VMs. O compartilhamento de dados estáticos entre várias VMs de um volume de disco permanente é mais barato do que replicar os dados em discos exclusivos para VMs individuais.

Se for necessário compartilhar espaço de armazenamento dinâmico entre várias VMs, use uma das seguintes opções:

Console

  1. No console do Google Cloud, acesse a página Instâncias de VMs.

    Acessar instâncias de VM

  2. Na lista de VMs do projeto, clique no nome da VM em que você quer anexar o disco. A página Detalhes da instância de VM será aberta.

  3. Na página de detalhes da instância, clique em Editar.

  4. Na seção Discos adicionais, clique em uma das opções a seguir:

    1. Adicionar um disco para adicionar um disco no modo somente leitura à VM.
    2. Anexe o disco atual para selecionar um disco atual e anexá-lo no modo somente leitura à VM.
  5. Especifique outras opções para seu disco.

  6. Clique em Concluído para aplicar as alterações.

  7. Clique em Salvar para aplicar as mudanças à VM.

  8. Conecte a VM e ative o disco.

  9. Repita este processo para adicionar o disco a outras VMs em modo somente leitura.

gcloud

Na CLI gcloud, use o comando compute instances attach-disk e especifique a sinalização --mode com a opção ro.

gcloud compute instances attach-disk INSTANCE_NAME \
  --disk DISK_NAME \
  --mode ro

Substitua:

  • INSTANCE_NAME: o nome da VM a que você quer anexar o volume zonal do disco permanente
  • DISK_NAME: o nome do disco que você quer anexar.

Depois de anexar o disco, conecte-se à VM e monte-o.

Repita este comando para cada VM onde quer adicionar esse disco no modo somente leitura.

Java

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


import com.google.cloud.compute.v1.AttachDiskInstanceRequest;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class AttachDisk {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "your-project-id";

    // Name of the zone in which the instance you want to use resides.
    String zone = "zone-name";

    // Name of the compute instance you want to attach a disk to.
    String instanceName = "instance-name";

    // Full or partial URL of a persistent disk that you want to attach. This can be either
    // be a regional or zonal disk.
    // Valid formats:
    //     * https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/disks/{disk_name}
    //     * /projects/{project}/zones/{zone}/disks/{disk_name}
    //     * /projects/{project}/regions/{region}/disks/{disk_name}
    String diskLink = String.format("/projects/%s/zones/%s/disks/%s",
        "project", "zone", "disk_name");

    // Specifies in what mode the disk will be attached to the instance. Available options are
    // `READ_ONLY` and `READ_WRITE`. Disk in `READ_ONLY` mode can be attached to
    // multiple instances at once.
    String mode = "READ_ONLY";

    attachDisk(projectId, zone, instanceName, diskLink, mode);
  }

  // Attaches a non-boot persistent disk to a specified compute instance.
  // The disk might be zonal or regional.
  // You need following permissions to execute this action:
  // https://cloud.google.com/compute/docs/disks/regional-persistent-disk#expandable-1
  public static void attachDisk(String projectId, String zone, String instanceName, String diskLink,
      String mode)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      AttachDiskInstanceRequest attachDiskInstanceRequest = AttachDiskInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstance(instanceName)
          .setAttachedDiskResource(AttachedDisk.newBuilder()
              .setSource(diskLink)
              .setMode(mode)
              .build())
          .build();

      Operation response = instancesClient.attachDiskAsync(attachDiskInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Attach disk failed! " + response);
        return;
      }
      System.out.println("Attach disk - operation status: " + response.getStatus());
    }
  }
}

Python

Python

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1

def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result

def attach_disk(
    project_id: str, zone: str, instance_name: str, disk_link: str, mode: str
) -> None:
    """
    Attaches a non-boot persistent disk to a specified compute instance. The disk might be zonal or regional.

    You need following permissions to execute this action:
    https://cloud.google.com/compute/docs/disks/regional-persistent-disk#expandable-1

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone:name of the zone in which the instance you want to use resides.
        instance_name: name of the compute instance you want to attach a disk to.
        disk_link: full or partial URL to a persistent disk that you want to attach. This can be either
            regional or zonal disk.
            Expected formats:
                * https://www.googleapis.com/compute/v1/projects/[project]/zones/[zone]/disks/[disk_name]
                * /projects/[project]/zones/[zone]/disks/[disk_name]
                * /projects/[project]/regions/[region]/disks/[disk_name]
        mode: Specifies in what mode the disk will be attached to the instance. Available options are `READ_ONLY`
            and `READ_WRITE`. Disk in `READ_ONLY` mode can be attached to multiple instances at once.
    """
    instances_client = compute_v1.InstancesClient()

    request = compute_v1.AttachDiskInstanceRequest()
    request.project = project_id
    request.zone = zone
    request.instance = instance_name
    request.attached_disk_resource = compute_v1.AttachedDisk()
    request.attached_disk_resource.source = disk_link
    request.attached_disk_resource.mode = mode

    operation = instances_client.attach_disk(request)

    wait_for_extended_operation(operation, "disk attachement")

REST

Na API, crie uma solicitação POST para o método compute.instances.attachDisk No corpo da solicitação, especifique o parâmetro mode como READ_ONLY.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/attachDisk

{
 "source": "zones/ZONE/disks/DISK_NAME",
 "mode": "READ_ONLY"
}

Substitua:

  • INSTANCE_NAME: o nome da VM a que você quer anexar o volume zonal do disco permanente
  • PROJECT_ID: ID do projeto;
  • ZONE: a zona onde o disco está localizado.
  • DISK_NAME: o nome do disco que você está anexando.

Depois de anexar o disco, conecte-se à VM e monte-o.

Repita esta solicitação para cada VM onde você quer adicionar esse disco no modo somente leitura.

Compartilhar um volume de disco permanente SSD no modo de vários gravadores entre as VMs

É possível compartilhar um volume de disco permanente SSD no modo de vários gravadores entre VMs N2 na mesma zona. Consulte Modo de vários gravadores em discos permanentes para detalhes sobre como ele funciona. Crie e anexe volumes do Persistent Disk com vários gravadores usando o seguinte processo:

gcloud

Crie e anexe um volume de disco permanente zonal usando a CLI gcloud:

  1. Use o comando gcloud beta compute disks create para criar um volume de disco permanente zonal. Inclua a sinalização --multi-writer para indicar que o disco precisa ser compartilhável entre as VMs no modo de vários gravadores.

    gcloud beta compute disks create DISK_NAME \
       --size DISK_SIZE \
       --type pd-ssd \
       --multi-writer
    

    Substitua:

    • DISK_NAME: o nome do novo disco
    • DISK_SIZE: o tamanho, em GB, do novo disco. Os tamanhos aceitáveis variam de 1 GB a 65.536 GB para volumes de disco permanente SSD ou de 200 GB a 65.536 GB para volumes de disco permanente padrão em vários gravadores mais recente.
  2. Depois de criar o disco, anexe-o a qualquer VM em execução ou parada com um tipo de máquina N2. Use o comando gcloud compute instances attach-disk:

    gcloud compute instances attach-disk INSTANCE_NAME \
       --disk DISK_NAME
    

    Substitua:

    • INSTANCE_NAME: o nome da VM N2 em que você está adicionando o novo volume zonal do Persistent Disk
    • DISK_NAME: o nome do novo disco que você está anexando à VM.
  3. Repita o comando gcloud compute instances attach-disk, mas substitua INSTANCE_NAME pelo nome da segunda VM.

Depois de criar e anexar um novo disco a uma VM, formate e monte o disco usando um sistema de arquivos de disco compartilhado. A maioria dos sistemas de arquivos não usa armazenamento compartilhado. Confirme se o sistema de arquivos é compatível com esses recursos antes de usá-los com o disco permanente de vários gravadores. Não é possível ativar o disco em várias VMs usando o mesmo processo que você normalmente usaria para ativar o disco em uma única VM.

REST

Use a API Compute Engine para criar e anexar um volume de disco permanente SSD às VMs N2 no modo de vários gravadores.

  1. Na API, crie uma solicitação POST para criar um volume de disco permanente zonal usando o método disks.insert. Inclua as propriedades name, sizeGb e type. Para criar esse novo disco como um disco que não será usado para inicialização e sem formatação, não especifique uma imagem ou um snapshot de origem para esse disco. Inclua a propriedade multiWriter com um valor True para indicar que o disco precisa ser compartilhável entre as VMs no modo de vários gravadores.

    POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/disks
    
    {
    "name": "DISK_NAME",
    "sizeGb": "DISK_SIZE",
    "type": "zones/ZONE/diskTypes/pd-ssd",
    "multiWriter": "True"
    }
    

    Substitua:

    • PROJECT_ID: ID do projeto
    • ZONE: a zona em que a VM e o novo disco estão localizados.
    • DISK_NAME: o nome do novo disco
    • DISK_SIZE: o tamanho, em GB, do novo disco. Os tamanhos aceitáveis variam de 1 GB a 65.536 GB para volumes de disco permanente SSD ou de 200 GB a 65.536 GB para volumes de disco permanente padrão em vários gravadores mais recente.
  2. Crie uma solicitação POST para o compute.instances.attachDiskmétodo e inclua o URL no Persistent Disk zonal que você acabou de criar.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/attachDisk
    
    {
    "source": "/compute/v1/projects/PROJECT_ID/zones/ZONE/disks/DISK_NAME"
    }
    

    Substitua:

    • PROJECT_ID: ID do projeto
    • ZONE: a zona em que a VM e o novo disco estão localizados.
    • INSTANCE_NAME: o nome da VM em que você está adicionando o novo volume do Persistent Disk.
    • DISK_NAME: o nome do novo disco
  3. Repita o comando disks.insert, mas especifique a segunda VM.

Depois de criar e anexar um novo disco a uma VM, formate e monte o disco usando um sistema de arquivos de disco compartilhado. A maioria dos sistemas de arquivos não usa armazenamento compartilhado. Confirme se o sistema de arquivos é compatível com esses recursos antes de usá-los com o Persistent Disk de vários gravadores.

A seguir