# Volume com NFS no Kubernetes

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)**

```yaml
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)**

```yaml
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:

```yaml
  ...
  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.
