<p>I have a Kubernetes cluster setup (on-premise), that has an NFS share (my-nfs.internal.tld) mounted to <code>/exports/backup</code> on each node to create backups there.</p>
<p>Now I'm setting up my logging stack and I wanted to make the data persistent. So I figured I could start by storing the indices on the NFS.</p>
<p>Now I found three different ways to achieve this:</p>
<h2>NFS-PV</h2>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: logging-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: my-nfs.internal.tld
    path: /path/to/exports/backup/logging-data/
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: logging-data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: logging-data
  resources:
    requests:
      storage: 10Gi
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      ...
      volumes:
        - name: logging-data-volume
          persistentVolumeClaim:
            claimName: logging-data-pvc
</code></pre>
<p>This would, of course, require, that my cluster gets access to the NFS (instead of only the nodes as it is currently setup).</p>
<h2>hostPath-PV</h2>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: logging-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /exports/backup/logging-data/
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: logging-data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: logging-data
  resources:
    requests:
      storage: 10Gi
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      ...
      volumes:
        - name: logging-data-volume
          persistentVolumeClaim:
            claimName: logging-data-pvc
</code></pre>
<h2>hostPath mount in deployment</h2>
<p>As the nfs is mounted to all my nodes, I could also just use the host path directly in the deployment without pinning anything.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      ...
      volumes:
        - name: logging-data-volume
          hostPath:
            path: /exports/backup/logging-data
            type: DirectoryOrCreate
</code></pre>
<hr />
<p>So my question is: Is there really any difference between these three? I'm pretty sure all three work. I tested the second and third already. I was not yet able to test the first though (in this specific setup at least). Especially the second and third solutions seem very similar to me. The second makes it easier to re-use deployment files on multiple clusters, I think, as you can use persistent volumes of different types without changing the <code>volumes</code> part of the deployment. But is there any difference beyond that? Performance maybe? Or is one of them deprecated and will be removed soon?</p>
<p>I found a <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume" rel="nofollow noreferrer">tutorial</a> mentioning, that the hostPath-PV only works on single-node clusters. But I'm sure it does also works in my case here. Maybe the comment was about: &quot;On multi-node clusters the data changes when deployed to different nodes.&quot;</p>
<p>From reading to a lot of documentation and How-To's I understand, that the first one is the preferred solution. I would probably also go for it as it is the one easiest <em>replicated</em> to a cloud setup. But I do not really understand why this is preferred to the other two.</p>
<p>Thanks in advance for your input on the matter!</p>

<p>The <a href="https://kubernetes.io/docs/concepts/storage/volumes/#nfs" rel="nofollow noreferrer">NFS</a> is indeed the preferred solution:</p>
<blockquote>
<p>An <code>nfs</code> volume allows an existing NFS (Network File System) share to
be mounted into a Pod. Unlike <code>emptyDir</code>, which is erased when a Pod
is removed, the contents of an <code>nfs</code> volume are preserved and the
volume is merely unmounted. This means that an NFS volume can be
pre-populated with data, and that data can be shared between pods. NFS
can be mounted by multiple writers simultaneously.</p>
</blockquote>
<p>So, an NFS is useful for two reasons:</p>
<ul>
<li><p>Data is persistent.</p>
</li>
<li><p>It can be accessed from multiple pods at the same time and the data can be shared between pods.</p>
</li>
</ul>
<p>See the NFS <a href="https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs" rel="nofollow noreferrer">example</a> for more details.</p>
<p>While the <a href="https://kubernetes.io/docs/concepts/storage/volumes/#hostpath" rel="nofollow noreferrer">hostPath</a>:</p>
<blockquote>
<p>A <code>hostPath</code> volume mounts a file or directory from the host node's
filesystem into your Pod.</p>
<p>Pods with identical configuration (such as created from a PodTemplate)
may behave differently on different nodes due to different files on
the nodes</p>
<p>The files or directories created on the underlying hosts are only
writable by root. You either need to run your process as root in a
privileged Container or modify the file permissions on the host to be
able to write to a <code>hostPath</code> volume</p>
</blockquote>
<p><code>hostPath</code> is not recommended due to several reasons:</p>
<ul>
<li><p>You don't directly control which node your pods will run on, so you're not guaranteed that the pod will actually be scheduled on the node that has the data volume.</p>
</li>
<li><p>You expose your cluster to security threats.</p>
</li>
<li><p>If a node goes down you need the pod to be scheduled on other node where your locally provisioned volume will not be available.</p>
</li>
</ul>
<p>the <code>hostPath</code> would be good if for example you would like to use it for log collector running in a <code>DaemonSet</code>. Other than that, it would be better to use the NFS.</p>
