Привет, Хабр!

Сегодня поговорим о Volume Snapshots — штуке, которая позволяет создать мгновенный «снимок» данных в Kubernetes, практически как Ctrl+S, только для объёмов дисков.

Volume Snapshot — это снимок данных на уровне диска, позволяющий сохранить текущее состояние PersistentVolume или его клон. В основном это полезно для бэкапов и восстановления, а также для таких задач, как миграция данных или клонирование систем.

Volume Snapshots

Основные термины, с которыми нужно быть «на ты»:

  1. VolumeSnapshot — это запрос на создание снапшота данных из PersistentVolumeClaim.

  1. VolumeSnapshotContent — фактический ресурс снапшота в системе, который хранит данные.

  1. VolumeSnapshotClass — описывает параметры, используемые для снапшотов.

Прежде чем что‑либо делать, тебе нужно убедиться, что в твоем кластере установлен и активирован CSI Snapshot Controller — он отвечает за управление снапшотами. Проверить можно командой:

kubectl get pods -n kube-system | grep snapshot-controller

Если он не запущен, установи его:

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml

Динамическое создание Volume Snapshot

Известно, что можно создать PersistentVolume динамически, так же и с Volume Snapshots. Для этого используется VolumeSnapshotClass, которая определяет, какой драйвер и параметры мы будем использовать.

Пример создания VolumeSnapshotClass:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-hostpath-snapclass
driver: hostpath.csi.k8s.io
deletionPolicy: Delete

Драйвер hostpath.csi.k8s.io — это пример для тестов. На проде будет собственный CSI драйвер от провайдера.

deletionPolicy: Delete — означает, что снапшот будет удалён вместе с его содержимым, когда ты удалишь сам VolumeSnapshot.

Теперь создаём снапшот:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: my-snapshot
spec:
  volumeSnapshotClassName: csi-hostpath-snapclass
  source:
    persistentVolumeClaimName: my-pvc

Обрати внимание на persistentVolumeClaimName. Это PVC, с которого ты делаешь снимок. Как только ты создаёшь этот YAML, Kubernetes тут же попытается привязать снапшот к PV через VolumeSnapshotContent.

Статический Volume Snapshot

Если ты — админ, который хочет подготовить снапшоты заранее, тебе понадобятся VolumeSnapshotContent. Это похоже на то, как ты создаёшь статические PersistentVolumes.

Пример:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
  name: pre-provisioned-snapshot-content
spec:
  deletionPolicy: Retain
  driver: hostpath.csi.k8s.io
  source:
    snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
  volumeSnapshotRef:
    name: pre-provisioned-snapshot
    namespace: default

Здесь snapshotHandle — это ID снапшота на твоей системе хранения, который уже существует.

Восстановление с VolumeSnapshot

Что нам толку от снапшота, если мы не можем восстановить данные? Теперь создадим новый PVC из нашего снапшота:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-from-snapshot
spec:
  storageClassName: manual
  dataSource:
    name: my-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Здесь dataSource указывает на наш VolumeSnapshot. Kubernetes возьмёт снапшот и восстановит данные в новый PVC.

Управление жизненным циклом

Снапшоты, как и PersistentVolume, как вы уже возможно заметили, можно настроить для автоматического удаления. Это настраивается в поле deletionPolicy в VolumeSnapshotContent. Доступно два варианта:

  • Delete — снапшот удаляется при удалении VolumeSnapshot.

  • Retain — снапшот остаётся на системе хранения даже после удаления объекта Kubernetes.

Автоматизация с помощью CronJobs

Почему бы не автоматизировать создание снапшотов? Используем Kubernetes CronJob для регулярных бэкапов.

Создаем CronJob:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: snapshot-cron
  namespace: default
spec:
  schedule: "0 2 * * *" # Каждый день в 2 часа ночи
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: snapshot
            image: bitnami/kubectl:latest
            command:
            - /bin/sh
            - -c
            - |
              kubectl create volumesnapshot db-snapshot-$(date +\%F) \
                --namespace=default \
                --volume-snapshot-class=csi-hostpath-snapclass \
                --source-pvc=db-pvc
          restartPolicy: OnFailure

Сохраняем в snapshot-cronjob.yaml и применяем:

kubectl apply -f snapshot-cronjob.yaml

Теперь каждый день в 2 часа ночи будет создаваться новый снапшот db-snapshot-YYYY-MM-DD, где YYYY-MM-DD — текущая дата.

Важные нюансы

Консистентность данных

Создание снапшота — это не просто моментальный снимок данных. Важно убедиться, что данные находятся в консистентном состоянии на момент создания снапшота.

Механизмы заморозки: Многие базы данных поддерживают команды для временной приостановки операций записи. Например, в PostgreSQL можно использовать pg_dump для создания резервной копии данных перед созданием снапшота.

pg_dump -U postgres -F c mydatabase > mydatabase_backup.sql

После выполнения команды pg_dump данные будут в консистентном состоянии, и можно безопасно создавать снапшот.

Транзакционные снапшоты: Некоторые системы хранения поддерживают транзакционные снапшоты, которые автоматом обеспечивают консистентность данных без необходимости дополнительного вмешательства. Например, Microsoft SQL Server может использовать транзакционные консистентные снимки.

Совместимость с драйверами

Не все CSI драйверы одинаково поддерживают Volume Snapshots. Некоторые могут иметь ограничения или особенности, которые нужно учитывать при настройке.

Всегда читайте официальную документацию своего CSI драйвера. Там указаны поддерживаемые функции, ограничения и примеры использования.

Например, AWS EBS и GCE Persistent Disk отлично интегрируются с Kubernetes, обеспечивая надёжные и кросс-зональные снапшоты, тогда как Azure Disk предлагает региональные снапшоты и интеграцию с Azure Backup. Для локальных тестов подойдёт HostPath CSI Driver, но он ограничен функциональностью и не рекомендован для продакшена. Открытые решения, такие как Ceph CSI Driver, предоставляют гибкость и мощные возможности, но требуют более сложной настройки.

Заключение

Внедряй Volume Snapshots в свои Kubernetes-кластеры, экспериментируй и делись своими наработками.

Все актуальные методы и инструменты IT-инфраструктуры можно освоить на онлайн-курсах OTUS: в каталоге можно посмотреть список всех программ, а в календаре — записаться на открытые уроки.

Комментарии (2)


  1. gmini
    04.11.2024 12:28

    только для объёмов дисков

    гугл транслейт?

    *дисковых томов


  1. vasyakrg
    04.11.2024 12:28

    После выполнения команды pg_dump данные будут в консистентном состоянии, и можно безопасно создавать снапшот.

    Ой.. уж пишите тогда, что после рестора диска надо опять консистент проверять и/или вообще ресторить базу ее методом.

    Перед снапшотом мы делаем бекап базы и кладем ее тут же рядом. Прэлестно.