Search code examples
mongodbmacoskubernetesdocker-desktoppersistent-volumes

PersistentVolume not utilized in Docker Desktop (MacOS) hosted Kubernetes cluster


I have deployed (using Helm) some services in the K8s cluster hosted by Docker Desktop (MacOS). One of the "services" is MongoDB, for which I'm trying to set up a PersistedVolume, so that the actual data will be retained in a MacOS local directory between cluster (re)installs (or MongoDB pod replacements). Everything "works" per se, but the MongoDB container process keeps setting up its local directory /data/db, as if nothing is really setup in terms of Persistent Volumes. I've been pulling my hair for a while now and thought an extra set of eyes might spot whats wrong or missing.

I have several other resources deployed, e.g a small Micronaut based backend service which exposes an API to read from the MongoDB instance. All of that works just fine.

Here are the descriptors involved for MongoDB:

PersistentVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: persons-mongodb-pvc
  namespace: fo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

Deployment:

kind: Deployment
metadata:
  name: fo-persons-mongodb
  namespace: fo
  labels:
    app: fo-persons-mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fo-persons-mongodb
  template:
    metadata:
      labels:
        app: fo-persons-mongodb
    spec:
      volumes:
        - name: fo-persons-mongodb-volume-pvc
          persistentVolumeClaim:
            claimName: persons-mongodb-pvc
      containers:
        - name: fo-persons-mongodb
          image: mongo
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: fo-persons-mongodb-volume-pvc
              mountPath: "/data/db"

Service:

apiVersion: v1
kind: Service
metadata:
  name: fo-persons-mongodb
  namespace: fo
spec:
  type: ClusterIP
  selector:
    app: fo-persons-mongodb
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017

StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

PersistentVolume:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: fo-persons-mongodb-volume
  labels:
    type: local
spec:
  storageClassName: local-storage
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /Users/mike/kubernetes/fo/persons/mongodb

Solution

  • Alright! I got it working. Seems I'd made two mistakes. Below are the updated descriptors for the PersistentVolumeClaim and PersistentVolume:

    Error #1: Not setting the storageClassName in the spec of the PersistentVolumeClaim:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: persons-mongodb-pvc
      namespace: fo
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 2Gi
      storageClassName: local-storage
    

    Error #2: Not setting the node affinity and not using local.path instead of hostPath, both in the PersistentVolume:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: fo-persons-mongodb-volume
      labels:
        type: local
    spec:
      persistentVolumeReclaimPolicy: Delete
      storageClassName: local-storage
      capacity:
        storage: 10Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteOnce
      local:
        path: /Users/mike/kubernetes/fo/persons/mongodb
      nodeAffinity:
        required:
          nodeSelectorTerms:
            - matchExpressions:
                - key: kubernetes.io/hostname
                  operator: In
                  values:
                    - docker-desktop