- When To Use Persistent Volumes
- Container Storage Interface (CSI) drivers
- Static provisioning
- Dynamic provisioning
- Жизненный цикл PV и PVC
- Подготовка
- Привязка
- С использованием
- Восстановление
- What problems does it solve?
- Linking Persistent Volumes to Pods
- NFS хранилище в качестве Persistence Volume
- Подключаем хранилище к поду
- Data persistence in Kubernetes
- Kubernetes volumes
- Ephemeral storage
- Persistent Volume Life Cycle
- Binding
- Using
- Reclaiming
- Infrastructure as Code on AWS
- Cloud Automation
- Infrastructure as Code on Azure
- CI/CD Pipeline
- Kubernetes Statefulset
- Storage Classes
- Types of Persistent Volumes (PV)
- In-Tree Plugins
- CSI Plugins
- Работа с дисками в Kubernetes
- What is Persistent Volume(PV)?
- How can you Create persistent volume?
- Step 1- Prerequisites
- Step 2 — Create a persistent volume configuration (jhooq-pv. yml)
- Step 3 — Apply the configuration
- Step 4 — Lets check the status of PV
- What is Persistent Volume claim?
- How to use Persistent Volume claim(PVC) ?
- Step 1 — Alright lets create your first Persistent Volume Claim(jhooq-pvc. yml) —
- Step 2 — Now apply this configuration using the following command
- Step 3 — Lets check our Persistent Volume and persistent Volume Claim
- Create a POD using Persistent Volume claim
- Step 1 — Create POD configuration yml. — «jhooq-pod. yml»
- Lets apply the pod configuration
- Test the microservice deployed under the POD
- Pros and Cons
- Conclusion
- Reclaim Policy
- Decoupling pods from the storage
- Backend technology
- Persistent volume claims
- Концепции хранилища Kubernetes
- Плагины CSI для Kubernetes
- Local Persistent Volume — хранилище Kubernetes на локальных дисках
- Работа с PV в кластере
- Работа с постоянными томами
- Создайте файл на узле
- Создайте постоянный том
- Шаг 3. Создание заявки на постоянный том
- Создайте модуль и смонтируйте PVC как том
- Шаг 5. Убедитесь, что у модуля есть доступ к постоянному хранилищу
- Persistent Volumes Features
- Demonstrating Persistence
- Learn More about Kubernetes Persistent Volume
- Storage Abstraction on Kubernetes
- Advanced Features on K8s with Cloud Volumes ONTAP
- Managing Persistent Volumes With kubectl
- Common Causes and Resolution [C]
When To Use Persistent Volumes
You should use a persistent volume whenever you have data that needs to outlive individual pods. Unless the data is transitory or specific to a single container, it’s usually best stored in a persistent volume.
Here are some common use cases:
- Log storage: Writing container log files to a persistent volume ensures they’ll be available after a crash or termination. If they’re not written to a persistent volume, the crash will destroy the logs that could have helped you debug the issue.
- Protection of important data: Persistent volumes let you avoid accidental data deletion. They include safeguards that prohibit the removal of volumes that are actively used by pods.
- Data independent of pods: Persistent volumes make sense whenever your data is of primary importance in your cluster. They give you the tools to manage data independently of application containers, making it easier to handle backups, performance, and storage capacity allocations.
Container Storage Interface (CSI) drivers
The Container Storage Interface (CSI) is an abstraction designed to facilitate using different storage solutions with Kubernetes. Different storage vendors can develop their own drivers that implement the CSI standards, enabling their storage solutions to work with Kubernetes (regardless of the internals of the underlying storage solution). AWS has CSI plugins for Amazon EBS, Amazon EFS , and Amazon FSx for Lustre.
Static provisioning
- Create an Amazon EFS file system volume.
- Copy and paste its filesystem ID to a PV YAML definition file.
- Create the PV using a YAML file.
- Kubernetes application developer’s task
Create a PVC to claim this PV.Mount the PVC to the Pod object in the Pod YAML definition file. - Create a PVC to claim this PV.
- Mount the PVC to the Pod object in the Pod YAML definition file.
This works, but would become time consuming to do at scale.
Dynamic provisioning
With dynamic provisioning, you do not have to create a PV object. Instead, it will be automatically created under the hood when you create the PVC. Kubernetes does so using another object called Storage Class.
A Storage Class essentially contains two things:
- Name: This is the name, which uniquely identifies the storage class object.
- Provisioner: This defines the underlying storage technology. For example, provisioner would be efs.csi.aws.com for Amazon EFS or ebs.csi.aws.com for Amazon EBS.
The Storage Class objects are the reason why Kubernetes is capable of dealing with so many different storage technologies. From a Pod perspective, no matter whether it is an EFS volume, EBS volume, NFS drive, or anything else, the Pod will only see a PVC object. All the underlying logic dealing with the actual storage technology is implemented by the provisioner the Storage Class object uses.

