Creating a PV and PVC on NFS for K8s

Took myself ages to figure this out, so I am noting this down for my future self.

First, we need to add NFS as a storage class:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"

Then, we can add the actual storage:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: nfs-persistentvolume
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: "nfs" # Empty string must be explicitly set otherwise default StorageClass will be set / or custom storageClassName name
  nfs:
    path: "/path/to/share"
    server: "xxx.xxx.xxx.xxx"
    readOnly: false
  claimRef:
    name: nfs-persistentvolumeclaim
    namespace: default
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-persistentvolumeclaim
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: "nfs" # Empty string must be explicitly set otherwise default StorageClass will be set / or custom storageClassName name
  volumeName: nfs-persistentvolume

Hope this helps

Bonus – run a Minecraft Bedrock inside K8S using your newly created PVC as storage

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mc-bedrock
  labels:
    app: mc-bedrock
spec:
  replicas: 1
  template:
    metadata:
      name: mc-bedrock
      labels:
        app: mc-bedrock
    spec:
      containers:
        - name: mc-bedrock
          image: itzg/minecraft-bedrock-server
          imagePullPolicy: Always
          resources:
            requests:
              cpu: 500m
              memory: 4Gi
          env:
            - name: EULA
              value: "TRUE"
            - name: GAMEMODE
              value: survival
            - name: DIFFICULTY
              value: normal
            - name: WHITE_LIST
              value: "false"
            - name: ONLINE_MODE
              value: "true"
            - name: ALLOW_CHEATS
              value: "true"
          volumeMounts:
            - mountPath: /data
              name: data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: nfs-persistentvolumeclaim
  selector:
    matchLabels:
      app: mc-bedrock
---
apiVersion: v1
kind: Service
metadata:
  name: mc-bedrock
  labels:
    app: mc-bedrock
spec:
  selector:
    app: mc-bedrock
  ports:
    - port: 19132
      protocol: UDP
  type: LoadBalancer

Get the IP assigned for the service

kubectl get service mc-bedrock -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Restart the pods in the deployment

kubectl logs -f deployment/mc-bedrock