Primeiramente, o assunto dessa publicação não é definir qual é a melhor opção. Portanto, aos comentaristas com ânsia em apontar a melhor ou a pior alternativa, estejam cientes desde já.
O assunto dessa publicação é, simplesmente, contribuir para quem precisa de provisionar um volume Kubernetes usando um serviço Network File System (NFS) como backend.
Vamos lá?
A priori, a Google Cloud (GCP) não disponibiliza Persistent Volume com ReadWriteMany
de maneira nativa. Atualmente, é necessário contratar uma solução gerenciada chamada Filestore.
O ReadWriteMany é útil quando mais de um workload precisa ler e escrever num mesmo volume, mesmo estando em nós diferentes. Por exemplo, se você tem um Deployment com cinco réplicas e cada Pod precisa de escrever no mesmo volume.
Dito isso, a criação de um serviço NFS para disponibilizar um share é um meio disponível. Na prática, o custo de uma VM e um disco persistente. Ou até mesmo um serviço no próprio cluster.
Nessa publicação, espera-se que você já tenha um share de NFS pronto e disponível.
Crie os seguintes objetos Kubernetes:
PersistentVolume (PV)
apiVersion: v1
kind: PersistentVolume
metadata:
name: share
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: ""
mountOptions:
- nfsvers=4.2
nfs:
server: "nfs.domain.tld"
path: "/my-share"
readOnly: false
# Se você quiser tornar esse PV exclusivo ao PVC
# claimRef:
# name:
# namespace:
PersistentVolumeClaim (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: share
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: ""
volumeName: share
Perceba que ambos possuem storageClassName
com uma string vazia. Isso acontece para evitar que ele adote por um armazenamento diferente do que estamos buscando.
E, além disso, o PVC buscará pelo PV através de volumeName
. Sendo parte da técnica de binding.
Por sua vez, o PV também pode fazer binding ao PVC através de claimRef
. Isso seria a técnica completa. Se preferir, pode definir o claimRef
para o nome e namespace do PVC. Nesse exemplo, não foi necessário.
O PV precisa do bloco nfs
configurado com server
e path
com o serviço NFS disponível. Ou seja, defina o endereço IP ou nome DNS no campo spec.nfs.server
e defina o caminho do share no campo spec.nfs.path
.
Essa é a configuração de utilizar um serviço NFS por trás de um PV.
Assim, é possível você definir o volume no seu Deployment por exemplo:
...
containers:
- image: busybox
name: teste
volumeMounts:
- mountPath: /opt/teste
name: volume-compartilhado
volumes:
- name: volume-compartilhado
persistentVolumeClaim:
claimName: share
Simples?
Em caso de problemas, verifique se o serviço NFS tem regras de firewall permitindo a rede do nó, ou se há alguma restrição com permissão de usuários sobre o diretório utilizado no servidor.