Жизненный цикл PV и PVC
PVC — это запрос на PV, который существует как ресурс хранения в кластере Kubernetes. PVC привязан к соответствующему PV, чтобы обеспечить постоянное хранение. В результате жизненный цикл PV и PVC обычно тесно связан.
Подготовка
Kubernetes предоставляет следующие типы подготовки для постоянного хранилища:
Привязка
Контур управления отслеживает новые PVC. Как только пользователь создает новый PVC, контур управления ищет марширующий PV, который соответствует требованиям PVC. Он надеется удовлетворить запрошенный объем хранилища и может сделать это, используя PV, который превышает запрос. Вот как работает этот процесс:
С использованием
Поды Kubernetes используют PVC в качестве томов. Пользователи могут указать режим доступа для PVC, и кластер монтирует привязанный PV к модулю. При использовании томов, поддерживающих несколько режимов доступа, пользователь должен указать нужный режим. Как только пользователь получает связанный PVC, связанный PV также принадлежит этому пользователю.
Восстановление
Когда пользователю больше не нужно использовать том, его можно удалить или сохранить. Пользователи могут удалить объект PVC непосредственно из API, что позволяет им восстановить этот ресурс. В противном случае политика восстановления PV определяет, что кластер должен делать с томом, который был освобожден из-за его претензии.
What problems does it solve?
- All the files inside the container are temporary which means if you terminate the container you are going to lose all your files.
- Secondly if in any case, your container crashes then there is no way to recover files.
Kuberenetes provides volume plugin as Persistent Volume to address the above problems.
The lifecycle of these volumes are independent of the lifecycle of pods.
So if PODs are terminated then volumes are unmounted and detached keeping the data intact.
How to use Persistent Volume and Persistent Claims
https://youtube.com/watch?v=1FTJQOvAGOY%3Fcontrols%3D1%26rel%3D0
Linking Persistent Volumes to Pods
Persistent volumes are linked to pods by means of a persistent volume claim. A claim represents a pod’s request to read and write files within a particular volume.
Persistent volume claims are stand-alone objects. Here’s what it looks like to claim the example volume created earlier:
The volumeName field references the previously created persistent volume. When you link this claim to a pod, the pod will receive access to the example-pv volume. The empty storageClassName field is intentional and causes the claim to use the storage class set within the persistent volume’s definition.
The claim now has accessModes and storageClassName fields to configure the volume that’ll be created. The volume’s capacity is defined via the resources.requests.storage field. Please note that this is a slightly different format from a stand-alone persistent volume.
Apply the claim to your cluster using kubectl:
$ apply -f pvc.yaml
Provided that you’ve specified a storage class that’s available in your cluster, the claim creation should succeed, even if the stand-alone volume creation failed with an error. The storage class will dynamically provision a new persistent volume that satisfies the claim.
Finally, you can link the claim to your pods using the volumes and volumeMount fields in the pod manifest:
Then add the pod to your cluster:
$ apply -f pvc-pod.yaml
The persistent volume claim is referenced by the pod’s spec.volumes field. This sets up a pod volume called pv, which can be included in the containers section of the manifest and is mounted to /pv-mount. Files written to this directory in the container will be stored in the persistent volume, letting them outlive the individual container instances.
NFS хранилище в качестве Persistence Volume
Для простоты я взял в качестве хранилища nfs сервер. Для него не существует встроенного Provisioner, как к примеру, для Ceph
у нас установлен nfs сервер:
192.168.1.82 с директорией /nfs
и клиент, наш миникуб
192.168.1.120 с директорией /nfs-client
на клиенте не забываем поставить все необходимые пакеты:
Создаем yaml файл pv-nfs.yaml с описанием Persistence Volume на основе .
persistentVolumeReclaimPolicy — что будет происходить с pv после удаления pvc. Могут быть 3 варианта:
- Retain — pv удален не будет.
- Recycle — pv будет очищен.
- Delete — pv будет удален.
Так как у нас нет Provisioner для nfs, удалять автоматически pv не получится. Так что у нас только 2 варианта — либо оставлять данные (retain), либо очищать том (recycle).
Добавляем описанный pv в кластер kubernetes.
Проверяем список pv и pvc

