a.barbieri
a.barbieri

Reputation: 2616

Kubernetes Deployment populates wrong Persistent Volume

I'm trying to create two deployments, one for Wordpress the other for MySQL which refer to two different Persistent Volumes.

Sometimes, while deleting and recreating volumes and deployments, the MySQL deployment populates the Wordpress volume (ending up with a database in the wordpress-volume directory).

This is clearer when you do kubectl get pv --namespace my-namespace:

mysql-volume       2Gi   RWO  Retain  Bound  flashart-it/wordpress-volume-claim   manual                   1h
wordpress-volume   2Gi   RWO  Retain  Bound  flashart-it/mysql-volume-claim       manual

I'm pretty sure the settings are ok. Please find the yaml file below.

Persistent Volume Claims + Persistent Volumes

kind: PersistentVolume
apiVersion: v1
metadata:
  namespace: my-namespace
  name: mysql-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /path/to/mount/mysql-volume
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: my-namespace
  name: mysql-volume-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
kind: PersistentVolume
apiVersion: v1
metadata:
  namespace: my-namespace
  name: wordpress-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /path/to/mount/wordpress-volume
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: my-namespace
  name: wordpress-volume-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

Deployments

kind: Deployment
apiVersion: apps/v1
metadata:
  name: wordpress
  namespace: my-namespace
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      namespace: my-namespace
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:5.0-php7.1-apache
        name: wordpress
        env:
          # ...
        ports:
          # ...
        volumeMounts:
        - name: wordpress-volume
          mountPath: /var/www/html
      volumes:
      - name: wordpress-volume
        persistentVolumeClaim:
          claimName: wordpress-volume-claim
---
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: my-namespace
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      namespace: my-namespace
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
        - image: mysql:5.7
          name: mysql
          env:
            # ...
          ports:
            # ...
          volumeMounts:
            - name: mysql-volume
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-volume
          persistentVolumeClaim:
            claimName: mysql-volume-claim

Upvotes: 2

Views: 899

Answers (2)

dragons_kee
dragons_kee

Reputation: 1

Persistent Volume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce    # Fixed: Changed from ReadOnlyMany to ReadWriteOnce for MongoDB
  hostPath:
    path: /data/mongodb
  storageClassName: standard

Persistent Volume Claim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  accessModes:
    - ReadWriteOnce    # Fixed: Now matches PV access mode
  resources:
    requests:          # Fixed: Corrected 'request' to 'requests'
      storage: 10Gi    # Fixed: Changed from 15Gi to match PV capacity
  storageClassName: standard    # Fixed: Now matches PV storage class

MongoDB Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb
spec:
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:latest
        volumeMounts:
        - name: mongodb-storage    # Fixed: Changed to match volume name below
          mountPath: /data/db
      volumes:
      - name: mongodb-storage
        persistentVolumeClaim:
          claimName: mongodb-pvc

Upvotes: 0

ccshih
ccshih

Reputation: 1210

It's expected behavior in Kubernetes. PVC can bind to any available PV, given that storage class is matched, access mode is matched, and storage size is sufficient. Names are not used to match PVC and PV.

A possible solution for your scenario is to use label selector on PVC to filter qualified PV.

First, add a label to PV (in this case: app=mysql)

kind: PersistentVolume
apiVersion: v1
metadata:
  name: mysql-volume
  labels:
    app: mysql

Then, add a label selector in PVC to filter PV.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: my-namespace
  name: mysql-volume-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  selector: 
    matchLabels: 
      app: mysql

Upvotes: 6

Related Questions