Sharing the public directory of an express.js app across all pods in a Kubernetes cluster

7/26/2019

I want to use a volume or persistent volume in a Kubernetes cluster deployed on Azure AKS to share the files in the public directory of an express.js app. The cluster has 3 replicas.

I tried following this: https://docs.microsoft.com/en-us/azure/aks/azure-files-volume. I reached out to the Kubernetes Slack channel. I was advised to try a persistent volume and a persistent volume claim. I did that and I still wasn't seeing a shared directory in any of the pods.

kind: Deployment
metadata:
  name: node-ffmpeg-video-cms-deployment 
  labels:
    app: node-ffmpeg-video-cms
spec:
  replicas: 3
  template:
    metadata:
      name: node-ffmpeg-video-cms
      labels:
        app: node-ffmpeg-video-cms
    spec:
      containers:
      - name: node-ffmpeg-video-cms
        image: nodeffmpegvideocmscr.azurecr.io/node-ffmpeg-video-cms:v1
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: mystorageaccount17924
          mountPath: /www/var/public
      restartPolicy: Always
      volumes:
      - name: mystorageaccount17924
        azureFile:
          secretName: azure-secret
          shareName: node-ffmpeg-video-cms
          readOnly: false
  selector:
    matchLabels:
      app: node-ffmpeg-video-cms

---

apiVersion: v1
kind: Service
metadata:
  name: node-ffmpeg-video-cms-service
spec:
  selector:
    app: node-ffmpeg-video-cms
  ports:
    - port: 3000
  type: LoadBalancer

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: sample-storage
  # The label is used for matching the exact claim
  labels:
    usage: sample-storage
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  azureFile:
    secretName: azure-secret
    shareName: node-ffmpeg-video-cms
    readOnly: false
  mountOptions:
    - dir_mode=0777
    - file_mode=0777
    - uid=1000
    - gid=1000

---

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: sample-storage-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: ""
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      usage: sample-storage

When I run kubectl describe pod on one of my pods:

Namespace:      default
Priority:       0
Node:           aks-nodepool1-22998726-0/10.240.0.4
Start Time:     Fri, 26 Jul 2019 14:55:29 -0500
Labels:         app=node-ffmpeg-video-cms
                pod-template-hash=8547d97c69
Annotations:    <none>
Status:         Running
IP:             10.244.0.24
Controlled By:  ReplicaSet/node-ffmpeg-video-cms-deployment-8547d97c69
Containers:
  node-ffmpeg-video-cms:
    Container ID:   docker://4c4f89dfc0058fcaa6fcba0b3dd66e89493715fe4373ffe625eacc0296a45ae1
    Image:          nodeffmpegvideocmscr.azurecr.io/node-ffmpeg-video-cms:v1
    Image ID:       docker-pullable://nodeffmpegvideocmscr.azurecr.io/node-ffmpeg-video-cms@sha256:2b949efa8535b59a927efbb4d7c6d24739691fa90fad86c91086dc4cfbadbe23
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 26 Jul 2019 14:55:31 -0500
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7pb5v (ro)
      /www/var/public from mystorageaccount17924 (rw)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  mystorageaccount17924:
    Type:        AzureFile (an Azure File Service mount on the host and bind mount to the pod)
    SecretName:  azure-secret
    ShareName:   node-ffmpeg-video-cms
    ReadOnly:    false
  default-token-7pb5v:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7pb5v
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
-- David Krause
azure
express
kubernetes
node.js
persistent-volumes

1 Answer

7/29/2019

To share a public directory to multiple pods of deployment in Azure, you can use the Azure File Share as it shows in the link that you provided. And you do not need to create the PV/PVC when you set the volumes and volumeMounts in the deployment.

It works fine in my test, I show the deployment and the screenshot of the result below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: nginx
        image: nginx:1.15.5
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        volumeMounts:
          - name: azure
            mountPath: /mnt/azure
      volumes:
        - name: azure
          azureFile:
            shareName: aksshare
            secretName: azure-secret
            readOnly: false

enter image description here

-- Charles Xu
Source: StackOverflow