<p>I'm starting out in K8s and I'm not quite wrapping my head around deploying a StatefulSet with multiple replicas bound to a local disc using <code>PV</code>+<code>PVC</code>+<code>SC</code> vs. <code>volumeClaimTemplates</code> + <code>HostPath</code>
scenarios.
My goal is to deploy a MongoDB StatefulSet with 3 replicas set in (mongo's replica set) ReplicaSet mode and bound each one to a local ssd.
I did a few tests and got a few concepts to get straight.</p>
<p>Scenario a) using <code>PV</code>+<code>PVC</code>+<code>SC</code>:
If in my <code>StatefulSet</code>'s container (set with replicas:1) I declare a <code>volumeMounts</code> and a <code>Volume</code> I can point it to a PVC which uses a SC used by a PV which points to a physical local ssd folder.
The concept is straight, it all maps beautifully.
If I increase the replicas to be more the one then from the second pod onward they'll won't find a Volume to bind to..and I get the <code>1 node(s) didn't find available persistent volumes to bind</code> error.</p>
<p>This makes me realise that the storage capacity reserved from the PVC on that PV is not replicated as the pods in the StatefulSet and mapped to each created POD.</p>
<p>Scenario b) <code>volumeClaimTemplates</code> + <code>HostPath</code>:</p>
<p>I commented out the Volume, and instead used the <code>volumeClaimTemplates</code> which indeed works as I was expecting in scenario a, for each created pod an associated claim gets created and some storage capacity gets reserved for that Pod. Here also pretty straight concept, but it only works as long as I use <code>storageClassName: hostpath</code> in <code>volumeClaimTemplates</code>. I tried using my SC and the result is the same <code>1 node(s) didn't find available persistent volumes to bind</code> error.</p>
<p>Also, when created with <code>volumeClaimTemplates</code> PV names are useless and confusing as the start with PVC..</p>
<pre><code>vincenzocalia@vincenzos-MacBook-Air server-node % kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                        STORAGECLASS   REASON   AGE
mg-pv                                      3Gi        RWO            Delete           Available                                mg-sc                   64s
pvc-32589cce-f472-40c9-b6e4-dc5e26c2177a   50Mi       RWO            Delete           Bound       default/mg-pv-cont-mongo-3   hostpath                36m
pvc-3e2f4e50-30f8-4ce8-8a62-0b923fd6aa79   50Mi       RWO            Delete           Bound       default/mg-pv-cont-mongo-1   hostpath                37m
pvc-8f4ff966-c30a-469f-a68d-ed579ef2a96f   50Mi       RWO            Delete           Bound       default/mg-pv-cont-mongo-4   hostpath                36m
pvc-9f8c933b-85d6-4024-8bd0-6668feee8757   50Mi       RWO            Delete           Bound       default/mg-pv-cont-mongo-2   hostpath                37m
pvc-d6c212f3-2391-4137-97c3-07836c90b8f3   50Mi       RWO            Delete           Bound       default/mg-pv-cont-mongo-0   hostpath                37m
vincenzocalia@vincenzos-MacBook-Air server-node % kubectl get pvc
NAME                 STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mg-pv-cont-mongo-0   Bound     pvc-d6c212f3-2391-4137-97c3-07836c90b8f3   50Mi       RWO            hostpath       37m
mg-pv-cont-mongo-1   Bound     pvc-3e2f4e50-30f8-4ce8-8a62-0b923fd6aa79   50Mi       RWO            hostpath       37m
mg-pv-cont-mongo-2   Bound     pvc-9f8c933b-85d6-4024-8bd0-6668feee8757   50Mi       RWO            hostpath       37m
mg-pv-cont-mongo-3   Bound     pvc-32589cce-f472-40c9-b6e4-dc5e26c2177a   50Mi       RWO            hostpath       37m
mg-pv-cont-mongo-4   Bound     pvc-8f4ff966-c30a-469f-a68d-ed579ef2a96f   50Mi       RWO            hostpath       37m
mg-pvc               Pending                                                                        mg-sc          74s
</code></pre>
<p>Is there any way to get to set the <code>volumeClaimTemplates</code>'s PVs names as something more useful as when declaring a PV?</p>
<p>How to point <code>volumeClaimTemplates</code>'s PVs to an ssd as I'm doing for my scenario a?</p>
<p>Many thanks</p>
<h1>PV</h1>
<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: mg-pv
  labels:
    type: local
spec:
  capacity:
    storage: 3Gi
  persistentVolumeReclaimPolicy: Delete
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem 
  storageClassName: mg-sc
  local:
    path: /Volumes/ProjectsSSD/k8s_local_volumes/mongo/mnt/data/unt
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - docker-desktop
</code></pre>
<h1>SC</h1>
<pre><code>kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
 name: mg-sc
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
</code></pre>
<h1>PVC</h1>
<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mg-pvc
spec:
  storageClassName: mg-sc
  # volumeName: mg-pv 
  resources:
    requests:
      # storage: 1Gi
      storage: 50Mi
  accessModes:
    - ReadWriteOnce
</code></pre>
<h1>StatefulSet</h1>
<pre><code>apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
      role: mongo
      environment: test
  serviceName: 'mongo'
  replicas: 5
  template:
    metadata:
      labels:
        role: mongo
        environment: test
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mongo
          image: mongo
          command:
            - mongod
            - '--bind_ip'
            - all
            - '--replSet'
            - rs0
            # - &quot;--smallfiles&quot;
            # - &quot;--noprealloc&quot;
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mg-pv-cont
              mountPath: /data/db
        - name: mongo-sidecar
          image: cvallance/mongo-k8s-sidecar
          env:
            - name: MONGO_SIDECAR_POD_LABELS
              value: 'role=mongo,environment=test'
            - name: KUBERNETES_MONGO_SERVICE_NAME
              value: 'mongo'

      ### using volumes you have to have one persistent volume for each created pod..useful only for static set of pods
      # volumes:
      #   - name: mg-pv-cont
      #     persistentVolumeClaim:
      #       claimName: mg-pvc
  ## volume claim templates create a claim for each created pos, so if scaling up or down the number of pod they¡ll clame their own space in the persistent volume.
  volumeClaimTemplates:
    - metadata:
        name: mg-pv-cont # this binds
        # name: mg-pv-pvc-template     # same name as volumeMounts or it won't bind.
        ### Waiting for deployments to stabilize...
        ### - statefulset/mongo: Waiting for statefulset spec update to be observed...
      spec:
        # storageClassName: mg-sc
        storageClassName: hostpath
        accessModes: ['ReadWriteOnce']
        resources:
          requests:
            storage: 50Mi
</code></pre>

<p>Ok, after fiddling with it a bit more and testing a couple more of configurations I found out that the <code>PVC</code> to <code>PV</code> binding happens in a 1:1 manner, so once the <code>PV</code> has bound to a claim (either <code>PVC</code> or <code>volumeClaimTemplates</code>) no other claim can bind to it. So the solution is just to create many <code>PV</code>s as many pods you expect to create. And some extra for scaling up and down the replicas of your <code>StatefulSet</code>. Now in the <code>volumeClaimTemplates: spec: storageClassName:</code> you can user the <code>SC</code> you defined so the those <code>PV</code> get used. No use for <code>PVC</code> if using <code>volumeClassTemplates</code>..it'd just create a claim that nobody uses..</p>
<p>Hope this will help others starting out in the Kubernetes world.
Cheers.</p>