Мы просили в pvc только 1 Гб хранилища, но в pv было только хранилище с 10 Гб и оно было выдано. Как я и говорил раньше. Так что в случае ручного создания и нужно самим следить за размером .
Подключаем хранилище к поду
Теперь подключим наш в виде volume к какому-нибудь поду. Опишем его в конфиге pod-with-nfs.yaml
Применяем.
# kubectl apply -f pod-with-nfs.yaml
Затем проверяйте статус запущенного пода.
Зайдем в его консоль и посмотрим, подмонтировалась ли nfs шара.
# kubectl exec -it pod-with-nfs sh
Попробуем теперь что-то записать в шару. Снова заходим на под и создаем текстовый файл.
Теперь запустим еще один под и подключим ему этот же pvc. Для этого просто немного изменим предыдущий под, обозвав его pod-with-nfs2.
Запускаем под и заходим в него.
# kubectl apply -f pod-with-nfs2.yaml
# kubectl exec -it pod-with-nfs2 sh
# cat /mnt/nfs/test.txt
test text
Все в порядке, файл на месте. С внешними хранилищем в Kubernetes закончили.
Data persistence in Kubernetes
When running a stateful application, and without persistent storage, data is tied to the lifecycle of the pod or container. If a pod crashes or is terminated, data is lost.

To prevent this data loss and run a stateful application on Kubernetes, we need to adhere to three simple storage requirements:
- Storage must not depend on the pod lifecycle.
- Storage must be available from all pods and nodes in the Kubernetes cluster.
- Storage must be highly available regardless of crashes or application failures.
Kubernetes volumes
Kubernetes has several types of storage options available, not all of which are persistent.
Ephemeral storage
An ephemeral Kubernetes Volume solves both of the problems faced with ephemeral storage. An ephemeral Volume‘s lifetime is coupled to the Pod. It enables safe container restarts and sharing of data between containers within a Pod. However as soon as the Pod is deleted, the Volume is deleted as well, so it still does not fulfill our three requirements.

