---
title: "Persistent volumes in a Managed Kubernetes cluster"
sidebar_label: "Persistent volumes"
sidebar_position: 2
description: "How to add, increase, and delete a persistent volume"
---

import Formbricks from '@theme/MDXComponents/Formbricks'
import {CustomTable} from '@selectel/docux/components'

# Persistent volumes in a Managed Kubernetes cluster

:::info

Cloud platform network volume-based persistent volume connectivity is not available in Managed Kubernetes clusters on dedicated servers.

:::

A Persistent Volume is used for long-term data storage in a Managed Kubernetes cluster. To manage persistent volumes in Kubernetes, you use [PersistentVolume (PV](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)), [PersistentVolumeClaim (PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)), and [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/#the-storageclass-resource) objects.

For persistent volumes in Managed Kubernetes, we recommend using [network volumes](/cloud-servers/volumes/about-network-volumes.mdx) from the Selectel cloud platform. You can create a persistent volume on a local disk, but the data will be deleted when the node is deleted.

After [creating](#create-persistent-volume) a persistent volume, you can [increase](#increase-persistent-volume) and [delete it](#delete-persistent-volume).

You can view all persistent volumes in the [control panel](https://my.selectel.ru/vpc/): in the top menu, click **Products** and select **Cloud Servers** → **Disks**.

## Create a persistent volume \{#create-persistent-volume}

:::info

Creation via the [Topology-Aware Volume Provisioning](https://kubernetes.io/blog/2018/10/11/topology-aware-volume-provisioning-in-kubernetes/) mechanism is not available.

:::

1. [Create a StorageClass](#1-create-storageclass) or use an existing one.
2. [Create a PersistentVolumeClaim](#2-create-persistentvolumeclaim).
3. [Create a pod with a persistent volume](#3-create-pod-with-persistent-volume).

### 1. Create a StorageClass \{#1-create-storageclass}

To create a PersistentVolume, use the [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) object. StorageClass allows you to predefine the configuration of persistent volumes required for cluster operations.

When a [cluster is created](/managed-kubernetes/create/create-cloud-cluster.mdx), a single StorageClass will be automatically created with a fast (fast) network volume in the pool where the cluster node group is located.

1. Create a YAML file with a manifest for the StorageClass object.

   An example of a StorageClass manifest for a fast disk in the ru-1a pool:

   ```yaml
   kind: StorageClass
   apiVersion: storage.k8s.io/v1
   metadata:
     name: fast.ru-1a
   provisioner: cinder.csi.openstack.org
   parameters:
     type: fast.ru-1a
     availability: ru-1a
     fsType: ext4
   allowVolumeExpansion: true
   ```

   Here, `fast.ru-1a` is a [StorageClass type](#storageclass-type).

   You can use other [predefined StorageClass manifests](https://github.com/selectel/kubernetes-examples/tree/master/storageclasses).

2. Apply the manifest:

   ```bash
   kubectl apply -f <file_name>
   ```

   Specify `<file_name>` — the name of the YAML file with the manifest for creating a new StorageClass. For example, `storage-class.yaml`.

3. Make sure that the StorageClass object is created:

   ```bash
   kubectl get sc
   ```

   The response will contain a list of created StorageClass objects. For example:

   ```bash
   NAME         PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
   fast.ru-1a   cinder.csi.openstack.org   Delete          Immediate           true                   16m
   ```

#### StorageClass type \{#storageclass-type}

The StorageClass type format is `<disk type>.<pool segment where it is located>`.

Disk types correspond to [network volumes](/cloud-servers/volumes/about-network-volumes.mdx) of the Selectel cloud platform:

<CustomTable>
  <table>
    <tbody>
      <tr>
        <th>Network volume type</th><td>Name in StorageClass</td>
      </tr>

      <tr>
        <th>Fast SSD</th><td>fast</td>
      </tr>

      <tr>
        <th>Basic HDD</th><td>basic</td>
      </tr>

      <tr>
        <th>Basic SSD</th><td>basicssd</td>
      </tr>

      <tr>
        <th>Universal SSD</th><td>universal</td>
      </tr>
    </tbody>
  </table>
</CustomTable>

For example, to create a fast disk in a pool segment of the ru-1a pool, you must add the following to the StorageClass description:

```yaml
parameters:
  type: fast.ru-1a
  availability: ru-1a
```

### 2. Create a PersistentVolumeClaim \{#2-create-persistentvolumeclaim}

:::info

Volumes can only be used in ReadWriteOnce mode — a single volume can be mounted to only one node, and only one pod can be connected to the persistent volume. Connecting multiple pods to a single PV may result in data corruption. To use ReadWriteMany mode (mounting a volume to multiple nodes), you can [connect network file storage to cluster nodes](/file-storage/add/add-storage-to-managed-kubernetes-cluster-in-one-pool.mdx).

:::

1. Create a YAML file with a manifest for the PersistentVolumeClaim (PVC) object.

   Example of a manifest:

   ```yaml
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: my-pv-claim
   spec:
     storageClassName: fast.ru-1a
     accessModes:
       - ReadWriteOnce
     resources:
       requests:
         storage: 10Gi
   ```

   The pool in the PVC manifest must match the pool of the node to which you plan to connect this PVC. If you use multiple pools for cluster nodes and PVCs, specify their pool binding in the Pod object descriptions.

2. Apply the manifest:

   ```bash
   kubectl apply -f <file_name>
   ```

   Specify `<file_name>` — the name of the YAML file with the manifest for creating a new PersistentVolumeClaim. For example, `pvc.yaml`.

### 3. Create a pod with a persistent volume \{#3-create-pod-with-persistent-volume}

If you create a pod ([Pod](https://kubernetes.io/docs/concepts/workloads/pods/)) with a persistent volume, the volume is preserved when the pod is deleted.

1. Create a YAML file with a manifest for creating a new pod with a persistent volume.

   Example of a manifest:

   ```yaml
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
     labels:
       app: webservice
   spec:
     containers:
     - name: nginx
       image: library/nginx:1.17-alpine
       ports:
       - containerPort: 80
       volumeMounts:
         - mountPath: "/var/www/html"
           name: data
     volumes:
       - name: data
         persistentVolumeClaim:
           claimName: my-pv-claim
   ```

   When creating a pod with the `securityContext.fsGroup` parameter, the persistent volume will not be mounted with the corresponding GID. To resolve this issue, add `fsType: ext4` to the StorageClass parameters.

2. Apply the manifest:

   ```bash
   kubectl apply -f <file_name>
   ```

   Specify `<file_name>` — the name of the YAML file with the manifest for creating a new pod with a persistent volume. For example, `pod-with-pv.yaml`.

3. Check that the PersistentVolume is created:

   ```bash
   kubectl get pv
   ```

   The response will contain a list of PersistentVolumes. For example:

   ```bash
   NAME CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
   pvc-f171f94c-0d38-41be-947e-2f5d7e46a6c3   10Gi       RWO            Delete           Bound    default/my-pv-claim   fast.ru-1a              97s
   ```

## Increase a persistent volume \{#increase-persistent-volume}

1. [Check the occupied space in the PersistentVolumeClaim](#1-check-occupied-space-in-pvc).
2. [Make sure you have enough quotas to increase the PersistentVolume](#2-check-quotas).
3. [Allow volume expansion in the StorageClass settings](#3-allow-permanent-persistent-volume-increase).
4. [Delete the pods with the volume that needs to be resized](#4-delete-pods-with-volume-to-be-increased).
5. [Edit the PersistentVolumeClaim manifest](#5-edit-persistentvolumeclaim-manifest).

### 1. Check the occupied space in the PVC \{#1-check-occupied-space-in-pvc}

Find out the amount of occupied space in the PVC:

```bash
kubectl -n <namespace> exec <pod_name> -- df -ah
```

Specify:

* `<namespace>` — the namespace where the PVC is located;
* `<pod_name>` — the name of the pod using the PVC.

### 2. Check quotas \{#2-check-quotas}

To ensure there are enough resources to increase the persistent volume, check your [quotas](/access-control/projects/quotas.mdx#quotas) and [change](/access-control/projects/quotas.mdx#change-quotas) them if necessary.

### 3. Allow increasing the persistent volume \{#3-allow-permanent-persistent-volume-increase}

In the StorageClass object parameters, specify `allowVolumeExpansion: true`.

Example of a manifest:

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: example-vol-default
provisioner: vendor-name.example/magicstorage
parameters:
 resturl: "http://192.168.10.100:8080"
 restuser: ""
 secretNamespace: ""
 secretName: ""
allowVolumeExpansion: true
reclaimPolicy: Delete
```

### 4. Delete pods with the volume that needs to be increased \{#4-delete-pods-with-volume-to-be-increased}

1. Check which pods are using the PVC:

   ```bash
   kubectl describe pvc <pvc_name>
   ```

   Specify `<pvc_name>` — the name of the PersistentVolumeClaim.

2. Delete the pods that are using the PVC:

   ```bash
   kubectl delete pod <pod_name>
   ```

   Specify `<pod_name>` — the name of the pod.

### 5. Edit the PersistentVolumeClaim manifest \{#5-edit-persistentvolumeclaim-manifest}

1. Open the YAML file with the PersistentVolumeClaim manifest and change the `storage:` parameter:

   ```yaml
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: my-pv-claim
   spec:
     storageClassName: fast.ru-1a
     accessModes:
       - ReadWriteOnce
     resources:
       requests:
         storage: 10Gi
   ```

2. Apply the manifest:

   ```bash
   kubectl apply -f <pvc_name>
   ```

   Specify `<pvc_name>` — the name of the PersistentVolumeClaim.

3. Run the pod using this PVC.

   Example of a manifest:

   ```yaml
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
     labels:
       app: webservice
   spec:
     containers:
     - name: nginx
       image: library/nginx:1.17-alpine
       ports:
       - containerPort: 80
       volumeMounts:
         - mountPath: "/var/www/html"
           name: data
     volumes:
       - name: data
         persistentVolumeClaim:
           claimName: my-pv-claim
   ```

4. Check that the PersistentVolumeClaim is created:

   ```bash
   kubectl get pvc
   ```

## Delete a persistent volume \{#delete-persistent-volume}

If you no longer need the persistent volume, delete the PersistentVolumeClaim that was used to create this volume.

The PV will be deleted immediately if the `persistentVolumeReclaimPolicy: Delete` parameter is specified in the PVC manifest. Learn more about the, return policy (Reclaim policy) in the [Reclaiming](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#reclaiming) article in the Kubernetes documentation.

1. Check which pods are bound to the PVC:

   ```bash
   kubectl describe pvc <pvc_name>
   ```

   Specify `<pvc_name>` — the name of the PersistentVolumeClaim.

2. Delete the pods that are using the PVC:

   ```bash
   kubectl delete pod <pod_name>
   ```

   Specify `<pod_name>` — the name of the pod.

3. Delete the PVC to which the PV is bound:

   ```bash
   kubectl delete pvc <pvc_name>
   ```

   Specify `<pvc_name>` — the name of the PersistentVolumeClaim.

<Formbricks />
