Sunday, November 8, 2026

PersistentVolumeClaim RWO

 ReadWriteOnce (RWO) is sufficient for your PostgreSQL volume if the PostgreSQL Pod runs on a single node. It is also sufficient for multiple Pods sharing a filesystem, provided all those Pods are scheduled on the same node.

However, there is an important distinction: multiple Pods accessing the same volume is not the same as multiple PostgreSQL instances accessing the same database directory.

You should not allow multiple independent PostgreSQL server instances to write to the same PostgreSQL data directory.

1. What does accessModes: ReadWriteOnce mean?

Kubernetes supports these access modes:

Access mode

Meaning

Multiple Pods, same node

Multiple nodes

ReadWriteOnce (RWO)

Read/write access from one node

Yes

No, not concurrently

ReadOnlyMany (ROX)

Read-only access from multiple nodes

Yes

Yes, if backend supports it

ReadWriteMany (RWX)

Read/write access from multiple nodes

Yes

Yes, if backend supports it

ReadWriteOncePod (RWOP)

Read/write access restricted to one Pod

No

No

RWO is a node-level access mode, not a Pod-level access mode.

For example:

Both Pods can mount the same RWO PVC because they are on the same node and the underlying volume supports it.

2. What happens with multiple Minikube nodes?

Suppose your Minikube profile contains three nodes:

Minikube cluster: myapp-dev
│
├── Node 1: minikube
│   ├── PostgreSQL Pod
│   └── Local PV: /data/myapp/postgres
│
├── Node 2: minikube-m02
│   └── API Server Pod
│
└── Node 3: minikube-m03
    └── AI Core Pod

Your local PostgreSQL PV is tied to Node 1.

The PostgreSQL volume cannot be mounted on Node 2 or Node 3 because it is local to Node 1.

But this does not prevent your API Server and AI Core from accessing PostgreSQL.

They should access PostgreSQL over the Kubernetes network using a Service:

API Server Pod (Node 2)
       |
       | TCP 5432
       v
postgres-service
       |
       v
PostgreSQL Pod (Node 1)

Your API Server and AI Core should not mount the PostgreSQL data PVC. They only need the PostgreSQL connection string.

For example:

postgresql://user:password@postgres-service:5432/myapp

3. PostgreSQL PVC vs shared-files PVC

Your generator has created two volumes:

Volume

Host path

Intended use

Recommended access

PostgreSQL PV

/data/myapp/postgress

Database files

RWO

Shared-files PV

/data/myapp/shared

Files shared between AI Core and API

RWO for single-node; RWX-capable backend for cross-node

These volumes have different requirements.

PostgreSQL: Only the PostgreSQL server Pod should mount the data PVC. Other application Pods communicate through the PostgreSQL Service.

Shared files: Both AI Core and API Server may need to mount the same PVC. With a local RWO volume, they must run on the node hosting that storage.

If the application scales across multiple nodes, you should consider NFS, a CSI driver backed by shared storage, or object storage for application-generated files.

4. Problems in your generated YAML

There are several issues worth correcting.

First, the YAML has capitalization and spelling errors. Kubernetes fields and access mode values are case-sensitive.

For example:

Your YAML

Correct

REadWriteOnce

ReadWriteOnce

Capacity

capacity

Required

required

matchExperssions

matchExpressions

noteSelectorTErms

nodeSelectorTerms

Kubernetes.io/hostnames

kubernetes.io/hostname

Type

type

Second, your PV uses hostPath together with nodeAffinity.

For production-style node-local persistent storage, I recommend using the local PV source instead of hostPath.

hostPath is primarily suitable for single-node development and testing. It can also create security and scheduling risks if used without careful controls.

Third, your host paths are under /data, whereas your previously defined customer storage allocation places application and PostgreSQL data under /apps. The production values should preserve that allocation.

5. Recommended corrected PostgreSQL PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: myapp-postgres-pv
spec:
  capacity:
    storage: 20Gi

  volumeMode: Filesystem

  accessModes:
    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  storageClassName: myapp-local

  local:
    path: /apps/postgres_data1

  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - customer-node-1

The directory must already exist on the specified node, with correct filesystem permissions. Replace customer-node-1 with the actual Kubernetes node hostname.

For Minikube, you can use a different PV definition with the appropriate node hostname and development storage path.

6. How to check where your Pods are running

kubectl get nodes
kubectl get pods -n ai-lab -o wide

The second command displays the node hosting each Pod.

To inspect your PV:

kubectl get pv
kubectl describe pv myapp-postgres-pv

To inspect your PVC:

kubectl get pvc -n ai-lab

To validate the generated YAML:

kubectl apply --dry-run=server -f your-pv.yaml

For a Helm-generated PV, render the template first and validate the rendered manifest.

7. Final recommendation for your application

Scenario

PostgreSQL storage

Shared application files

Single-node Minikube

RWO local PV/PVC

RWO local PV/PVC

Multi-node Minikube

RWO local PV, pinned to one node

RWX shared storage, or pin both application Pods to the storage node

Single-node customer Kubernetes

RWO local PV under /apps

RWO local PV under /apps

Future multi-node production

RWO storage with suitable node placement and recovery strategy

RWX-capable storage or object storage

For your current single-node customer deployment, RWO is sufficient for both PostgreSQL and shared files.

For multi-node Minikube, PostgreSQL can remain on one node while AI Core and API Server communicate with it over the network. However, the shared-files PVC requires special consideration because both application Pods must access the same files.

One final point: Kubernetes access modes are not a database concurrency-control mechanism or a security boundary. RWO does not prevent two PostgreSQL processes on the same node from attempting to use the same data directory. Ensure your PostgreSQL deployment has only one active database instance using that directory.

No comments:

Post a Comment