The temporary file system is tied to the lifecycle of the container; the ephemeral Volume is tied to the lifecycle of the pod
Persistent Volume Life Cycle
Here are the two main types of provisioning:
Binding
Here is a quick rundown of how the binding process works:
- A control loop, located in the master, looks for new PVCs, and then:
Static — the control loop attempts to find a matching PV and then binds it to the PVC.Dynamic — if a PV was already dynamically provisioned for the PVC, the control loop binds them together. - Static — the control loop attempts to find a matching PV and then binds it to the PVC.
- Dynamic — if a PV was already dynamically provisioned for the PVC, the control loop binds them together.
- After a PVC and a PV are bound, they remain exclusive.
A PVC to PV binding is a one-to-one mapping. The process uses a ClaimRef, which creates a bi-directional binding between the PV and the PVC.
Using
Pods use claims as volumes. Here is how the using process works:
Reclaiming
Together with our content partners, we have authored in-depth guides on several other topics that can also be useful as you explore the world of DevOps.
Infrastructure as Code on AWS
Learn how to implement IaC on AWS using a wide range of techniques, including guides for Ansible and Terraform implementations.
See top articles in our guide to IaC on AWS:
Cloud Automation
Learn about cloud automation techniques and tools, including IaC deployments with Ansible, OpenShift, and tips for DevOps pipelines.
See top articles in our cloud automation guide:
Infrastructure as Code on Azure
Learn how IaC works on Azure, and how to combine first-party services and resources with third-party tools like Terraform.
See top articles in our IaC on Azure guide:
CI/CD Pipeline
Learn how modern development teams create an automated pipeline that pushes new software versions from development through to testing and production environments.
Kubernetes Statefulset
Learn about the Kubernetes StatefulSet object that lets you manage and automate stateful applications, like databases, in a Kubernetes cluster.
Storage Classes
StorageClass позволяет описать классы хранения, которые предлагают хранилища. Например, они могут отличаться по скорости, по политикам бэкапа, либо какими-то еще произвольными политиками. Каждый StorageClass содержит поля provisioner, parameters и reclaimPolicy, которые используются, чтобы динамически создавать PersistentVolume.
Можно создать дефолтный StorageClass для тех , которые его вообще не указывают. Так же storage class хранит параметры подключения к реальному хранилищу. используют эти параметры для подключения хранилища к подам.
Важный нюанс. зависим от namespace. Если у вас будет с секретом, то этот секрет должен быть в том же namespace, что и , с которого будет запрос на подключение.
Types of Persistent Volumes (PV)
Kubernetes comes with numerous plugins that let you make different types of storage resources available to nodes in the Kubernetes cluster.
In-Tree Plugins
These are plugins shipped together with the Kubernetes distribution, which are implemented using the StorageClass object. Here are some of the main plugins currently supported:
Read our blog post on the Kubernetes NFS integration.
CSI Plugins
Until recently, it was challenging to develop new storage volume plugins for Kubernetes. All volume plugins were “in tree”, meaning they were shipped together with the Kubernetes distribution, and vendors creating plugins had to align with the Kubernetes release process.
In 2019 Kubernetes adopted the Container Storage Interface (CSI), which made Kubernetes volumes extensible. Any storage equipment developer can easily write a CSI plugin exposing their storage system, without having to touch the core Kubernetes code. Here is the full list of CSI drivers available for use with Kubernetes.
Read our blog post on Container Storage Interface (CSI).
Работа с дисками в Kubernetes
Работа с дисковыми томами в Kubernetes проходит по следующей схеме:
- Вы описываете типы файловых хранилищ с помощью Storage Classes и Persistent Volumes. Они могут быть совершенно разными от локальных дисков до внешних кластерных систем и дисковых полок.
- Для подключения диска к поду вы создаете Persistent Volume Claim, в котором описываете потребности пода в доступе к хранилищу — объем, тип и т.д. На основе этого запроса используются либо готовые PV, либо создаются под конкретный запрос автоматически с помощью PV Provisioners.
- В описании пода добавляете информацию о Persistent Volume Claim, который он будет использовать в своей работе.
What is Persistent Volume(PV)?
It’s basically a directory with some data in it and all the containers running inside the pods can access it. But Persistent Volumes are independent of the POD life cycle.
So if PODs live or die, persistent volume does get affected and it can be reused by some other PODs.
Kubernetes provides many volume plugins based on the cloud service provider you are using —
How can you Create persistent volume?
There are some prerequisites before you create your persistent volume
Step 1- Prerequisites
- Kubernetes Cluster: — You should have Kubernetes cluster up and running (If you do not know «How to setup then please refer to this article)
- Directory for persistent Volume storage:- Create one directory .i.e. /home/vagrant/storage inside your Linux machine for persistent volume. You can keep the directory name and path as per your need
Once you are done with all the 3 prerequisites then your ready to proceed.
Step 2 — Create a persistent volume configuration (jhooq-pv. yml)
I saved the above configuration with name jhooq-pv.yml but you can assign any name of your choice.
In step 1 we have created Persistent Volume for Local Storage, now you need to apply the configuration.
Step 3 — Apply the configuration
kubectl apply -f jhooq-pv.yml
Now you have created the persistent volume with the name «jhooq-demo-pv» inside the Kubernetes cluster
Step 4 — Lets check the status of PV
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
jhooq-demo-pv 1Gi RWO Retain Available local-storage 9s
Here is the screen of the status
create kubernetes persistent volume for local storage
Great now you have created PV, let’s move ahead and create a Persistent Volume claim.
What is Persistent Volume claim?
Persistent volume provides you an abstraction between the consumption of the storage and implementation of the storage.
In the nutshell you can say its a request for storage on behalf of an application which is running on cluster.
How to use Persistent Volume claim(PVC) ?
If you as an application developer wants to use/access Persistent Volume(PV) then you must create a request for storage and it can be done by creating PVC objects.
Step 1 — Alright lets create your first Persistent Volume Claim(jhooq-pvc. yml) —
Save the above configuration with file name of your choice, in mycase I am saving this file with the name jhooq-pvc.yml
Step 2 — Now apply this configuration using the following command
kubectl create -f jhooq-pvc.yml
Step 3 — Lets check our Persistent Volume and persistent Volume Claim
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jhooq-pvc Bound jhooq-demo-pv 1Gi RWO local-storage 17h
create persistent volume claim in your kubernetes cluster
Create a POD using Persistent Volume claim
Now in this step we are going to create a POD using the PV and PVC from the previous steps.
We are going to deploy Spring Boot Docker image but you can use any docker application of your choice. But if you do not have any docker image with you then you can refer to — How to deploy spring boot application in Kubernetes cluster
Step 1 — Create POD configuration yml. — «jhooq-pod. yml»
—
—
—
—
One point you can note over here is we are using «persistentVolumeClaim» which is «jhooq-pvc» .
Lets apply the pod configuration
kubectl apply -f jhooq-pod.yml
Lets check the pod status
NAME READY STATUS RESTARTS AGE
jhooq-pod-with-pvc 1/1 Running 8m37s
Now you have deployed your pod successfully using the Persistent Volume and Persistent Volume Claim.
Test the microservice deployed under the POD
In this testing step we need to access the microservice which we deployed inside the POD.
To test the POD first we need to find the IP address on which it is running.
$ kubectl get pod -o wide
It should return you with (You may get different IP address) —
You should note down the IP address of the POD because we are going to use that IP address for accessing the microservice.
$ curl 10.233.90.3:8080/hello
Hello — Jhooq-k8s
If you are using my docker-image then it should return a message «Hello — Jhooq-k8s» but you can use any docker image or docker container of your choice.
Pros and Cons
After using the persistent volume and persistent volume claim, I must say its always beneficial to use both when you are working in the production environment because you can not just delete the data after the end of the POD cycle.
The most favorable use case which I can see setting up the database such as MySQL, Oracle, Postgress inside the persistent volume so that it is always there irrespective of your POD life cycle.
But here I collected some of the Pros and Cons of using PV and PVC —
- Storing and archiving the logs
- Setting up the database
- Useful for application handling a large number of batch jobs
- Storing configs of application
- Independent from PODs life-cycle
- Easy to use
- Easy to backup
- Can not be used to store transnational data for performance-intensive application
- You need to set up your own backup policies
- Couldn’t be used for HA(High Availability)
Conclusion
If you are reading this part of the blog post then I must say you have at least implemented PV and PVC inside your Kubernetes cluster. But to conclude it here is recap of what we did —
- Gone through the concepts of «What is Persistent Volume and Persistent Volume Claim»
- Then we created a Persistent Volume .i.e — jhooq-demo-pv with 1 Gi of storage
- Created the Persistent Volume Claim .i.e. — jhooq-pvc to use persistent volume jhooq-demo-pv
- Finally created the POD and deployed spring boot microservice.
Для простоты я взял в качестве хранилища PV nfs сервер. Для него не существует встроенного Provisioner, как к примеру, для Ceph. Возможно в будущем я рассмотрю более сложный пример с применением хранилища на основе ceph. Но перед этим надо будет написать статью про установку и работу с ceph.
Создаем yaml файл pv-nfs.yaml с описанием Persistence Volume на основе NFS.
Reclaim Policy
persistentVolumeReclaimPolicy — что будет происходить с pv после удаления pvc. Могут быть 3 варианта:
- Retain — pv удален не будет.
- Recycle — pv будет очищен.
- Delete — pv будет удален.
Так как у нас нет Provisioner для nfs, удалять автоматически pv не получится. Так что у нас только 2 варианта — либо оставлять данные (retain), либо очищать том (recycle).
Все остальное и так понятно, описывать не буду. Добавляем описанный pv в кластер kubernetes.
# kubectl apply -f pv-nfs.yml
Проверяем список pv и pvc
# kubectl get pv
# kebectl get pvc

