Essa é a versão completa de impressão dessa seção Clique aqui para imprimir.
Armazenamento
1 - Volumes
Os arquivos em disco em um contêiner são efêmeros, o que apresenta alguns problemas para
aplicações não triviais quando executadas em contêineres. Um problema é a perda de arquivos
quando um contêiner quebra. O kubelet reinicia o contêiner, mas em um estado limpo. Um segundo
problema ocorre ao compartilhar arquivos entre contêineres que são executados juntos em
um Pod
. A abstração de volume
do Kubernetes resolve ambos os problemas. Sugere-se familiaridade com Pods .
Contexto
Docker tem um conceito de volumes, embora seja um pouco mais simples e menos gerenciado. Um volume Docker é um diretório em disco ou em outro contêiner. O Docker oferece drivers de volume, mas a funcionalidade é um pouco limitada.
O Kubernetes suporta muitos tipos de volumes. Um Pod é capaz de utilizar qualquer quantidade de tipos de volumes simultaneamente. Os tipos de volume efêmeros têm a mesma vida útil do pod, mas os volumes persistentes existem além da vida útil de um pod. Quando um pod deixa de existir, o Kubernetes destrói volumes efêmeros; no entanto, o Kubernetes não destrói volumes persistentes. Para qualquer tipo de volume em um determinado pod, os dados são preservados entre as reinicializações do contêiner.
Em sua essência, um volume é um diretório, eventualmente com alguns dados dentro dele, que é acessível aos contêineres de um Pod. Como esse diretório vem a ser, o meio que o suporta e o conteúdo do mesmo são determinados pelo tipo particular de volume utilizado.
Para utilizar um volume, especifique os volumes que serão disponibilizados para o Pod em .spec.volumes
e declare onde montar esses volumes dentro dos contêineres em .spec.containers[*].volumeMounts
. Um processo em um contêiner enxerga uma visualização do sistema de arquivos composta pelo do conteúdo inicial da imagem do contêiner mais os volumes (se definidos) montados dentro do contêiner. O processo enxerga um sistema de arquivos raiz que inicialmente corresponde ao conteúdo da imagem do contêiner. Qualquer gravação dentro dessa hierarquia do sistema de arquivos, se permitida, afetará o que esse processo enxerga quando ele executa um acesso subsequente ao sistema de arquivos. Os volumes são montados nos caminhos especificados dentro da imagem. Para cada contêiner definido em um Pod, você deve especificar independentemente onde montar cada volume utilizado pelo contêiner.
Volumes não podem ser montados dentro de outros volumes (mas você pode consultar Utilizando subPath para um mecanismo relacionado). Além disso, um volume não pode conter um link físico para qualquer outro dado em um volume diferente.
Tipos de Volumes
Kubernetes suporta vários tipos de volumes.
awsElasticBlockStore
Um volume awsElasticBlockStore
monta um volume EBS da Amazon Web Services (AWS) em seu pod. Ao contrário do emptyDir
que é apagado quando um pod é removido, o conteúdo de um volume EBS é preservado e o volume é desmontado. Isto significa que um volume EBS pode ser previamente populado com dados e que os dados podem ser compartilhados entre Pods.
aws ec2 create-volume
ou pela API da AWS antes que você consiga utilizá-lo.Existem algumas restrições ao utilizar um volume awsElasticBlockStore
:
- Os nós nos quais os Pods estão sendo executados devem ser instâncias AWS EC2
- Estas instâncias devem estar na mesma região e na mesma zona de disponibilidade que o volume EBS
- O EBS suporta montar um volume em apenas uma única instância EC2
Criando um volume AWS EBS
Antes de poder utilizar um volume EBS com um pod, precisa criá-lo.
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
Certifique-se de que a zona corresponde à mesma zona em que criou o cluster. Verifique se o tamanho e o tipo de volume EBS são adequados para a sua utilização.
Exemplo de configuração do AWS EBS
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# Esse volume AWS EBS já deve existir.
awsElasticBlockStore:
volumeID: "<volume id>"
fsType: ext4
Se o volume EBS estiver particionado, é possível informar o campo opcional partition: "<partition em umber>"
para especificar em que partição deve ser montado.
Migração de CSI do AWS EBS
Kubernetes v1.17 [beta]
Quando o recurso CSIMigration
para awsElasticBlockStore
está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o driver Cointainer Storage Interface (CSI) ebs.csi.aws.com
. Para usar esse recurso, o driver CSI AWS EBS deve estar instalado no cluster e os recursos beta CSIMigration
e CSIMigrationAWS
devem estar ativados.
Migração CSI AWS EBS concluída
Kubernetes v1.17 [alpha]
Para desabilitar o carregamento do plugin de armazenamento awsElasticBlockStore
pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAWSUnregister
como true
.
azureDisk
O tipo de volume azureDisk
monta um Disco de Dados Microsoft Azure em um pod.
Para obter mais detalhes, consulte plugin de volume azureDisk
.
Migração de CSI do azureDisk
Kubernetes v1.19 [beta]
Quando o recurso CSIMigration
para azureDisk
está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o Driver de Cointêiner Storage Interface (CSI) disk.csi.azure.com
. Para utilizar este recurso, o Driver CSI Azure Disk deve estar instalado no cluster e os recursos CSIMigration
e CSIMigrationAzureDisk
devem estar ativados.
Migração CSI azureDisk concluída
Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento azureDisk
pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAzureDiskUnregister
como true
.
azureFile
O tipo de volume azureFile
monta um volume de arquivo Microsoft Azure (SMB 2.1 e 3.0) em um pod.
Para obter mais detalhes, consulte plugin de volume azureFile
.
Migração de CSI azureFile
Kubernetes v1.21 [beta]
Quando o recurso CSIMigration
para azureFile
está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o Driver de Cointainer Storage Interface (CSI) file.csi.azure.com
. Para utilizar este recurso, o Driver CSI do Azure Disk deve estar instalado no cluster e as feature gates CSIMigration
e CSIMigrationAzureFile
devem estar habilitadas.
O driver de CSI do Azure File não oferece suporte ao uso do mesmo volume por fsgroups diferentes, se a migração de CSI Azurefile estiver habilitada, o uso do mesmo volume por fsgroups diferentes não será suportado.
Migração do CSI azureFile concluída
Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento azureFile
pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAzureFileUnregister
como true
.
cephfs
Um volume cephfs
permite que um volume CephFS existente seja montado no seu Pod. Ao contrário do emptyDir
que é apagado quando um pod é removido, o conteúdo de um volume cephfs
é preservado e o volume é simplesmente desmontado. Isto significa que um volume cephfs
pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods. O volume cephfs
pode ser montado por vários gravadores simultaneamente.
Consulte o exemplo CephFS para mais detalhes.
cinder
O tipo de volume cinder
é utilizado para montar o volume do OpenStack Cinder no seu pod.
Exemplo de configuração de volume Cinder
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-cinder-container
volumeMounts:
- mountPath: /test-cinder
name: test-volume
volumes:
- name: test-volume
# Esse volume OpenStack já deve existir.
cinder:
volumeID: "<volume id>"
fsType: ext4
Migração de CSI OpenStack
Kubernetes v1.21 [beta]
O recurso CSIMigration
para o Cinder é ativado por padrão no Kubernetes 1.21. Ele redireciona todas as operações de plugin do tipo in-tree para o Driver de Cointainer Storage Interface (CSI) cinder.csi.openstack.org
. O Driver CSI OpenStack Cinder tem de estar instalado no cluster. Você pode desativar a migração Cinder CSI para o seu cluster definindo a feature gate CSIMigrationOpenStack
como false
. Se você desativar o recurso CSIMigrationOpenStack
, o plugin de volume in-tree do Cinder assume a responsabilidade por todos os aspectos do gerenciamento de armazenamento de volume do Cinder.
configMap
Um ConfigMap oferece uma forma de injetar dados de configuração em Pods. Os dados armazenados em um ConfigMap podem ser referenciados em um volume de tipo configMap
e depois consumidos por aplicações conteinerizadas executadas em um pod.
Ao referenciar um ConfigMap, você informa o nome do ConfigMap no volume. Pode personalizar o caminho utilizado para uma entrada específica no ConfigMap. A seguinte configuração mostra como montar o log-config
do ConfigMap em um Pod chamado configmap-pod
:
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
O ConfigMap log-config
é montado como um volume e todos os conteúdos armazenados em sua entrada log_level
são montados no Pod através do caminho /etc/config/log_level
. Observe que esse caminho é derivado do volume mountPath
e do path
configurado com log_level
.
É preciso criar um ConfigMap antes de usá-lo.
Um contêiner que utiliza ConfigMap através de um ponto de montagem com a propriedade
subPath
não receberá atualizações deste ConfigMap.Os dados de texto são expostos como arquivos utilizando a codificação de caracteres UTF-8. Para outras codificações de caracteres, use
binaryData
.
downwardAPI
Um volume downwardAPI
disponibiliza dados da downward API para as aplicações. Ele monta um diretório e grava os dados solicitados em arquivos de texto sem formatação.
subPath
não receberá atualizações desta downward API.Consulte o exemplo de downward API para obter mais detalhes.
emptyDir
Um volume emptyDir
é criado pela primeira vez quando um Pod é atribuído a um nó e existe enquanto esse Pod estiver sendo executado nesse nó. Como o nome diz, o volume emptyDir
está inicialmente vazio. Todos os contêineres no Pod podem ler e gravar os mesmos arquivos no volume emptyDir
, embora esse volume possa ser montado no mesmo caminho ou em caminhos diferentes em cada contêiner. Quando um Pod é removido de um nó por qualquer motivo, os dados no emptyDir
são eliminados permanentemente.
emptyDir
são mantidos em caso de falha do contêiner.Alguns usos para um emptyDir
são:
- espaço temporário, como para uma merge sort baseado em disco
- ponto de verificação de um processamento longo para recuperação de falhas
- manter arquivos que um contêiner gerenciador de conteúdo busca enquanto um contêiner de webserver entrega os dados
Dependendo do seu ambiente, os volumes emptyDir
são armazenados em qualquer mídia que componha o nó, como disco ou SSD, ou armazenamento de rede. No entanto, se você definir o campo emptyDir.medium
como "Memory"
, o Kubernetes monta um tmpfs (sistema de arquivos com suporte de RAM) para você. Embora o tmpfs seja muito rápido, tenha em atenção que, ao contrário dos discos, o tmpfs é limpo na reinicialização do nó e quaisquer arquivos que grave consomem o limite de memória do seu contêiner.
SizeMemoryBackedVolumes
estiver habilitada, é possível especificar um tamanho para volumes mantidos em memória. Se nenhum tamanho for especificado, os volumes mantidos em memória são dimensionados para 50% da memória em um host Linux.Exemplo de configuração emptyDir
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
fc (fibre channel)
Um tipo de volume fc
permite que um volume de armazenamento de fibre channel existente seja montado em um Pod. Você pode especificar um ou vários WWNs usando o parâmetro targetWWNs
em sua configuração de volume. Se forem especificados vários WWNs, o targetWWNs espera que esses WWNs sejam de conexões multipath.
Consulte o exemplo de fibre channel para obter mais detalhes.
flocker (descontinuado)
Flocker é um gerenciador de volumes de dados de contêineres em cluster de código aberto. O Flocker oferece gerenciamento e orquestração de volumes de dados suportados por uma variedade de backends de armazenamento.
Um volume flocker
permite que um conjunto de dados Flocker seja montado em um Pod. Se o conjunto de dados ainda não existir no Flocker, ele precisará ser criado primeiro com o CLI do Flocker ou usando a API do Flocker. Se o conjunto de dados já existir, ele será anexado pelo Flocker ao nó que o pod está escalonado. Isto significa que os dados podem ser compartilhados entre os Pods, conforme necessário.
Consulte exemplo do Flocker para obter mais detalhes.
gcePersistentDisk
Um volume gcePersistentDisk
monta um disco persistente (PD) do Google Compute Engine (GCE) no seu Pod. Ao contrário do emptyDir
que é apagado quando um pod é removido, o conteúdo de um PD é preservado e o volume é simplesmente desmontado. Isto significa que um PD pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
gcloud
, ou via GCE API ou via UI antes de poder utilizá-lo.Existem algumas restrições ao utilizar um gcePersistentDisk
:
- Os nós nos quais os Pods estão sendo executados devem ser VMs GCE
- Essas VMs precisam estar no mesmo projeto e zona GCE que o disco persistente
Uma característica do disco persistente GCE é o acesso simultâneo somente leitura a um disco persistente. Um volume gcePersistentDisk
permite que vários consumidores montem simultaneamente um disco persistente como somente leitura. Isto significa que é possível alimentar previamente um PD com o seu conjunto de dados e, em seguida, disponibilizá-lo em paralelo a quantos Pods necessitar. Infelizmente, os PDs só podem ser montados por um único consumidor no modo de leitura e escrita. Não são permitidos gravadores simultâneos.
O uso de um disco persistente GCE com um Pod controlado por um ReplicaSet falhará, a menos que o PD seja somente leitura ou a contagem de réplica seja 0 ou 1.
Criando um disco persistente GCE
Antes de poder utilizar um disco persistente GCE com um Pod, é necessário criá-lo.
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
Exemplo de configuração de disco persistente GCE
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# Esse Disco Persistente (PD) GCE já deve existir.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
Discos persistentes regionais
O recurso de Discos persistentes regionais permite a criação de discos persistentes que estão disponíveis em duas zonas dentro da mesma região. Para usar esse recurso, o volume deve ser provisionado como PersistentVolume; referenciar o volume diretamente a partir de um pod não é uma configuração suportada.
Provisionar manualmente um PersistentVolume PD Regional
O provisionamento dinâmico é possível usando uma StorageClass para GCE PD. Antes de criar um PersistentVolume, você deve criar o disco persistente:
gcloud compute disks create --size=500GB my-data-disk
--region us-central1
--replica-zones us-central1-a,us-central1-b
Exemplo de configuração de disco persistente regional
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
# failure-domain.beta.kubernetes.io/zone deve ser usado para versões anteriores à 1.21
- key: topology.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-b
Migração do CSI GCE
Kubernetes v1.17 [beta]
Quando o recurso CSIMigration
para o GCE PD é habilitado, todas as operações de plugin do plugin in-tree existente são redirecionadas para o Driver de Cointainer Storage Interface (CSI) pd.csi.storage.gke.io
. Para utilizar este recurso, o Driver CSI GCE PD deve ser instalado no cluster e os recursos beta CSIMigration
e CSIMigrationGCE
devem estar habilitados.
Migração de CSI GCE concluída
Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento gcePersistentDisk
pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginGCEUnregister
como true
.
gitRepo (descontinuado)
gitRepo
foi descontinuado. Para provisionar um contêiner com um repositório git , monte um EmptyDir em um InitContainer que clone o repositório usando git, depois monte o EmptyDir no contêiner do Pod.Um volume gitRepo
é um exemplo de um plugin de volume. Este plugin monta um diretório vazio e clona um repositório git neste diretório para que seu Pod utilize.
Aqui está um exemplo de um volume gitRepo
:
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs
Um volume glusterfs
permite que um volume Glusterfs (um sistema de arquivos em rede de código aberto) seja montado no seu Pod. Ao contrário do emptyDir
que é apagado quando um Pod é removido, o conteúdo de um volume glusterfs
é preservado e o volume é simplesmente desmontado. Isto significa que um volume glusterfs pode ser previamente populado com dados e que os dados podem ser compartilhados entre Pods. O GlusterFS pode ser montado para escrita por vários pods simultaneamente.
Consulte o exemplo do GlusterFS para obter mais detalhes.
hostPath
Os volumes HostPath apresentam muitos riscos de segurança e é uma prática recomendada evitar o uso de HostPaths quando possível. Quando um volume HostPath precisa ser usado, ele deve ser definido com escopo apenas para o arquivo ou diretório necessário e montado como ReadOnly.
Se você restringir o acesso do HostPath a diretórios específicos através da AdmissionPolicy, a propriedade volumeMounts
DEVE obrigatoriamente usar pontos de montagem readOnly
para que a política seja eficaz.
Um volume hostPath
monta um arquivo ou diretório do sistema de arquivos do nó do host em seu Pod. Isto não é algo de que a maioria dos Pods irá precisar, mas oferece uma poderosa alternativa de escape para algumas aplicações.
Por exemplo, alguns usos para um hostPath
são:
- Executar um contêiner que necessita de acesso aos documentos internos do Docker; utilizar um
hostPath
apontando para/var/lib/docker
- Executando o cAdvisor em um contêiner; use um
hostPath
apontando para/sys
- Permitir que um Pod especifique se um dado
hostPath
deve existir antes de o Pod ser executado, se deve ser criado e como deve existir
Além da propriedade obrigatória path
, você pode opcionalmente definir um type
para um volume hostPath
.
Os valores suportados para o campo type
são:
Valor | Comportamento |
---|---|
A string vazia (padrão) é para compatibilidade com versões anteriores, o que significa que nenhuma verificação será executada antes de montar o volume hostPath. | |
DirectoryOrCreate | Se nada existir no caminho indicado, um diretório vazio será criado lá, conforme necessário, com permissão definida para 0755, tendo o mesmo grupo e propriedade com a Kubelet. |
Directory | Um diretório deve existir no caminho indicado |
FileOrCreate | Se não houver nada no caminho indicado, um arquivo vazio será criado lá, conforme necessário, com permissão definida para 0644, tendo o mesmo grupo e propriedade com Kubelet. |
File | Um arquivo deve existir no caminho indicado |
Socket | Um socket UNIX deve existir no caminho indicado |
CharDevice | Deve existir um dispositivo de caracteres no caminho indicado |
BlockDevice | Deve existir um dispositivo de bloco no caminho indicado |
Tenha cuidado ao utilizar este tipo de volume, porque:
- Os HostPaths podem expor as credenciais privilegiadas do sistema (como para o Kubelet) ou APIs privilegiadas (como o container runtime socket), que podem ser usadas para o explorar vulnerabilidades de escape do contêiner ou para atacar outras partes do cluster.
- Os Pods com configuração idêntica (como criado a partir de um PodTemplate) podem se comportar de forma diferente em nós diferentes devido a arquivos diferentes nos nós
- Os arquivos ou diretórios criados nos hosts subjacentes são graváveis apenas pelo root. Você precisa executar seu processo como root em um contêiner privilegiado ou modificar as permissões de arquivo no host para poder gravar em um volume
hostPath
Exemplo de configuração do hostPath
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# localização do diretório no host
path: /data
# este campo é opcional
type: Directory
FileOrCreate
não cria o diretório onde ficará arquivo. Se o caminho de diretório do arquivo montado não existir, o pod não será iniciado. Para garantir que esse modo funcione, você pode tentar montar diretórios e arquivos separadamente, como mostrado em configuração FileOrCreate
.Exemplo de configuração FileOrCreate do hostPath
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: k8s.gcr.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Certifique-se de que o diretório foi criado.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
iscsi
Um volume iscsi
permite que um volume iSCSI (SCSI sobre IP) existente seja montado no seu Pod. Ao contrário do emptyDir
que é apagado quando um Pod é removido, o conteúdo de um volume iscsi
é preservado e o volume é simplesmente desmontado. Isto significa que um volume iscsi pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Uma característica do iSCSI é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo para tantos Pods quanto necessitar. Infelizmente, os volumes iSCSI só podem ser montados por um único consumidor no modo de leitura-escrita. Não são permitidos gravadores simultâneos.
Consulte o exemplo iSCSI para obter mais detalhes.
local
Um volume local
representa um dispositivo de armazenamento local montado, como um disco, partição ou diretório.
Os volumes locais só podem ser usados como um PersistentVolume criado estaticamente. O provisionamento dinâmico não é suportado.
Em comparação com volumes hostPath
, os volumes local
são usados de forma durável e portátil, sem escalonamento manual dos Pods para os nós. O sistema está ciente das restrições de nós do volume, observando a afinidade do nó com o PersistentVolume.
No entanto, os volumes local
estão sujeitos à disponibilidade do nó que o comporta e não são adequados para todas as aplicações. Se um nó não está íntegro, então o volume local
torna-se inacessível pelo pod. O pod que utiliza este volume não consegue ser executado. Os aplicativos que usam volumes local
devem ser capazes de tolerar essa disponibilidade reduzida, bem como uma possível perda de dados, dependendo das caraterísticas de durabilidade do disco subjacente.
O exemplo a seguir mostra um PersistentVolume usando um volume local
e nodeAffinity
:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
É preciso definir a propriedade nodeAffinity
do PersistentVolume ao utilizar volumes local
. O escalonador do Kubernetes usa o PersistentVolume nodeAffinity
para escalonar esses pods para o nó correto.
A propriedade volumeMode
do PersistentVolume pode ser definida como "Block" (ao invés do valor padrão "Filesystem") para expor o volume local como um dispositivo de bloco bruto.
Ao usar volumes locais, é recomendável criar uma StorageClass com a propriedade volumeBindingMode
definida como WaitForFirstConsumer
. Para obter mais detalhes, consulte o exemplo local StorageClass. A postergação da vinculação do volume garante que a decisão de vinculação da PersistentVolumeClaim também será avaliada com quaisquer outras restrições de nós que o Pod possa ter, tais como requisitos de recursos de nós, seletores de nós, afinidade do Pod e anti afinidade do Pod.
Um provisionador estático externo pode ser executado separadamente para uma melhor gestão do ciclo de vida do volume local. Observe que este provisionador ainda não suporta o provisionamento dinâmico. Para um exemplo sobre como executar um provisionador local externo, veja o manual do usuário do provisionador local do volume.
nfs
Um volume nfs
permite que um compartilhamento NFS (Network File System) existente seja montado em um Pod. Ao contrário do emptyDir
que é apagado quando um Pod é removido, o conteúdo de um volume nfs
é preservado e o volume é simplesmente desmontado. Isto significa que um volume NFS pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods. O NFS pode ser montado por vários gravadores simultaneamente.
Consulte o exemplo NFS para obter mais detalhes.
persistentVolumeClaim
Um volume persistentVolumeClaim
é usado para montar um PersistentVolume em um Pod. PersistentVolumeClaims são uma forma de os usuários "solicitarem" armazenamento durável (como um GCE PersistentDisk ou um volume iSCSI) sem conhecerem os detalhes do ambiente de nuvem em particular.
Consulte as informações sobre PersistentVolumes para obter mais detalhes.
portworxVolume
Um portworxVolume
é uma camada de armazenamento em bloco extensível que funciona hiperconvergente com Kubernetes. O Portworx tira as impressões digitais de um armazenamento em um servidor, organiza com base nas capacidades e agrega capacidade em múltiplos servidores. Portworx funciona em máquinas virtuais ou em nós Linux bare-metal.
Um portworxVolume
pode ser criado dinamicamente através do Kubernetes ou também pode ser previamente provisionado e referenciado dentro de um Pod. Aqui está um exemplo de um Pod referenciando um volume Portworx pré-provisionado:
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# Este volume Portworx já deve existir.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
pxvol
antes de usá-lo no Pod.Para obter mais detalhes, consulte os exemplos de volume Portworx .
projetado
Um volume projetado mapeia várias fontes de volume existentes dentro do mesmo diretório. Para obter mais detalhes, consulte Volumes projetados.
quobyte (descontinuado)
Um Volume quobyte
permite que um volume Quobyte existente seja montado no seu Pod.
Quobyte oferece suporte para o Container Storage Interface. CSI é o plugin recomendado para usar volumes Quobyte dentro de Kubernetes. O projeto GitHub da Quobyte tem instruções para implantar o Quobyte usando o CSI, acompanhado de exemplos.
rbd
Um volume rbd
permite que um volume Rados Block Device (RBD) seja montado em seu Pod. Ao contrário do emptyDir
que é apagado quando um pod é removido, o conteúdo de um volume rbd
é preservado e o volume é desmontado. Isto significa que um volume RBD pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Uma caraterística do RBD é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo para tantos pods quanto necessitar. Infelizmente, os volumes RBD só podem ser montados por um único consumidor no modo de leitura-escrita. Não são permitidos gravadores simultâneos.
Consulte o exemplo RBD para obter mais detalhes.
Migração de CSI RBD
Kubernetes v1.23 [alpha]
Quando o recurso CSIMigration
do RBD
está ativado, redireciona todas as operações do plugin in-tree existente para o driver CSI rbd.csi.ceph.com
. Para utilizar este recurso, o driver Ceph CSI deve estar instalado no cluster e as feature gates CSIMigration
e csiMigrationRBD
devem estar habilitadas.
Como operador do cluster Kubernetes que administra o armazenamento, aqui estão os pré-requisitos que você deve atender antes de tentar a migração para o driver CSI RBD:
- Você deve instalar o driver Ceph CSI (
rbd.csi.ceph.com
), v3.5.0 ou superior, no cluster Kubernetes. - Considerando que o campo
clusterID
é um parâmetro necessário para o driver CSI e sua operação , mas o campo in-tree StorageClass tem o parâmetro obrigatóriomonitors
, um administrador de armazenamento Kubernetes precisa criar um clusterID baseado no hash dos monitores (ex.:#echo -n '<monitors_string>' | md5sum
) no mapa de configuração do CSI e manter os monitores sob esta configuração de clusterID. - Além disso, se o valor de
adminId
no Storageclass in-tree for diferente deadmin
, oadminSecretName
mencionado no Storageclass in-tree tem que ser corrigido com o valor base64 do valor do parâmetroadminId
, caso contrário esta etapa pode ser ignorada.
secret
Um volume secret
é usado para passar informações sensíveis, tais como senhas, para Pods. Você pode armazenar segredos na API Kubernetes e montá-los como arquivos para serem usados por pods sem necessidade de vinculação direta ao Kubernetes. Volumes secret
são mantidos pelo tmpfs (um sistema de arquivos com baseado em memória RAM) para que nunca sejam gravados em armazenamento não volátil.
subPath
não receberá atualizações deste Secret.Para obter mais detalhes, consulte Configurando Secrets.
storageOS (descontinuado)
Um volume storageos
permite que um volume StorageOS existente seja montado em seu Pod.
O StorageOS funciona como um contêiner dentro de seu ambiente Kubernetes, tornando o armazenamento local ou anexado acessível a partir de qualquer nó dentro do cluster Kubernetes. Os dados podem ser replicados para a proteção contra falhas do nó. O provisionamento e a compressão podem melhorar a utilização e reduzir os custos.
Em sua essência, o StorageOS fornece armazenamento em bloco para containers, acessível a partir de um sistema de arquivo.
O Conteiner StorageOS requer Linux de 64 bits e não possui dependências adicionais. Uma licença para desenvolvedores está disponível gratuitamente.
O exemplo a seguir é uma configuração do Pod com StorageOS:
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# O volume `redis-vol01` já deve existir dentro do StorageOS no namespace `default`.
volumeName: redis-vol01
fsType: ext4
Para obter mais informações sobre StorageOS, provisionamento dinâmico e PersistentVolumeClaims, consulte os exemplos do StorageOS.
vsphereVolume
Um vsphereVolume
é usado para montar um volume VMDK do vSphere em seu Pod. O conteúdo de um volume é preservado quando é desmontado. Ele suporta sistemas de armazenamento de dados tanto do tipo VMFS quanto do tipo VSAN.
Criar um volume VMDK
Escolha um dos seguintes métodos para criar um VMDK.
Primeiro acesse o ESX via ssh, depois use o seguinte comando para criar um VMDK:
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
Utilize o seguinte comando para criar um VMDK:
vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
Exemplo de configuração do VMDK no vSphere
apiVersion: v1
kind: Pod
metadata:
name: test-vmdk
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-vmdk
name: test-volume
volumes:
- name: test-volume
# This VMDK volume must already exist.
vsphereVolume:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
Para obter mais informações, consulte os exemplos de volume do vSphere .
Migração de CSI vSphere
Kubernetes v1.19 [beta]
Quando o recurso CSIMigration
do vsphereVolume
está ativado, redireciona todas as operações do plugin in-tree existente para o driver CSI csi.vsphere.vmware.com
. Para usar esse recurso, o driver CSI do vSphere deve estar instalado no cluster e as feature gates CSIMigration
e CSIMigrationvSphere
devem estar habilitadas.
Isso também requer que a versão mínima do vSphere vCenter/ESXi seja 7.0u1 e a versão mínima do hardware seja a VM versão 15.
Os seguintes parâmetros da StorageClass do plugin integrado vsphereVolume
não são suportados pelo driver CSI do vSphere:
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
Os volumes existentes criados usando esses parâmetros serão migrados para o driver CSI do vSphere, mas novos volumes criados pelo driver de CSI do vSphere não estarão respeitando esses parâmetros.
Migração do CSI do vSphere foi concluída
Kubernetes v1.19 [beta]
Para desativar o carregamento do plugin de armazenamento vsphereVolume
pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginvSphereUnregister
como true
. Você precisa instalar o driver csi.vsphere.vmware.com
CSI em todos os nós de processamento.
Migração de driver CSI do Portworx
Kubernetes v1.23 [alpha]
O recurso CSIMigration
para Portworx foi adicionado, mas desativado por padrão no Kubernetes 1.23 visto que está no estado alfa. Ele redireciona todas as operações de plugin do tipo in-tree para o Driver de Cointainer Storage Interface (CSI) pxd.portworx.com
. O driver CSI Portworx deve ser instalado no cluster. Para ativar o recurso, defina CSIMigrationPortworx=true
no kube-controller-manager e no kubelet.
Utilizando subPath
Às vezes, é útil compartilhar um volume para múltiplos usos em um único pod. A propriedade volumeMounts.subPath
especifica um sub caminho dentro do volume referenciado em vez de sua raiz.
O exemplo a seguir mostra como configurar um Pod com um ambiente LAMP (Linux, Apache, MySQL e PHP) usando um único volume compartilhado. Esta exemplo de configuração subPath
não é recomendada para uso em produção.
O código e os ativos da aplicação PHP mapeiam para a pasta do volume html
e o banco de dados MySQL é armazenado na pasta do volume mysql
. Por exemplo:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
Usando subPath com variáveis de ambiente expandidas
Kubernetes v1.17 [stable]
Use o campo subPathExpr
para construir nomes de diretório subPath
a partir de variáveis de ambiente da downward API. As propriedades subPath
e subPathExpr
são mutuamente exclusivas.
Neste exemplo, um Pod
usa subPathExpr
para criar um diretório pod1
dentro do volume hostPath
/var/log/pods
. O volume hostPath
recebe o nome Pod
do downwardAPI
. O diretório /var/log/pods/pod1
do host é montado em /logs
no contêiner.
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox:1.28
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
# A expansão de variáveis usa parênteses (não chaves).
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
Recursos
A mídia de armazenamento(como Disco ou SSD) de um volume emptyDir
é determinada por meio do sistema de arquivos que mantém o diretório raiz do kubelet (normalmente /var/lib/kubelet
). Não há limite para quanto espaço um volume emptyDir
ou hostPath
podem consumir, e não há isolamento entre contêineres ou entre pods.
Para saber mais sobre como solicitar espaço usando uma especificação de recursos, consulte como gerenciar recursos.
Plugins de volume out-of-tree
Os plugins de volume out-of-tree incluem o Container Storage Interface (CSI) e também o FlexVolume (que foi descontinuado). Esses plugins permitem que os fornecedores de armazenamento criem plugins de armazenamento personalizados sem adicionar seu código-fonte do plugin ao repositório Kubernetes.
Anteriormente, todos os plugins de volume eram "in-tree". Os plugins "in-tree" eram construídos, vinculados, compilados e distribuídos com o código principal dos binários do Kubernetes. Isto significava que a adição de um novo sistema de armazenamento ao Kubernetes (um plugin de volume) exigia uma validação do código no repositório central de código Kubernetes.
Tanto o CSI quanto o FlexVolume permitem que os plugins de volume sejam desenvolvidos independentemente da base de código Kubernetes e implantados (instalados) nos clusters Kubernetes como extensões.
Para fornecedores de armazenamento que procuram criar um plugin de volume out-of-tree, consulte as Perguntas mais frequentes sobre plugins de volume.
csi
O Cointainer Storage Interface (CSI) define uma interface padrão para sistemas de orquestração de contêineres (como Kubernetes) para expor sistemas de armazenamento arbitrários a suas cargas de trabalho de contêiner.
Leia a proposta de design CSI para obter mais informações.
Uma vez que um driver de volume compatível com CSI seja implantado em um cluster Kubernetes, os usuários podem usar o tipo de volume csi
para anexar ou montar os volumes expostos pelo driver CSI.
Um volume csi
pode ser utilizado em um Pod de três formas diferentes:
- Através de uma referência a PersistentVolumeClaim
- com um volume efêmero genérico (recurso alfa)
- com volume efêmero de CSI se o driver suportar esse (recurso beta)
Os seguintes campos estão disponíveis para administradores de armazenamento configurarem um volume persistente de CSI:
driver
: Um valor do tipo string que especifica o nome do driver de volume a ser usado. Este valor deve corresponder ao valor retornado noGetPluginInfoResponse
pelo driver CSI, conforme definido na especificação CSI. Ele é usado pelo Kubernetes para identificar qual driver CSI chamar, e pelos componentes do driver CSI para identificar quais objetos PV pertencem ao driver CSI.volumeHandle
: Um valor do tipo string que identifica exclusivamente o volume. Este valor deve corresponder ao valor retornado no campovolume.id
emCreateVolumeResponse
pelo driver CSI, conforme definido na especificação CSI. O valor é passado comovolume_id
em todas as chamadas para o driver de volume CSI quando se faz referência ao volume.readOnly
: Um valor booleano opcional que indica se o volume deve ser "ControllerPublished" (anexado) como somente leitura. O valor padrão é false. Este valor é passado para o driver CSI através do camporeadonly
emControllerPublishVolumeRequest
.fsType
: Se oVolumeMode
do PV forFilesystem
então este campo pode ser usado para especificar o sistema de arquivos que deve ser usado para montar o volume. Se o volume não tiver sido formatado e a formatação for suportada, este valor será utilizado para formatar o volume. Este valor é passado para o driver CSI através do campoVolumeCapability
nas propriedadesControllerPublishVolumeRequest
,NodeStageVolumeRequest
eNodePublishVolumeRequest
.volumeAttributes
: Um mapa de valores do tipo string para string que especifica propriedades estáticas de um volume. Este mapa deve corresponder ao mapa retornado no campovolume.attributes
doCreateVolumeResponse
pelo driver CSI, conforme definido na especificação CSI. O mapa é passado para o driver CSI através do campovolume_context
nas propriedadesControllerPublishVolumeRequest
,NodeStageVolumeRequest
, eNodePublishVolumeRequest
.controllerPublishSecretRef
: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver CSI para completar as chamadas CSIControllerPublishVolume
eControllerUnpublishVolume
. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão passados.nodeStageSecretRef
: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI para completar a chamada de CSI doNodeStageVolume
. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão passados.nodePublishSecretRef
: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI para completar a chamada de CSI doNodePublishVolume
. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o objeto Secret contiver mais de um segredo, todos os segredos serão passados.
Suporte CSI para volume de bloco bruto
Kubernetes v1.18 [stable]
Os fornecedores com drivers CSI externos podem implementar o suporte de volume de blocos brutos nas cargas de trabalho Kubernetes.
Você pode configurar o PersistentVolume/PersistentVolumeClaim com suporte de volume de bloco bruto , como habitualmente, sem quaisquer alterações específicas de CSI.
Volumes efêmeros de CSI
Kubernetes v1.16 [beta]
É possível configurar diretamente volumes CSI dentro da especificação do Pod. Os volumes especificados desta forma são efêmeros e não persistem nas reinicializações do pod. Consulte Volumes efêmeros para obter mais informações.
Para obter mais informações sobre como desenvolver um driver CSI, consulte a documentação kubernetes-csi
Migrando para drivers CSI a partir de plugins in-tree
Kubernetes v1.17 [beta]
Quando o recurso CSIMigration
está habilitado, direciona operações relacionadas a plugins in-tree existentes para plugins CSI correspondentes (que devem ser instalados e configurados). Como resultado, os operadores não precisam fazer nenhuma alteração de configuração para Storage Classes, PersistentVolumes ou PersistentVolumeClaims existentes (referindo-se aos plugins in-tree) quando a transição para um driver CSI que substitui um plugin in-tree.
As operações e características que são suportadas incluem: provisionamento/exclusão, anexação/remoção, montargem/desmontagem e redimensionamento de volumes.
Plugins in-tree que suportam CSIMigration
e têm um driver CSI correspondente implementado são listados em tipos de volumes.
flexVolume
Kubernetes v1.23 [deprecated]
O FlexVolume é uma interface de plugin out-of-tree que usa um modelo baseado em execução para fazer interface com drivers de armazenamento. Os binários do driver FlexVolume devem ser instalados em um caminho de plugin de volume predefinido em cada nó e, em alguns casos, também nos nós da camada de gerenciamento.
Os Pods interagem com os drivers do FlexVolume através do plugin de volume in-tree flexVolume
. Para obter mais detalhes, consulte o documento README do FlexVolume.
O FlexVolume foi descontinuado. Usar um driver CSI out-of-tree é a maneira recomendada de integrar o armazenamento externo com Kubernetes.
Os mantenedores do driver FlexVolume devem implementar um driver CSI e ajudar a migrar usuários de drivers FlexVolume para CSI. Os usuários do FlexVolume devem mover suas cargas de trabalho para usar o driver CSI equivalente.
Propagação de montagem
A propagação de montagem permite compartilhar volumes montados por um contêiner para outros contêineres no mesmo pod, ou mesmo para outros pods no mesmo nó.
A propagação de montagem de um volume é controlada pelo campo mountPropagation
na propriedade Container.volumeMounts
. Os seus valores são:
None
- Este volume de montagem não receberá do host nenhuma montagem posterior que seja montada para este volume ou qualquer um de seus subdiretórios. De forma semelhante, nenhum ponto de montagem criado pelo contêiner será visível no host. Este é o modo padrão.Este modo é igual à propagação de montagem
private
conforme descrito na documentação do kernel LinuxHostToContainer
- Este volume de montagem receberá todas as montagens posteriores que forem montadas para este volume ou qualquer um de seus subdiretórios.Em outras palavras, se o host montar qualquer coisa dentro do volume de montagem, o container o visualizará montado ali.
Da mesma forma, se qualquer Pod com propagação de montagem
Bidirectional
para o mesmo volume montar qualquer coisa lá, o contêiner com propagação de montagemHostToContainer
o reconhecerá.Este modo é igual à propagação de montagem
rslave
conforme descrito na documentação do kernel LinuxBidirectional
- Esta montagem de volume se comporta da mesma forma que a montagem de volumeHostToContainer
. Além disso, todas as montagens de volume criadas pelo contêiner serão propagadas de volta ao host e a todos os contêineres de todas os pods que utilizam o mesmo volume.Um caso de uso típico para este modo é um Pod com um driver FlexVolume ou CSI ou um Pod que precisa montar algo no host utilizando um volume
hostPath
.Este modo é igual à propagação de montagem
rshared
conforme descrito na documentação do kernel LinuxAviso: A propagação de montagemBidirectional
pode ser perigosa. Ela pode danificar o sistema operacional do host e, portanto, ela só é permitida em contêineres privilegiados. A familiaridade com o comportamento do kernel Linux é fortemente recomendada. Além disso, quaisquer montagens de volume criadas por contêineres em pods devem ser destruídas ( desmontadas) pelos contêineres ao final.
Configuração
Antes que a propagação da montagem possa funcionar corretamente em algumas distribuições (CoreOS, RedHat/Centos, Ubuntu), o compartilhamento de montagem deve ser configurado corretamente no Docker como mostrado abaixo.
Edite seu arquivo de serviços systemd
do Docker. Configure a propriedade MountFlags
da seguinte forma:
MountFlags=shared
Ou, se a propriedade MountFlags=slave
existir, remova-a. Em seguida, reinicie o daemon Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
Próximos passos
Siga um exemplo de implantação do WordPress e MySQL com volumes persistentes.
2 - Volumes Persistentes
Esse documento descreve o estado atual dos volumes persistentes no Kubernetes. Sugerimos que esteja familiarizado com volumes.
Introdução
O gerenciamento de armazenamento é uma questão bem diferente do gerenciamento de instâncias computacionais. O subsistema PersistentVolume provê uma API para usuários e administradores que mostra de forma detalhada de como o armazenamento é provido e como ele é consumido. Para isso, nós introduzimos duas novas APIs: PersistentVolume e PersistentVolumeClaim.
Um PersistentVolume (PV) é uma parte do armazenamento dentro do cluster que tenha sido provisionada por um administrador, ou dinamicamente utilizando Classes de Armazenamento. Isso é um recurso dentro do cluster da mesma forma que um nó também é. PVs são plugins de volume da mesma forma que Volumes, porém eles têm um ciclo de vida independente de qualquer Pod que utilize um PV. Essa API tem por objetivo mostrar os detalhes da implementação do armazenamento, seja ele NFS, iSCSI, ou um armazenamento específico de um provedor de cloud pública.
Uma PersistentVolumeClaim (PVC) é uma requisição para armazenamento por um usuário. É similar a um Pod. Pods utilizam recursos do nó e PVCs utilizam recursos do PV. Pods podem solicitar níveis específicos de recursos (CPU e Memória). Claims podem solicitar tamanho e modos de acesso específicos (exemplo: montagem como ReadWriteOnce, ReadOnlyMany ou ReadWriteMany, veja Modos de Acesso).
Enquanto as PersistentVolumeClaims permitem que um usuário utilize recursos de armazenamento de forma limitada, é comum que usuários precisem de PersistentVolumes com diversas propriedades, como desempenho, para problemas diversos. Os administradores de cluster precisam estar aptos a oferecer uma variedade de PersistentVolumes que difiram em tamanho e modo de acesso, sem expor os usuários a detalhes de como esses volumes são implementados. Para necessidades como essas, temos o recurso de StorageClass.
Veja os exemplos de passo a passo de forma detalhada.
Requisição e ciclo de vida de um volume
PVs são recursos dentro um cluster. PVCs são requisições para esses recursos e também atuam como uma validação da solicitação desses recursos. O ciclo de vida da interação entre PVs e PVCs funcionam da seguinte forma:
Provisionamento
Existem duas formas de provisionar um PV: estaticamente ou dinamicamente.
Estático
O administrador do cluster cria uma determinada quantidade de PVs. Eles possuem todos os detalhes do armazenamento os quais estão atrelados, que neste caso fica disponível para utilização por um usuário dentro do cluster. Eles estão presentes na API do Kubernetes e disponíveis para utilização.
Dinâmico
Quando nenhum dos PVs estáticos, que foram criados anteriormente pelo administrador, satisfazem os critérios de uma PersistentVolumeClaim enviado por um usuário, o cluster pode tentar realizar um provisionamento dinâmico para atender a essa PVC. Esse provisionamento é baseado em StorageClasses: a PVC deve solicitar uma classe de armazenamento e o administrador deve ter previamente criado e configurado essa classe para que o provisionamento dinâmico possa ocorrer. Requisições que solicitam a classe ""
efetivamente desabilitam o provisionamento dinâmico para elas mesmas.
Para habilitar o provisionamento de armazenamento dinâmico baseado em classe de armazenamento, o administrador do cluster precisa habilitar o controle de admissão DefaultStorageClass
no servidor da API. Isso pode ser feito, por exemplo, garantindo que DefaultStorageClass
esteja entre aspas simples, ordenado por uma lista de valores para a flag --enable-admission-plugins
, componente do servidor da API. Para mais informações sobre os comandos das flags do servidor da API, consulte a documentação kube-apiserver.
Binding
Um usuário cria, ou em caso de um provisionamento dinâmico já ter criado, uma PersistentVolumeClaim solicitando uma quantidade específica de armazenamento e um determinado modo de acesso. Um controle de loop no master monitora por novas PVCs, encontra um PV (se possível) que satisfaça os requisitos e realiza o bind. Se o PV foi provisionado dinamicamente por uma PVC, o loop sempre vai fazer o bind desse PV com essa PVC em específico. Caso contrário, o usuário vai receber no mínimo o que ele havia solicitado, porém, o volume possa exceder em relação à solicitação inicial. Uma vez realizado esse processo, PersistentVolumeClaim sempre vai ter um bind exclusivo, sem levar em conta como o isso aconteceu. Um bind entre uma PVC e um PV é um mapeamento de um para um, utilizando o ClaimRef que é um bind bidirecional entre o PersistentVolume e o PersistentVolumeClaim.
As requisições permanecerão sem bind se o volume solicitado não existir. O bind ocorrerá somente se os requisitos forem atendidos exatamente da mesma forma como solicitado. Por exemplo, um bind de uma PVC de 100 GB não ocorrerá num cluster que foi provisionado com vários PVs de 50 GB. O bind ocorrerá somente no momento em que um PV de 100 GB for adicionado.
Utilização
Pods utilizam requisições como volumes. O cluster inspeciona a requisição para encontrar o volume atrelado a ela e monta esse volume para um Pod. Para volumes que suportam múltiplos modos de acesso, o usuário especifica qual o modo desejado quando utiliza essas requisições.
Uma vez que o usuário tem a requisição atrelada a um PV, ele pertence ao usuário pelo tempo que ele precisar. Usuários agendam Pods e acessam seus PVs requisitados através da seção persistentVolumeClaim
no bloco volumes
do Pod. Para mais detalhes sobre isso, veja Requisições como Volumes.
Proteção de Uso de um Objeto de Armazenamento
O propósito da funcionalidade do Objeto de Armazenamento em Proteção de Uso é garantir que as PersistentVolumeClaims (PVCs) que estejam sendo utilizadas por um Pod e PersistentVolume (PVs) que pertençam aos PVCs não sejam removidos do sistema, pois isso pode resultar numa perda de dados.
Se um usuário deleta uma PVC que está sendo utilizada por um Pod, esta PVC não é removida imediatamente. A remoção da PVC é adiada até que a PVC não esteja mais sendo utilizado por nenhum Pod. Se um administrador deleta um PV que está atrelado a uma PVC, o PV não é removido imediatamente também. A remoção do PV é adiada até que o PV não esteja mais atrelado à PVC.
Note que uma PVC é protegida quando o status da PVC é Terminating
e a lista Finalizers
contém kubernetes.io/pvc-protection
:
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
Note que um PV é protegido quando o status da PVC é Terminating
e a lista Finalizers
contém kubernetes.io/pv-protection
também:
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Recuperação
Quando um usuário não precisar mais utilizar um volume, ele pode deletar a PVC pela API, que, permite a recuperação do recurso. A política de recuperação para um PersistentVolume diz ao cluster o que fazer com o volume após ele ter sido liberado da sua requisição. Atualmente, volumes podem ser Retidos, Reciclados ou Deletados.
Retenção
A política Retain
permite a recuperação de forma manual do recurso. Quando a PersistentVolumeClaim é deletada, ela continua existindo e o volume é considerado "livre". Mas ele ainda não está disponível para outra requisição porque os dados da requisição anterior ainda permanecem no volume. Um administrador pode manualmente recuperar o volume executando os seguintes passos:
- Deletar o PersistentVolume. O armazenamento associado à infraestrutura externa (AWS EBS, GCE PD, Azure Disk ou Cinder volume) ainda continuará existindo após o PV ser deletado.
- Limpar os dados de forma manual no armazenamento associado.
- Deletar manualmente o armazenamento associado. Caso você queira utilizar o mesmo armazenamento, crie um novo PersistentVolume com esse armazenamento.
Deletar
Para plugins de volume que suportam a política de recuperação Delete
, a deleção vai remover o tanto o PersistentVolume do Kubernetes, quanto o armazenamento associado à infraestrutura externa, como AWS EBS, GCE PD, Azure Disk, ou Cinder volume. Volumes que foram provisionados dinamicamente herdam a política de retenção da sua StorageClass, que por padrão é Delete
. O administrador precisa configurar a StorageClass de acordo com as necessidades dos usuários. Caso contrário, o PV deve ser editado ou reparado após sua criação. Veja Alterar a política de retenção de um PersistentVolume.
Reciclar
Recycle
está depreciada. Ao invés disso, recomendamos a utilização de provisionamento dinâmico.Em caso do volume plugin ter suporte a essa operação, a política de retenção Recycle
faz uma limpeza básica (rm -rf /thevolume/*
) no volume e torna ele disponível novamente para outra requisição.
Contudo, um administrador pode configurar um template personalizado de um Pod reciclador utilizando a linha de comando do gerenciamento de controle do Kubernetes como descrito em referência.
O Pod reciclador personalizado deve conter a spec volume
como é mostrado no exemplo abaixo:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
Contudo, o caminho especificado no Pod reciclador personalizado em volumes
é substituído pelo caminho do volume que está sendo reciclado.
Reservando um PersistentVolume
A camada de gerenciamento pode fazer o bind de um PersistentVolumeClaims com PersistentVolumes equivalentes no cluster. Contudo, se você quer que uma PVC faça um bind com um PV específico, é preciso fazer o pré-bind deles.
Especificando um PersistentVolume na PersistentVolumeClaim, você declara um bind entre uma PVC e um PV específico. O bind ocorrerá se o PersistentVolume existir e não estiver reservado por uma PersistentVolumeClaims através do seu campo claimRef
.
O bind ocorre independentemente se algum volume atender ao critério, incluindo afinidade de nó. A camada de gerenciamento verifica se a classe de armazenamento, modo de acesso e tamanho do armazenamento solicitado ainda são válidos.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
volumeName: foo-pv
...
Esse método não garante nenhum privilégio de bind no PersistentVolume. Para evitar que alguma outra PersistentVolumeClaims possa usar o PV que você especificar, você precisa primeiro reservar esse volume de armazenamento. Especifique sua PersistentVolumeClaim no campo claimRef
do PV para que outras PVCs não façam bind nele.
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
Isso é útil se você deseja utilizar PersistentVolumes que possuem suas claimPolicy
configuradas para Retain
, incluindo situações onde você estiver reutilizando um PV existente.
Expandindo Requisições de Volumes Persistentes
Kubernetes v1.11 [beta]
Agora, o suporte à expansão de PersistentVolumeClaims (PVCs) já é habilitado por padrão. Você pode expandir os tipos de volumes abaixo:
- gcePersistentDisk
- awsElasticBlockStore
- Cinder
- glusterfs
- rbd
- Azure File
- Azure Disk
- Portworx
- FlexVolumes
- CSI
Você só pode expandir uma PVC se o campo da classe de armazenamento allowVolumeExpansion
é true
.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restusuário: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
Para solicitar um volume maior para uma PVC, edite a PVC e especifique um tamanho maior. Isso irá fazer com o que volume atrelado ao respectivo PersistentVolume seja expandido. Nunca um PersistentVolume é criado para satisfazer a requisição. Ao invés disso, um volume existente é redimensionado.
Expansão de volume CSI
Kubernetes v1.24 [stable]
O suporte à expansão de volumes CSI é habilitada por padrão, porém é necessário um driver CSI específico para suportar a expansão do volume. Verifique a documentação do driver CSI específico para mais informações.
Redimensionando um volume que contém um sistema de arquivo
Só podem ser redimensionados os volumes que contém os seguintes sistemas de arquivo: XFS, Ext3 ou Ext4.
Quando um volume contém um sistema de arquivo, o sistema de arquivo somente é redimensionado quando um novo Pod está utilizando a PersistentVolumeClaim no modo ReadWrite
. A expansão de sistema de arquivo é feita quando um Pod estiver inicializando ou quando um Pod estiver em execução e o respectivo sistema de arquivo tenha suporte para expansão a quente.
FlexVolumes permitem redimensionamento se o RequiresFSResize
do drive é configurado como true
. O FlexVolume pode ser redimensionado na reinicialização do Pod.
Redimensionamento de uma PersistentVolumeClaim em uso
Kubernetes v1.15 [beta]
ExpandInUsePersistentVolumes
precisa ser habilitada, o que já está automático para vários clusters que possuem funcionalidades beta. Verifique a documentação feature gate para mais informações.Neste caso, você não precisa deletar e recriar um Pod ou um deployment que está sendo utilizado por uma PVC existente. Automaticamente, qualquer PVC em uso fica disponível para o Pod assim que o sistema de arquivo for expandido. Essa funcionalidade não tem efeito em PVCs que não estão em uso por um Pod ou deployment. Você deve criar um Pod que utilize a PVC antes que a expansão seja completada.
Da mesma forma que outros tipos de volumes - volumes FlexVolume também podem ser expandidos quando estiverem em uso por um Pod.
Recuperação em caso de falha na expansão de volumes
Se a expansão do respectivo armazenamento falhar, o administrador do cluster pode recuperar manualmente o estado da Persistent Volume Claim (PVC) e cancelar as solicitações de redimensionamento. Caso contrário, as tentativas de solicitação de redimensionamento ocorrerão de forma contínua pelo controlador sem nenhuma intervenção do administrador.
- Marque o PersistentVolume(PV) que estiver atrelado à PersistentVolumeClaim(PVC) com a política de recuperação
Retain
. - Delete a PVC. Desde que o PV tenha a política de recuperação
Retain
- nenhum dado será perdido quando a PVC for recriada. - Delete a entrada
claimRef
da especificação do PV para que uma PVC possa fazer bind com ele. Isso deve tornar o PVAvailable
. - Recrie a PVC com um tamanho menor que o PV e configure o campo
volumeName
da PCV com o nome do PV. Isso deve fazer o bind de uma nova PVC a um PV existente. - Não esqueça de restaurar a política de recuperação do PV.
Tipos de volumes persistentes
Tipos de PersistentVolume são implementados como plugins. Atualmente o Kubernetes suporta os plugins abaixo:
awsElasticBlockStore
- AWS Elastic Block Store (EBS)azureDisk
- Azure DiskazureFile
- Azure Filecephfs
- CephFS volumecinder
- Cinder (OpenStack block storage) (depreciado)csi
- Container Storage Interface (CSI)fc
- Fibre Channel (FC) storageflexVolume
- FlexVolumeflocker
- Flocker storagegcePersistentDisk
- GCE Persistent Diskglusterfs
- Glusterfs volumehostPath
- HostPath volume (somente para teste de nó único; ISSO NÃO FUNCIONARÁ num cluster multi-nós; ao invés disso, considere a utilização de volumelocal
.)iscsi
- iSCSI (SCSI over IP) storagelocal
- storage local montados nos nós.nfs
- Network File System (NFS) storagephotonPersistentDisk
- Controlador Photon para disco persistente. (Esse tipo de volume não funciona mais desde a removação do provedor de cloud correspondente.)portworxVolume
- Volume Portworxquobyte
- Volume Quobyterbd
- Volume Rados Block Device (RBD)scaleIO
- Volume ScaleIO (depreciado)storageos
- Volume StorageOSvsphereVolume
- Volume vSphere VMDK
Volumes Persistentes
Cada PV contém uma spec
e um status, que é a especificação e o status do volume. O nome do PersistentVolume deve ser um DNS válido.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Capacidade
Geralmente, um PV terá uma capacidade de armazenamento específica. Isso é configurado usando o atributo capacity
do PV. Veja o Modelo de Recurso do Kubernetes para entender as unidades aceitas pelo atributo capacity
.
Atualmente, o tamanho do armazenamento é o único recurso que pode ser configurado ou solicitado. Os futuros atributos podem incluir IOPS, throughput, etc.
Modo do Volume
Kubernetes v1.18 [stable]
O Kubernetes suporta dois volumeModes
de PersistentVolumes: Filesystem
e Block
.
volumeMode
é um parâmetro opcional da API.
Filesystem
é o modo padrão utilizado quando o parâmetro volumeMode
é omitido.
Um volume com volumeMode: Filesystem
é montado em um diretório nos Pods. Se o volume for de um dispositivo de bloco e ele estiver vazio, o Kubernetes cria o sistema de arquivo no dispositivo antes de fazer a montagem pela primeira vez.
Você pode configurar o valor do volumeMode
para Block
para utilizar um disco bruto como volume. Esse volume é apresentado num Pod como um dispositivo de bloco, sem nenhum sistema de arquivo. Esse modo é útil para prover ao Pod a forma mais rápida para acessar um volume, sem nenhuma camada de sistema de arquivo entre o Pod e o volume. Por outro lado, a aplicação que estiver rodando no Pod deverá saber como tratar um dispositivo de bloco. Veja Suporte a Volume de Bloco Bruto para um exemplo de como utilizar o volume como volumeMode: Block
num Pod.
Modos de Acesso
Um PersistentVolume pode ser montado num host das mais variadas formas suportadas pelo provedor. Como mostrado na tabela abaixo, os provedores terão diferentes capacidades e cada modo de acesso do PV são configurados nos modos específicos suportados para cada volume em particular. Por exemplo, o NFS pode suportar múltiplos clientes read/write, mas um PV NFS específico pode ser exportado no server como read-only. Cada PV recebe seu próprio modo de acesso que descreve suas capacidades específicas.
Os modos de acesso são:
- ReadWriteOnce -- o volume pode ser montado como leitura-escrita por um nó único
- ReadOnlyMany -- o volume pode ser montado como somente-leitura por vários nós
- ReadWriteMany -- o volume pode ser montado como leitura-escrita por vários nós
Na linha de comando, os modos de acesso ficam abreviados:
- RWO - ReadWriteOnce
- ROX - ReadOnlyMany
- RWX - ReadWriteMany
Importante! Um volume somente pode ser montado utilizando um único modo de acesso por vez, independente se ele suportar mais de um. Por exemplo, um GCEPersistentDisk pode ser montado como ReadWriteOnce por um único nó ou ReadOnlyMany por vários nós, porém não simultaneamente.
Plugin de Volume | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
CSI | depende do driver | depende do driver | depende do driver |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | depende do driver |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | (funcionam quando os Pods são do tipo collocated) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
Classe
Um PV pode ter uma classe, que é especificada na configuração do atributo storageClassName
com o nome da StorageClass. Um PV de uma classe específica só pode ser atrelado a requisições PVCs dessa mesma classe. Um PV sem storageClassName
não possui nenhuma classe e pode ser montado somente a PVCs que não solicitem nenhuma classe em específico.
No passado, a notação volume.beta.kubernetes.io/storage-class
era utilizada no lugar do atributo storageClassName
. Essa notação ainda funciona. Contudo, ela será totalmente depreciada numa futura versão do Kubernetes.
Política de Retenção
Atualmente as políticas de retenção são:
- Retain -- recuperação manual
- Recycle -- limpeza básica (
rm -rf /thevolume/*
) - Delete -- o volume de armazenamento associado, como AWS EBS, GCE PD, Azure Disk ou OpenStack Cinder é deletado
Atualmente, somente NFS e HostPath suportam reciclagem. Volumes AWS EBS, GCE PD, Azure Disk e Cinder suportam delete.
Opções de Montagem
Um administrador do Kubernetes pode especificar opções de montagem adicionais quando um Volume Persistente é montado num nó.
Seguem os tipos de volumes que suportam opções de montagem.
- AWSElasticBlockStore
- AzureDisk
- AzureFile
- CephFS
- Cinder (OpenStack block storage)
- GCEPersistentDisk
- Glusterfs
- NFS
- Quobyte Volumes
- RBD (Ceph Block Device)
- StorageOS
- VsphereVolume
- iSCSI
Não há validação em relação às opções de montagem. A montagem irá falhar se houver alguma opção inválida.
No passado, a notação volume.beta.kubernetes.io/mount-options
era usada no lugar do atributo mountOptions
. Essa notação ainda funciona. Contudo, ela será totalmente depreciada numa futura versão do Kubernetes.
Afinidade de Nó
Um PV pode especificar uma afinidade de nó para definir restrições em relação ao limite de nós que podem acessar esse volume. Pods que utilizam um PV serão somente reservados para nós selecionados pela afinidade de nó.
Estado
Um volume sempre estará em um dos seguintes estados:
- Available -- um recurso que está livre e ainda não foi atrelado a nenhuma requisição
- Bound -- um volume atrelado a uma requisição
- Released -- a requisição foi deletada, mas o curso ainda não foi recuperado pelo cluster
- Failed -- o volume fracassou na sua recuperação automática
A CLI mostrará o nome do PV que foi atrelado à PVC
PersistentVolumeClaims
Cada PVC contém uma spec
e um status, que é a especificação e estado de uma requisição. O nome de um objeto PersistentVolumeClaim precisa ser um DNS válido.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Modos de Acesso
As requisições usam as mesmas convenções que os volumes quando eles solicitam um armazenamento com um modo de acesso específico.
Modos de Volume
As requisições usam as mesmas convenções que os volumes quando eles indicam o tipo de volume, seja ele um sistema de arquivo ou dispositivo de bloco.
Recursos
Assim como Pods, as requisições podem solicitar quantidades específicas de recurso. Neste caso, a solicitação é por armazenamento. O mesmo modelo de recurso vale para volumes e requisições.
Seletor
Requisições podem especifiar um seletor de rótulo para posteriormente filtrar um grupo de volumes. Somente os volumes que possuam rótulos que satisfaçam os critérios do seletor podem ser atrelados à requisição. O seletor pode conter dois campos:
matchLabels
- o volume deve ter um rótulo com esse valormatchExpressions
- uma lista de requisitos, como chave, lista de valores e operador relacionado aos valores e chaves. São operadores válidos: In, NotIn, Exists e DoesNotExist.
Todos os requisitos de matchLabels
e matchExpressions
, são do tipo AND - todos eles juntos devem ser atendidos.
Classe
Uma requisição pode solicitar uma classe específica através da StorageClass utilizando o atributo storageClassName
. Neste caso o bind ocorrerá somente com os PVs que possuírem a mesma classe do storageClassName
dos PVCs.
As PVCs não precisam necessariamente solicitar uma classe. Uma PVC com sua storageClassName
configurada como ""
sempre solicitará um PV sem classe, dessa forma ela sempre será atrelada a um PV sem classe (que não tenha nenhuma notação, ou seja, igual a ""
). Uma PVC sem storageClassName
não é a mesma coisa e será tratada pelo cluster de forma diferente, porém isso dependerá se o puglin de admissão DefaultStorageClass
estiver habilitado.
- Se o plugin de admissão estiver habilitado, o administrador poderá especificar a StorageClass padrão. Todas as PVCs que não tiverem
storageClassName
podem ser atreladas somente a PVs que atendam a esse padrão. A especificação de uma StorageClass padrão é feita através da notaçãostorageclass.kubernetes.io/is-default-class
recebendo o valortrue
no objeto da StorageClass. Se o administrador não especificar nenhum padrão, o cluster vai tratar a criação de uma PVC como se o plugin de admissão estivesse desabilitado. Se mais de um valor padrão for especificado, o plugin de admissão proíbe a criação de todas as PVCs. - Se o plugin de admissão estiver desabilitado, não haverá nenhuma notação para a StorageClass padrão. Todas as PVCs que não tiverem
storageClassName
poderão ser atreladas somente aos PVs que não possuem classe. Neste caso, as PVCs que não tiveremstorageClassName
são tratadas da mesma forma como as PVCs que possuem suasstorageClassName
configuradas como""
.
Dependendo do modo de instalação, uma StorageClass padrão pode ser implantada num cluster Kubernetes durante a instalação pelo addon manager.
Quando uma PVC especifica um selector
para solicitar uma StorageClass, os requisitos são do tipo AND: somente um PV com a classe solicitada e com o rótulo requisitado pode ser atrelado à PVC.
selector
não pode ter um PV dinamicamente provisionado.No passado, a notação volume.beta.kubernetes.io/storage-class
era usada no lugar do atributo storageClassName
Essa notação ainda funciona. Contudo, ela será totalmente depreciada numa futura versão do Kubernetes.
Requisições como Volumes
Os Pods podem ter acesso ao armazenamento utilizando a requisição como um volume. Para isso, a requisição tem que estar no mesmo namespace que o Pod. Ao localizar a requisição no namespace do Pod, o cluster passa o PersistentVolume para a requisição.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Sobre Namespaces
Os binds dos PersistentVolumes são exclusivos e, desde que as PersistentVolumeClaims são objetos do namespace, fazer a montagem das requisições com "Muitos" nós (ROX
, RWX
) é possível somente para um namespace.
PersistentVolumes do tipo hostPath
Um PersistentVolume do tipo hostPath
utiliza um arquivo ou diretório no nó para emular um network-attached storage (NAS). Veja um exemplo de volume do tipo hostPath
.
Suporte a Volume de Bloco Bruto
Kubernetes v1.18 [stable]
Os plugins de volume abaixo suportam volumes de bloco bruto, incluindo provisionamento dinâmico onde for aplicável:
- AWSElasticBlockStore
- AzureDisk
- CSI
- FC (Fibre Channel)
- GCEPersistentDisk
- iSCSI
- Local volume
- OpenStack Cinder
- RBD (Ceph Block Device)
- VsphereVolume
Utilização de PersistentVolume com Volume de Bloco Bruto
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
Requisição de PersistentVolumeClaim com Volume de Bloco Bruto
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
Especificação de Pod com Dispositivo de Bloco Bruto no contêiner
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
Bind de Volumes de Bloco
Se um usuário solicita um volume de bloco bruto através do campo volumeMode
na spec
da PersistentVolumeClaim, as regras de bind agora têm uma pequena diferença em relação às versões anteriores que não consideravam esse modo como parte da spec
.
A tabela abaixo mostra as possíveis combinações que um usuário e um administrador pode especificar para requisitar um dispositivo de bloco bruto. A tabela indica se o volume será ou não atrelado com base nas combinações:
Matriz de bind de volume para provisionamento estático de volumes:
PV volumeMode | PVC volumeMode | Result |
---|---|---|
unspecified | unspecified | BIND |
unspecified | Block | NO BIND |
unspecified | Filesystem | BIND |
Block | unspecified | NO BIND |
Block | Block | BIND |
Block | Filesystem | NO BIND |
Filesystem | Filesystem | BIND |
Filesystem | Block | NO BIND |
Filesystem | unspecified | BIND |
Snapshot de Volume e Restauração de Volume a partir de um Snapshot
Kubernetes v1.20 [stable]
O snapshot de volume é suportado somente pelo plugin de volume CSI. Veja Snapshot de Volume para mais detalhes. Plugins de volume in-tree estão depreciados. Você pode consultar sobre os plugins de volume depreciados em Perguntas Frequentes sobre Plugins de Volume.
Criar uma PersistentVolumeClaim a partir de um Snapshot de Volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Clonagem de Volume
A Clonagem de Volume é possível somente com plugins de volume CSI.
Criação de PersistentVolumeClaim a partir de uma PVC já existente
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Boas Práticas de Configuração
Se você está criando templates ou exemplos que rodam numa grande quantidade de clusters e que precisam de armazenamento persistente, recomendamos que utilize o padrão abaixo:
Inclua objetos PersistentVolumeClaim em seu pacote de configuração (com Deployments, ConfigMaps, etc.).
Não inclua objetos PersistentVolume na configuração, pois o usuário que irá instanciar a configuração talvez não tenha permissão para criar PersistentVolume.
Dê ao usuário a opção dele informar o nome de uma classe de armazenamento quando instanciar o template.
- Se o usuário informar o nome de uma classe de armazenamento, coloque esse valor no campo
persistentVolumeClaim.storageClassName
. Isso fará com que a PVC encontre a classe de armazenamento correta se o cluster tiver a StorageClasses habilitado pelo administrador. - Se o usuário não informar o nome da classe de armazenamento, deixe o campo
persistentVolumeClaim.storageClassName
sem nenhum valor (vazio). Isso fará com que o PV seja provisionado automaticamente no cluster para o usuário com o StorageClass padrão. Muitos ambientes de cluster já possuem uma StorageClass padrão, ou então os administradores podem criar suas StorageClass de acordo com seus critérios.
- Se o usuário informar o nome de uma classe de armazenamento, coloque esse valor no campo
Durante suas tarefas de administração, busque por PVCs que após um tempo não estão sendo atreladas, pois, isso talvez indique que o cluster não tem provisionamento dinâmico (onde o usuário deveria criar um PV que satisfaça os critérios da PVC) ou cluster não tem um sistema de armazenamento (onde usuário não pode realizar um deploy solicitando PVCs).
Próximos passos
- Saiba mais sobre Criando um PersistentVolume.
- Saiba mais sobre Criando um PersistentVolumeClaim.
- Leia a documentação sobre planejamento de Armazenamento Persistente.