Volumes permanentes e provisionamento dinâmico

Nesta página, apresentamos uma visão geral de PersistentVolumes e PersistentVolumeClaims no Kubernetes e como eles são usados com o Google Kubernetes Engine (GKE). Nesta página, o foco é o armazenamento com discos permanentes do Compute Engine.

Volumes permanentes

Os recursos PersistentVolume são usados para gerenciar o armazenamento durável em um cluster. No GKE, os PersistentVolumes normalmente são usados com discos permanentes do Compute Engine. Eles também podem ser usados com outros tipos de armazenamento, como o NFS. O Filestore é uma solução NFS no Google Cloud. Para saber como configurar uma instância do Filestore como uma solução NFS PV para seus Clusters do GKE, consulte Como acessar compartilhamentos de arquivos dos clusters do Google Kubernetes Engine na documentação do Filestore.

Também é possível usar PersistentVolumes com o Cloud Volumes Service. Este produto é um serviço de armazenamento de dados baseado em nuvem totalmente gerenciado que oferece recursos avançados de gerenciamento de dados e desempenho altamente escalonável. Para ver exemplos, consulte Cloud Volumes Service para Google Cloud.

Ao contrário dos Volumes, o ciclo de vida dos PersistentVolumes é gerenciado pelo Kubernetes. Os PersistentVolumes podem ser provisionados dinamicamente. Não é preciso criar e excluir manualmente o armazenamento de apoio.

PersistentVolumes são recursos de cluster que existem independentemente dos pods. Isso significa que o disco e os dados representados por um PersistentVolume continuam existindo enquanto o cluster é alterado e os pods são excluídos e recriados. Os recursos PersistentVolume podem ser provisionados dinamicamente por meio de PersistentVolumeClaims ou podem ser explicitamente criados por um administrador de cluster.

Para saber mais sobre PersistentVolumes, consulte a documentação do Kubernetes.

PersistentVolumeClaims

Um PersistentVolumeClaim é uma solicitação e uma declaração de um PersistentVolume. Objetos PersistentVolumeClaim solicitam tamanho, modo de acesso e StorageClass específicos para o PersistentVolume. Se um PersistentVolume que satisfizer a solicitação existir ou puder ser provisionado, o PersistentVolumeClaim será associado a ele.

Os pods usam declarações como volumes. O cluster inspeciona a declaração para encontrar o volume vinculado e o monta para um pod.

A portabilidade é outra vantagem do uso de PersistentVolumes e PersistentVolumeClaims. É fácil usar a mesma especificação de pod em diferentes clusters e ambientes, já que o PersistentVolume é uma interface com o armazenamento de apoio real.

StorageClasses

Implementações de volume, como gcePersistentDisk, são configuradas por meio dos recursos StorageClass. O GKE cria para você um StorageClass padrão que usa o tipo de disco permanente padrão (ext4). O StorageClass padrão é usado quando um PersistentVolumeClaim não especifica um StorageClassName. É possível substituir o StorageClass padrão fornecido pelo seu.

Se você estiver usando um cluster com pools de nós do Windows, precisará criar um StorageClass e especificar um StorageClassName no PersistentVolumeClaim, porque o fstype padrão, ext4, não é compatível com o Windows. Se você estiver usando um disco permanente do Compute Engine, use o NTFS como o tipo de armazenamento de arquivos.

É possível criar seus próprios recursos do StorageClass para descrever diferentes classes de armazenamento. Por exemplo, as classes podem ser mapeadas para níveis de qualidade de serviço ou para políticas de backup. Esse conceito é algumas vezes chamado de "perfis" em outros sistemas de armazenamento.

Como provisionar PersistentVolumes dinamicamente

Na maioria das vezes, você não precisa configurar objetos PersistentVolume diretamente nem criar discos permanentes do Compute Engine. Em vez disso, é possível criar um PersistentVolumeClaim e o Kubernetes provisiona automaticamente um disco permanente para você.

O manifesto a seguir descreve uma solicitação para um disco de 30 gibibytes (GiB) com modo de acesso que permite que ele seja montado como leitura e gravação por um único nó:

# pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi

Quando você cria esse PersistentVolumeClaim com kubectl apply -f pvc-demo.yaml, o Kubernetes cria dinamicamente um objeto PersistentVolume correspondente. No exemplo a seguir, mostramos o PersistentVolume criado.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  uid: ced478c1-695a-11ea-a3da-42010a800003
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 30Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-demo
    uid: cd3fd5e9-695a-11ea-a3da-42010a800003
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cluster-1-pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - us-central1-c
        - key: topology.kubernetes.io/region
          operator: In
          values:
          - us-central1
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard
  volumeMode: Filesystem
status:
  phase: Bound

Se você não substituiu a classe de armazenamento padrão do GKE, esse PersistentVolume é respaldado por um disco permanente novo e vazio do Compute Engine. Para usar esse disco em um pod, utilize a declaração como um volume (em inglês). Quando você exclui uma declaração, o objeto PersistentVolume correspondente e o disco permanente provisionado do Compute Engine também são excluídos.

Defina a política de reivindicação do recurso PersistentVolume ou do recurso StorageClass dele como Retain para evitar a exclusão de discos permanentes provisionados dinamicamente. Nesse caso, você será cobrado pelo tempo que o disco permanente existir, mesmo que não haja nenhum PersistentVolumeClaim consumindo-o. Para ver exemplos sobre como alterar a política de reivindicação, consulte Alterar a política de reivindicação de um PersistentVolume. e StorageClass Resource.