Мы просили в pvc только 1 Гб хранилища, но в pv было только хранилище с 10 Гб и оно было выдано. Как я и говорил раньше. Так что в случае ручного создания PV и PVC нужно самим следить за размером PV.
Decoupling pods from the storage
Kubernetes also supports Persistent Volumes. With Persistent Volumes, data is persisted regardless of the lifecycle of the application, container, Pod, Node, or even the cluster itself. Persistent Volumes fulfill the three requirements outlined earlier.
A Persistent Volume (PV) object represents a storage volume that is used to persist application data. A PV has its own lifecycle, separate from the lifecycle of Kubernetes Pods.
A PV essentially consists of two different things:
- A backend technology called a PersistentVolume
- An access mode, which tells Kubernetes how the volume should be mounted.
Backend technology
A PV is an abstract component, and the actual physical storage must come from somewhere. Here are a few examples:
- iscsi: iSCSI (SCSI over IP) storage
- local: Local storage devices mounted on nodes
- nfs: Network File System (NFS) storage
Kubernetes is versatile and supports many different types of PVs. Kubernetes does not care about the underlying storage internals; it just gives us the PV component as an interface to the actual storage.
There are three major benefits to a PV:
- A PV is not bound to the lifecycle of a Pod: when removing a Pod that is attached to a PV object, the PV will survive.
- The preceding statement is also valid when a Pod crashes: the PV object will survive the fault and not be removed from the cluster.
- A PV is cluster-wide: it can be attached to any Pod running on any Node in the cluster.
All different backend storage technologies have their own performance characteristics and tradeoffs. For this reason, we see different types of PVs in production Kubernetes environments that depend on the application.
The access mode is set during PV creation and tells Kubernetes how the volume should be mounted. Persistent Volumes support three access modes:
- ReadWriteOnce: Volume allows read/write by only one node at the same time.
- ReadOnlyMany: Volume allows read-only mode by many nodes at the same time.
- ReadWriteMany: Volume allows read/write by multiple nodes at the same time.
Not all PersistentVolume types support all access modes.
Persistent volume claims
A Persistent Volume (PV) represents an actual storage volume. Kubernetes has an additional layer of abstraction necessary for attaching a PV to a Pod: the PersistentVolumeClaim (PVC).
A PV represents the actual storage volume, and the PVC represents the request for storage that a Pod makes to get the actual storage.
The separation between PV and PVC relates to the idea that there are two types of people in a Kubernetes environment:
Essentially, a Pod cannot mount a PV object directly. It needs to explicitly ask for it. And that asking action is achieved by creating a PVC object and attaching it to the Pod. This is the only reason why this additional layer of abstraction exists. PVCs and PVs have a one-to-one mapping (a PV can only be associated with a single PVC).

