//
import CodeBlock from '@/components/mdx/CodeBlock'
import Tip from '@/components/mdx/Tip'
import Terminal from '@/components/mdx/Terminal'
import OutputBlock from '@/components/mdx/OutputBlock'
export const meta = { title: 'Kubernetes Storage and Persistence', description: 'Detailed exploration of storage solutions in Kubernetes.', lastUpdated: '2026-05-15', readTime: '10 min read', order: 61 }
# Kubernetes Storage and Persistence
## Introduction
In the world of container orchestration, managing data persistence is a critical aspect. Kubernetes provides robust mechanisms to ensure that your applications can store and retrieve data reliably, even in the face of node failures or pod rescheduling. This tutorial will delve into the various storage solutions available in Kubernetes, including Persistent Volumes (PVs), Persistent Volume Claims (PVCs), Storage Classes, and more.
## Concept
### Persistent Volumes (PVs)
A PersistentVolume is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes. PVs are resources in the cluster just like nodes are cluster resources. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual pod that uses them.
### Persistent Volume Claims (PVCs)
A PersistentVolumeClaim is a request for storage by a user. It is similar to how Pods consume node resources. PVCs allow users to abstract away the underlying details of the storage implementation and focus on what they need in terms of capacity, access modes, and other parameters.
### Storage Classes
Storage Classes provide a way for administrators to describe the "classes" of storage they offer. Different classes might map to quality-of-service levels, backup policies, or replication policies. Storage Classes are used by PVCs to request dynamic provisioning.
### Access Modes
Access modes define how a volume can be mounted:
- **ReadWriteOnce (RWO)**: The volume can be mounted as read-write by a single node.
- **ReadOnlyMany (ROX)**: The volume can be mounted as read-only by many nodes.
- **ReadWriteMany (RWX)**: The volume can be mounted as read-write by many nodes.
### Volume Modes
Kubernetes supports two types of volumes:
- **Filesystem**: This is the default mode, where the volume is exposed as a filesystem.
- **Block**: In this mode, the raw block device is exposed to the container. This is useful for databases that require direct access to storage devices.
## Examples
### Creating a Persistent Volume (PV)
Let's start by creating a simple PV using hostPath. This is suitable for single-node clusters or testing purposes but not recommended for production environments.
<CodeBlock language="yaml">
{`apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"`}
</CodeBlock>
### Creating a Persistent Volume Claim (PVC)
Next, we create a PVC that requests the PV we just defined.
<CodeBlock language="yaml">
{`apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi`}
</CodeBlock>
### Using a PVC in a Pod
Now, let's create a pod that uses the PVC.
<CodeBlock language="yaml">
{`apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: example-container
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: example-volume
volumes:
- name: example-volume
persistentVolumeClaim:
claimName: example-pvc`}
</CodeBlock>
### Dynamic Provisioning with Storage Classes
For dynamic provisioning, we need to define a Storage Class.
<CodeBlock language="yaml">
{`apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate`}
</CodeBlock>
With this Storage Class, we can create a PVC that requests dynamic provisioning.
<CodeBlock language="yaml">
{`apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard`}
</CodeBlock>
### Using a Storage Class in a Pod
Finally, let's create a pod that uses the dynamically provisioned PVC.
<CodeBlock language="yaml">
{`apiVersion: v1
kind: Pod
metadata:
name: dynamic-pod
spec:
containers:
- name: dynamic-container
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: dynamic-volume
volumes:
- name: dynamic-volume
persistentVolumeClaim:
claimName: dynamic-pvc`}
</CodeBlock>
## What's Next?
In the next section, we will explore Kubernetes Multitenancy, which involves managing multiple teams or applications on a single cluster while ensuring isolation and security.
By understanding these concepts and examples, you should have a solid foundation for managing storage in your Kubernetes clusters.