Meios de acesso

Os PersistentVolumes são compatíveis com os meios de acesso a seguir:

  • ReadWriteOnce: o volume pode ser montado como leitura-gravação por um único nó.
  • ReadOnlyMany: o volume pode ser montado somente para leitura por muitos nós.
  • ReadWriteMany: o volume pode ser montado como leitura-gravação por muitos nós. Os PersistentVolumes que são respaldados pelos discos permanentes do Compute Engine não são compatíveis com esse meio de acesso.

Como usar discos permanentes do Compute Engine como ReadOnlyMany

ReadWriteOnce é o caso de uso mais comum para discos permanentes e funciona como o meio de acesso padrão para a maioria dos aplicativos. Os discos permanentes do Compute Engine também são compatíveis com o modo ReadOnlyMany, para que muitos aplicativos ou muitas réplicas do mesmo aplicativo consumam o mesmo disco ao mesmo tempo. Um exemplo de caso de uso é a disponibilização de conteúdo estático em várias réplicas.

Consulte este artigo para instruções sobre como criar discos permanentes para vários leitores.

Como usar discos permanentes preexistentes como PersistentVolumes

Os PersistentVolumes provisionados dinamicamente estão vazios quando são criados. Se você tiver um disco permanente existente do Compute Engine preenchido com dados, poderá apresentá-lo ao seu cluster criando manualmente um recurso PersistentVolume correspondente. O disco permanente precisa estar na mesma [zona] que os nós do cluster.

Consulte este exemplo de como criar um volume permanente respaldado por um disco permanente preexistente.

Implantações vs. StatefulSets

É possível usar modelos de PersistentVolumeClaims ou VolumeClaim em controladores de nível superior, como Implantações ou StatefulSets, respectivamente.

As implantações foram projetadas para aplicativos sem estado, de modo que todas as réplicas de uma implantação compartilhem o mesmo PersistentVolumeClaim. Como os pods de réplica criados são idênticos, somente os volumes com os modos ReadOnlyMany ou ReadWriteMany podem funcionar nessa configuração.

As implantações com uma réplica que usa um volume ReadWriteOnce também não são recomendadas. Afinal a estratégia de implantação padrão cria um segundo pod antes de desativar o primeiro pod em uma recriação. A implantação pode falhar no impasse, já que o segundo pod não pode ser iniciado porque o volume ReadWriteOnce já está em uso, e o primeiro pod não será removido porque o segundo pod ainda não foi iniciado. Em vez disso, use um StatefulSet com volumes ReadWriteOnce.

StatefulSets são o método recomendado para implantar aplicativos com estado que exigem um volume exclusivo por réplica. Ao usar StatefulSets com modelos PersistentVolumeClaim, você tem aplicativos capazes fazer o escalonamento vertical automaticamente com PersistentVolumesClaims exclusivos que estão associados a cada pod de réplica.

Discos permanentes regionais

Os discos permanentes regionais são recursos multizonais que replicam dados entre duas zonas na mesma região e podem ser usados de maneira semelhante aos discos permanentes zonais. No caso de uma falha zonal ou se os nós do cluster de uma zona não puderem ser programados, o Kubernetes poderá usar o volume para fazer o failover das cargas de trabalho para a outra zona. É possível usar discos permanentes regionais para criar soluções altamente disponíveis para cargas de trabalho com estado no GKE. É preciso garantir que as zonas principal e de failover estejam configuradas com capacidade de recursos suficiente para executar a carga de trabalho.

Os Discos permanentes SSD regionais são uma opção para aplicativos, como bancos de dados, que exigem disponibilidade e desempenho altos. Para mais detalhes, consulte Comparação de desempenho do armazenamento em blocos.

Como ocorre com os discos permanentes zonais, os discos permanentes regionais podem ser provisionados dinamicamente conforme necessário ou provisionados manualmente com antecedência pelo administrador do cluster. Para saber como adicionar discos permanentes regionais, consulte Como provisionar discos permanentes regionais.

Zonas em discos permanentes

Os discos permanentes zonais são recursos zonais, e os discos permanentes regionais são recursos multizonais. Quando você adiciona armazenamento permanente ao cluster, o GKE atribui o disco a uma única zona, a menos que ela seja especificada. O GKE escolhe a zona aleatoriamente. Após o provisionamento de um disco permanente, quaisquer pods que façam referência a ele são programados para a mesma zona do disco.

Se você provisionar dinamicamente um disco permanente no cluster, recomendamo definir o modo de vinculação de volume WaitForFirstConsumer (em inglês) na sua StorageClass. Essa configuração instrui o Kubernetes a provisionar um disco permanente na mesma zona para a qual o pod é programado. Ele respeita as restrições de programação do pod, como as antiafinidades (em inglês) e os seletores de nós. A antiafinidade nas zonas permite que os pods do StatefulSet sejam distribuídos entre as zonas com os discos correspondentes.

Veja a seguir uma StorageClass de exemplo para provisionar discos permanentes zonais que definem WaitForFirstConsumer:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  fstype: ext4
volumeBindingMode: WaitForFirstConsumer

Para ver um exemplo usando discos permanentes regionais, consulte Como provisionar discos permanentes regionais.

A seguir