This blog post includes a demo of this process of attaching persistent storage to a Pod, but before that, we need to provide some background on CSI drivers.
Концепции хранилища Kubernetes
Kubernetes позволяет администраторам определять StorageClasses, которые абстрагируются от реализации хранилища. Это позволяет пользователям запрашивать конкретный StorageClass, относящийся к каждому PVC, без указания всех требований к хранилищу.
Администраторы могут создавать различные типы StorageClasses, каждый из которых определяется по-своему для поставщика, параметров и reclaimPolicy. Он позволяет настраивать StorageClasses, которые обеспечивают различную производительность, например HDD или SSD, затраты и приложения.
Средство подготовки позволяет привязать StorageClass к определенным бэкендам, таким как AWS EBS или Azure Files, и к конечной точке хранилища. Дополнительные параметры доступны в зависимости от выбранного поставщика, чтобы помочь вам описать тома для каждого StorageClass, используя такие параметры, как «тип», «зона», «сервер» или «путь».
Kubernetes StatefulSet — это объект API рабочей нагрузки для управления приложениями с отслеживанием состояния. Он позволяет определить набор модулей с уникальными сетевыми идентификаторами для развертывания и масштабирования в определенном порядке. StatefulSets помогает управлять постоянным хранилищем в кластере Kubernetes.
Плагины CSI для Kubernetes
Плагины Container Storage Interface (CSI) помогают сделать стороннее хранилище доступным для вашего кластера Kubernetes. Это помогает внедрить постоянное хранилище в контейнерные приложения. Подключаемые модули CSI получают запросы PVC, в которых сторонний поставщик указывается в качестве поставщика, а затем создают и монтируют запрошенный том.
Теперь подключим наш PVC в виде volume к какому-нибудь поду. Опишем его в конфиге pod-with-nfs.yaml
Затем проверяйте статус запущенного пода.
# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-with-nfs 0/1 ContainerCreating 0 80s
У меня он не стартовал. Я решил посмотреть из-за чего.
# kubectl describe pod pod-with-nfsУвидел в самом конце в разделе Messages ошибку:
Я сразу понял в чем проблема. На ноде, где стартовал под, не были установлены утилиты для работы с nfs. В моем случае система была Centos и я их установил.
# yum install nfs-utils nfs-utils-lib
После этого в течении минуты pod запустился. Зайдем в его консоль и посмотрим, подмонтировалась ли nfs шара.

Как видите, все в порядке. Попробуем теперь что-то записать в шару. Снова заходим на под и создаем текстовый файл.
Теперь запустим еще один под и подключим ему этот же pvc. Для этого просто немного изменим предыдущий под, обозвав его pod-with-nfs2.
Запускаем под и заходим в него.
# kubectl apply -f pod-with-nfs2.yaml
# kubectl exec -it pod-with-nfs2 sh
# cat /mnt/nfs/test.txt
test text

Все в порядке, файл на месте. С внешними хранилищем в Kubernetes закончили. Расскажу дальше, как можно работать с локальными дисками нод, если вы хотите их так же пустить в работу.
Local Persistent Volume — хранилище Kubernetes на локальных дисках
Локальные тома, как и nfs, не имеют встроенного провизионера, так что нарезать их можно только вручную, создавая . Есть внешний provisioner — https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner, но лично я его не проверял.
Создаем вручную pv-local-node-1.yaml, который будет располагаться на kub-node-1 в /mnt/local-storage. Эту директорию необходимо вручную создать на сервере.
Создаем pvc-local.yaml для запроса сторейджа, который передадим поду.
И в завершении создадим тестовый pod-with-pvc-local.yaml для проверки работы local storage.
Применяем все вышеперечисленное в строго определенном порядке:
После этого посмотрите статус всех запущенных абстракций.
Проверим, что Local Persistent Volume правильно работает. Зайдем в под и создадим тестовый файл.
Теперь идем на сервер kub-node-1 и проверяем файл.
Все в порядке. Файл создан.
Если у вас возникли какие-то проблемы с , то в будет ошибка:
И в это же время в поде:
Возникли ошибки из-за того, что в описании я ошибся в названии сервера, где будет доступен local storage. В итоге pod запускался, проверял pvc, а pvc смотрел на pv и видел, что адрес ноды с pv не соответствует имени ноды, где будет запущен pod. В итоге все висело в ожидании разрешения этих несоответствий.
Работа с PV в кластере
Проверим, есть ли у нас какие-то PV в кластере.
# kubectl get pv
No resources found.
Ничего нет. Попробуем создать и применить какой-нибудь PVC и проверим, что произойдет. Для примера создаем pvc.yaml следующего содержания.
Просим выделить нам 1 гб пространства с типом доступа ReadWriteMany. Применяем yaml.
# kubectl apply -f pvc.yaml
Ждем немного и проверяем статус pvc.
Статус pending. Проверяем почему так.
# kubectl get pvc

