Что такое PV и PVC в Kubernetes?

«Что такое PV и PVC в Kubernetes?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

PV (PersistentVolume) и PVC (PersistentVolumeClaim) — это абстракции Kubernetes для управления постоянным хранилищем (persistent storage). Они разделяют ответственность: администратор кластера настраивает ресурсы хранения (PV), а разработчик/пользователь запрашивает их через PVC.

PersistentVolume (PV):

  • Что это: Ресурс кластера, представляющий собой кусок предварительно подготовленного сетевого или локального хранилища (например, диск AWS EBS, Azure Disk, NFS-шара, Ceph RBD).
  • Кто создает: Администратор кластера или динамический provisioner (на основе StorageClass).
  • Жизненный цикл: Существует независимо от любого пода. Имеет собственный цикл: Available -> Bound -> Released -> Available (или Failed).

PersistentVolumeClaim (PVC):

  • Что это: Запрос пользователя на определенное количество хранилища с определенными характеристиками (размер, режим доступа).
  • Кто создает: Разработчик (манифест приложения).
  • Жизненный цикл: Связан с жизненным циклом пода. PVC ищет подходящий PV и "связывается" (bind) с ним.

Пример статического provisioning (администратор создает PV вручную):

# 1. Администратор создает PV (например, на основе NFS)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: app-data-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany  # Могут писать многие ноды (подходит для NFS)
  nfs:
    server: 10.0.0.100
    path: "/exports/data"
---
# 2. Разработчик создает PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi  # Запрашивает 5Gi, свяжется с PV на 10Gi (главное, чтобы хватило)
---
# 3. Под использует PVC
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: app-storage
  volumes:
  - name: app-storage
    persistentVolumeClaim:
      claimName: app-data-pvc  # Ссылка на PVC

Динамическое Provisioning (рекомендуемый способ): Здесь администратор создает StorageClass, а PVC автоматически запускает создание нового PV через внешний provisioner.

# StorageClass для AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ebs
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  fsType: ext4
---
# PVC, который триггерит создание PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
spec:
  storageClassName: fast-ebs  # Указываем класс хранилища
  accessModes:
    - ReadWriteOnce  # Только одна нода может монтировать на запись (типично для EBS)
  resources:
    requests:
      storage: 20Gi

Режимы доступа (accessModes):

  • ReadWriteOnce (RWO): Монтируется на запись и чтение только одной нодой (EBS, Azure Disk).
  • ReadOnlyMany (ROX): Монтируется на чтение многими нодами.
  • ReadWriteMany (RWX): Монтируется на запись и чтение многими нодами (NFS, CephFS, некоторые облачные файловые хранилища).

Применение в DevOps: Управление состоянием stateful-приложений (базы данных, кэши, брокеры сообщений), общими конфигурациями и логами.