no persistent volumes available for this claim and no storage class is set
Все понятно. Запрос находится в ожидании, так как у нас в кластере нет ни одного PV, который бы удовлетворял запросу. Давайте это исправим и добавим одно хранилище для примера на основе внешнего nfs сервера.
Работа с постоянными томами
Это руководство основано на полном руководстве по постоянному хранилищу в документации Kubernetes.
Прежде чем приступить к этому руководству, настройте кластер Kubernetes на локальном компьютере только с одним узлом. Убедитесь, что kubectl установлен на вашем компьютере и успешно взаимодействует с кластером. Вы можете легко создать кластер из одного узла с помощью Minikube.
Создайте файл на узле
Поскольку мы работаем с постоянным хранилищем, нам нужно создать статический файл и продемонстрировать, что этот файл сохраняется даже после закрытия узла.
Откройте оболочку для своего узла, создайте каталог с именем /mnt/data и внутри него создайте файл index.html с текстом «Hello World Persistent Volume».
Создайте постоянный том
Чтобы создать постоянный том, откройте текстовый редактор и скопируйте и вставьте приведенный ниже код YAML.
Путь к хосту:
Сохраните файл YAML как my-pv-volume.yaml в локальном каталоге. Разверните постоянный том, выполнив следующую команду:
kubectl create -f my-pv-volume.yaml
Шаг 3. Создание заявки на постоянный том
Создайте спецификацию PVC, открыв текстовый редактор и скопировав приведенный ниже код YAML:
Сохраните файл в своем локальном каталоге под именем my-pv-claim.yaml. Разверните его с помощью этой команды:**
kubectl применить -f my-pv-claim.yaml
Создайте модуль и смонтируйте PVC как том
Теперь становится интереснее — давайте создадим модуль, который монтирует этот PVC, чтобы он мог использовать наш постоянный том. Скопируйте следующий код в текстовый редактор:
— имя: мой-pv-контейнер
Обратите внимание, что модуль определяет PVC, а не напрямую ссылается на PV. Kubernetes отвечает за сопоставление этого модуля с PV, который соответствует его требованиям, на основе информации в PVC. В нашем случае это просто, потому что есть только один PV.
Сохраните спецификацию пода в локальном каталоге под именем my-pv-pod.yaml. Разверните модуль, выполнив эту команду:
kubectl применить -f my-pv-pod.yaml
Убедитесь, что модуль работает:
kubectl получить pod my-pv-pod
Шаг 5. Убедитесь, что у модуля есть доступ к постоянному хранилищу
Давайте посмотрим, сможет ли наш модуль получить доступ к файлу, который мы сохранили в постоянном хранилище в начале руководства. Здесь важно то, что любой модуль, который вы создаете с использованием этой спецификации, будет иметь доступ к тому же хранилищу — даже после того, как вы закроете или удалите модуль, файл сохранится.
kubectl exec -it my-pv-pod — /bin/bash
Запустив корневую оболочку контейнера, выполните следующие команды:
способ установить завиток
Вы должны увидеть содержимое ваших файлов index.html:
«Постоянный том Hello World»
Поздравляем! Вы только что создали модуль, который имеет доступ к постоянному тому через заявку на постоянный том.
Persistent Volumes Features
Kubernetes Persistent Volumes offer powerful capabilities. The most important are detailed below.
Demonstrating Persistence
You can verify this behavior with a quick example.
Get a shell to the pod created earlier:
$ exec —stdin —tty pod-with-pvc — sh
Now write a file to the /pv-mount directory, which the persistent volume was mounted to:
Then detach from the container:
Use kubectl to delete the pod:
$ delete pods/pod-with-pvc
deleted
Recreate the pod by applying its YAML manifest again:
Get a shell to the container in the new pod and read the file from /pv-mount/demo:
$ exec —stdin —tty pod-with-pvc — sh
$ /pv-mount/demo
file is persisted
The content of the persistent volume was not affected by the first pod’s deletion. It can be remounted into new pods at any time, preserving everything that’s been previously written.
Learn More about Kubernetes Persistent Volume
A Kubernetes volume is a directory containing data, which can be accessed by containers in a Kubernetes pod. Understand the main types of Kubernetes volumes, including persistent volumes and ephemeral volumes, learn about volumeMounts, deploying volumes, and more.
Storage Abstraction on Kubernetes
This article is a side-by-side comparison of two technologies used to deploy Kubernetes persistent volumes for stateful applications: the open-source OpenEBS and NetApp’s Cloud Volumes ONTAP.
What are the tradeoffs between the two technologies, and which is right for enterprise-level Kubernetes deployments?
Advanced Features on K8s with Cloud Volumes ONTAP
As the backend storage management system for Kubernetes clusters, Cloud Volumes ONTAP provides a number of advanced features. This blog post gives you an overview of specific Cloud Volumes ONTAP features for Kubernetes-based stateful applications and takes a look at how enterprises can benefit from them.
Managing Persistent Volumes With kubectl
You can retrieve a list of your persistent volumes using kubectl:
$ get pv
CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
Similarly, you can view all your persistent volume claims:
$ get pvc
STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
If a volume or claim shows a Pending status, it’s usually because the storage class is still provisioning storage for the volume. You can check what’s holding up the process by using the describe command to view the object’s event history:
$ describe pvc example-pvc
Reason Age From Message
—— —- —- ——-
Provisioning 9m30s dobs.csi.digitalocean.com_master_68ea6d30-36fe-4f9f-9161-0db299cb0a9c External provisioner is provisioning volume for claim
ProvisioningSucceeded 9m24s dobs.csi.digitalocean.com_master_68ea6d30-36fe-4f9f-9161-0db299cb0a9c Successfully provisioned volume pvc-f90a46bd-fac0-4cb5-b020-18b3e74dd3b6
To edit your volumes and claims, it’s usually best to modify your YAML file and reapply it to your cluster with kubectl:
$ apply -f changed-file.yaml
This uses the Kubernetes declarative API model to automatically detect and apply the changes you made. If you’d prefer to use imperative commands, run the edit command to open the object’s YAML in your editor. Changes will be applied when you save and close the file:
$ edit pvc example-pvc
It’s not possible to change volume properties, such as access mode and storage class. Other fields, like the volume’s capacity, are implementation-dependent: most major storage classes support dynamic resizes, but this isn’t universal. You should consult your Kubernetes provider’s documentation if in doubt.
Don’t manually edit dynamically created persistent volume objects by adding a persistent volume claim. Edit the properties on the claim instead.
To remove a volume or a claim, use the delete command:
$ delete pvc example-pvc
deleted
This will empty and remove the storage that was provisioned by your provider. The data inside the volume will be non-recoverable unless separate backups have been made. Don’t delete volumes that were dynamically provisioned by a storage class: as with edits and creations, you should interact with the claim they were created for. The storage class will handle the persistent volume object for you.
Проверим, есть ли у нас какие-то в кластере.
Ничего нет. Попробуем создать и применить какой-нибудь и проверим, что произойдет. Для примера создаем pvc.yaml следующего содержания.
Просим выделить нам 1 гб пространства с типом доступа ReadWriteMany. Применяем yaml.
Ждем немного и проверяем статус pvc.
StorageClass позволяет описать классы хранения, которые предлагают хранилища. Например, они могут отличаться по скорости, по политикам бэкапа, либо какими-то еще произвольными политиками. Каждый StorageClass содержит поля provisioner, parameters и reclaimPolicy, которые используются, чтобы динамически создавать PersistentVolume.
Можно создать дефолтный StorageClass для тех PVC, которые его вообще не указывают. Так же storage class хранит параметры подключения к реальному хранилищу. PVC используют эти параметры для подключения хранилища к подам.
Важный нюанс. PVC зависим от namespace. Если у вас SC будет с секретом, то этот секрет должен быть в том же namespace, что и PVC, с которого будет запрос на подключение.
Common Causes and Resolution [C]
Kubernetes PVC can be complex to use, resulting in errors that may be difficult to diagnose and address. PVC errors are generally related to three broad categories — issues with creation of PVs, issues with provisioning of PVs, and changes in PV or PVC specifications.
The most common errors related to PVCs are FailedAttachVolume, FailedMount, and CrashLoopBackOff.
These two errors indicate that a pod was unable to mount a PV. The difference is that FailedAttachVolume occurs when a volume fails to detach from a previous node, and FailedMount occurs when a volume fails to mount on the required path.
There are numerous possible causes of these two errors, including failure on the new node, too many disks attached to the new node, a network partitioning error, and failure of storage devices on the previous node.
Diagnosing the problem
Resolving the problem
Kubernetes cannot address the FailedAttachVolume and FailedMount errors automatically, so you will need to handle the problem manually:
- If the cause of the error is Failure to Detach- use the storage device’s interface to detach the volume manually.
- If the error is Failure to Attach or Mount- check for a network partitioning issue or incorrect network path. If this is not the issue, try to get Kubernetes to schedule the pod on another node, or investigate and fix the problem on the new node.
CrashLoopBackOff indicates that a pod crashed, restarted, and crashed again repeatedly. In some cases, this error occurs as a result of corrupted PersistentVolumeClaims.
To identify whether a CrashLoopBackOff error is due to a PVC, check the logs from the previous container instance that mounted the PV, check deployment logs, and if necessary, run a shell on the container to identify why it is crashing.
- Scale the deployment to 0 instances to enable debugging.
- Create a new pod for debugging and run a shell using this command: exec -it volume-debugger sh
- Identify the volume currently mounted in the /datadirectory and fix the issue causing the pod to crash.
- Exit the shell, delete the debugging pod, and scale the deployment back to the required number of replicas.

