Перейти до вмісту

Модуль 4.4: Знімки томів та клонування

Hands-On Lab Available
K8s Cluster advanced 30 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [MEDIUM] — Захист даних та клонування

Час на виконання: 30–40 хвилин

Передумови: Модуль 4.2 (PV та PVC), Модуль 4.3 (StorageClasses)


Що ви зможете робити

Розділ «Що ви зможете робити»

Після цього модуля ви зможете:

  • Створити VolumeSnapshots та відновити PVC зі знімків для резервного копіювання та відновлення
  • Налаштувати VolumeSnapshotClasses та пояснити, як вони пов’язані зі StorageClasses
  • Імплементувати стратегію резервного копіювання на основі знімків для stateful-навантажень
  • Дебажити збої знімків, перевіряючи логи snapshot controller та можливості CSI-драйвера

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Знімки томів надають копії ваших постійних даних на певний момент часу — це важливо для резервного копіювання, аварійного відновлення та створення тестових середовищ. Клонування томів дозволяє створювати нові томи з існуючих. На іспиті CKA можуть перевіряти ваше розуміння цих примітивів захисту даних, особливо оскільки вони стають все поширенішими у продакшен-середовищах Kubernetes.

Аналогія з фотоапаратом

Уявіть VolumeSnapshot як фотографію ваших даних у конкретний момент. Фото фіксує саме те, як виглядав ваш диск у цю мить. Пізніше ви можете використати це фото для відновлення диска до точного стану або створити новий диск, який починається як копія того моменту. VolumeSnapshotClass — це як налаштування фотоапарата — він визначає, як знімок створюється та зберігається.


Після завершення цього модуля ви зможете:

  • Розуміти архітектуру знімків (VolumeSnapshotClass, VolumeSnapshot, VolumeSnapshotContent)
  • Створювати VolumeSnapshots з існуючих PVC
  • Відновлювати томи зі знімків
  • Клонувати томи за допомогою dataSource
  • Розуміти вимоги CSI для знімків

  • Знімки є інкрементальними: Більшість бекендів сховища зберігають знімки як різницю від оригіналу, заощаджуючи місце
  • CSI є обов’язковим: Застарілі вбудовані (in-tree) плагіни томів не підтримують знімки — вам потрібні CSI-драйвери
  • Copy-on-write: Багато систем зберігання використовують CoW для знімків, що робить їх створення майже миттєвим
  • Відновлення між namespace: VolumeSnapshotContent має область видимості кластера, що дозволяє реалізувати сценарії аварійного відновлення

Частина 1: Архітектура знімків

Розділ «Частина 1: Архітектура знімків»

1.1 Три ресурси знімків

Розділ «1.1 Три ресурси знімків»
┌──────────────────────────────────────────────────────────────────────┐
│ Архітектура знімків │
│ │
│ Подібно до моделі PV/PVC: │
│ │
│ VolumeSnapshotClass VolumeSnapshot VolumeSnapshot │
│ (область кластера) (у namespace) Content │
│ ┌─────────────────┐ ┌─────────────┐ (область кластера)│
│ │ Визначає ЯК │ │ Запит на │ ┌─────────────┐ │
│ │ створюються │ │ знімок │ │ Фактичне │ │
│ │ знімки │◄────────│ конкретного │─────►│ посилання │ │
│ │ │ │ PVC │ │ на знімок │ │
│ │ - driver │ │ - source │ │ │ │
│ │ - deletionPolicy│ │ - class │ │ - driver │ │
│ └─────────────────┘ └─────────────┘ │ - handle │ │
│ └─────────────┘ │
│ │
│ Адмін створює Розробник створює Створюється │
│ (раз на кластер) (за потреби) автоматично │
│ (контролером) │
└──────────────────────────────────────────────────────────────────────┘

1.2 Як це відповідає PV/PVC

Розділ «1.2 Як це відповідає PV/PVC»
ЗберіганняЗнімки
StorageClassVolumeSnapshotClass
PersistentVolumeVolumeSnapshotContent
PersistentVolumeClaimVolumeSnapshot

Перед використанням знімків вам потрібно:

  1. CSI-драйвер, що підтримує знімки (не всі підтримують)
  2. Контролер знімків, розгорнутий у кластері
  3. CRD для знімків встановлені
  4. VolumeSnapshotClass створений
Terminal window
# Перевірити, чи встановлені CRD для знімків
k get crd | grep snapshot
# volumesnapshotclasses.snapshot.storage.k8s.io
# volumesnapshotcontents.snapshot.storage.k8s.io
# volumesnapshots.snapshot.storage.k8s.io
# Перевірити наявність контролера знімків
k get pods -n kube-system | grep snapshot

Частина 2: VolumeSnapshotClass

Розділ «Частина 2: VolumeSnapshotClass»

2.1 Створення VolumeSnapshotClass

Розділ «2.1 Створення VolumeSnapshotClass»
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true" # Опціонально
driver: ebs.csi.aws.com # Має збігатися з CSI-драйвером
deletionPolicy: Delete # Delete або Retain
parameters: # Параметри, специфічні для драйвера
# Приклад для деяких драйверів:
# csi.storage.k8s.io/snapshotter-secret-name: snap-secret
# csi.storage.k8s.io/snapshotter-secret-namespace: default

2.2 Політики видалення

Розділ «2.2 Політики видалення»
ПолітикаПоведінка
DeleteVolumeSnapshotContent та базовий знімок видаляються при видаленні VolumeSnapshot
RetainVolumeSnapshotContent та знімок зберігаються після видалення VolumeSnapshot

2.3 Приклади для хмарних провайдерів

Розділ «2.3 Приклади для хмарних провайдерів»

AWS EBS CSI:

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

GCP PD CSI:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: gcp-snapclass
driver: pd.csi.storage.gke.io
deletionPolicy: Delete
parameters:
storage-locations: us-central1

Azure Disk CSI:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: azure-snapclass
driver: disk.csi.azure.com
deletionPolicy: Delete
parameters:
incremental: "true"

Частина 3: Створення знімків

Розділ «Частина 3: Створення знімків»

3.1 Створення VolumeSnapshot

Розділ «3.1 Створення VolumeSnapshot»
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: data-snapshot
namespace: production
spec:
volumeSnapshotClassName: csi-snapclass # Посилання на клас
source:
persistentVolumeClaimName: data-pvc # PVC для знімка

3.2 Процес створення знімка

Розділ «3.2 Процес створення знімка»
┌─────────────────────────────────────────────────────────────────────┐
│ Процес створення знімка │
│ │
│ 1. Створити VolumeSnapshot │
│ │ │
│ ▼ │
│ 2. Контролер знімків перевіряє │
│ - PVC існує │
│ - VolumeSnapshotClass існує │
│ - CSI-драйвер підтримує знімки │
│ │ │
│ ▼ │
│ 3. CSI-драйвер створює знімок на бекенді сховища │
│ │ │
│ ▼ │
│ 4. VolumeSnapshotContent створено (автоматично) │
│ │ │
│ ▼ │
│ 5. Статус VolumeSnapshot: readyToUse=true │
│ │
└─────────────────────────────────────────────────────────────────────┘

3.3 Перевірка статусу знімка

Розділ «3.3 Перевірка статусу знімка»
Terminal window
# Список знімків
k get volumesnapshot -n production
# NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS
# data-snapshot true data-pvc 10Gi csi-snapclass
# Детальний статус
k describe volumesnapshot data-snapshot -n production
# Перевірити VolumeSnapshotContent
k get volumesnapshotcontent

3.4 Поля статусу знімка

Розділ «3.4 Поля статусу знімка»
status:
boundVolumeSnapshotContentName: snapcontent-xxxxx
creationTime: "2024-01-15T10:30:00Z"
readyToUse: true # Знімок готовий
restoreSize: 10Gi # Розмір при відновленні
error: # Якщо невдача, тут повідомлення про помилку

Частина 4: Відновлення зі знімків

Розділ «Частина 4: Відновлення зі знімків»

4.1 Створення PVC зі знімка

Розділ «4.1 Створення PVC зі знімка»
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restored-data
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd # StorageClass для нового PVC
resources:
requests:
storage: 10Gi # Має бути >= розміру знімка
dataSource: # Ключова частина!
name: data-snapshot # Ім'я VolumeSnapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io

4.2 Процес відновлення

Розділ «4.2 Процес відновлення»
┌─────────────────────────────────────────────────────────────────────┐
│ Відновлення зі знімка │
│ │
│ VolumeSnapshot Новий PVC │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ data-snap │ │ restored │ │
│ │ │ │ │ │
│ │ restoreSize:│◄──dataSource──────│ storage: │ │
│ │ 10Gi │ │ 10Gi │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ▼ ▼ │
│ VolumeSnapshotContent Новий PV (з даними) │
│ (містить дескриптор (наданий зі │
│ знімка) знімка) │
│ │
└─────────────────────────────────────────────────────────────────────┘

4.3 Відновлення між namespace

Розділ «4.3 Відновлення між namespace»

VolumeSnapshotContent має область видимості кластера, тому можна відновлювати в різних namespace:

# У namespace "dr-test"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dr-restore
namespace: dr-test # Інший namespace!
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
dataSourceRef: # Використовуйте dataSourceRef для між-namespace
name: data-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
namespace: production # Вихідний namespace

Примітка: Відновлення між namespace потребує Kubernetes 1.26+ та відповідного RBAC.


Частина 5: Клонування томів

Розділ «Частина 5: Клонування томів»

5.1 Що таке клонування томів?

Розділ «5.1 Що таке клонування томів?»

Клонування створює новий PVC з даними з існуючого PVC без попереднього створення знімка.

┌─────────────────────────────────────────────────────────────────────┐
│ Знімок vs Клон │
│ │
│ ЗНІМОК КЛОН │
│ ────── ──── │
│ PVC → Знімок → Новий PVC PVC → Новий PVC (напряму) │
│ │
│ Двокроковий процес Однокроковий процес │
│ Резервна копія на момент часу Негайна копія │
│ Можна відновити багато разів Одна операція копіювання │
│ Знімок зберігається Немає проміжного артефакту │
│ │
└─────────────────────────────────────────────────────────────────────┘
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi # Має бути >= вихідного PVC
dataSource: # Клонування з існуючого PVC
name: source-pvc # Ім'я вихідного PVC
kind: PersistentVolumeClaim # Інший kind, ніж для знімка!

5.3 Вимоги до клонування

Розділ «5.3 Вимоги до клонування»
  • Джерело та клон повинні бути в одному namespace
  • Бекенд сховища повинен підтримувати клонування
  • Розмір клону має бути >= розміру джерела
  • Зазвичай потрібен той самий StorageClass

5.4 Випадки використання клонування

Розділ «5.4 Випадки використання клонування»
Випадок використанняОпис
Середовища dev/testКлонування продакшен-даних для тестування
Резервні копії перед оновленнямКлонування перед ризикованими змінами
Аналіз данихКлон для аналітики без впливу на продакшен
Паралельна обробкаКілька клонів для паралельних навантажень

Частина 6: Найкращі практики

Розділ «Частина 6: Найкращі практики»

6.1 Стратегія резервного копіювання

Розділ «6.1 Стратегія резервного копіювання»
# Створення знімків за розкладом за допомогою CronJob або зовнішнього інструменту
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: daily-backup-2024-01-15
labels:
backup-type: daily
source-pvc: database-data
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: database-data

6.2 Зберігання знімків

Розділ «6.2 Зберігання знімків»
Terminal window
# Очищення старих знімків (концепція скрипта)
# Зберігати останні 7 щоденних, 4 щотижневих, 12 щомісячних
# Список знімків старших за 7 днів з міткою daily
k get volumesnapshot -l backup-type=daily --sort-by=.metadata.creationTimestamp

6.3 Консистентність додатків

Розділ «6.3 Консистентність додатків»

Для консистентних знімків:

  1. Призупиніть запис перед знімком (якщо можливо)
  2. Скиньте буфери на диск
  3. Зробіть знімок швидко
  4. Відновіть запис
Terminal window
# Приклад: MySQL flush перед знімком
k exec mysql-pod -- mysql -e "FLUSH TABLES WITH READ LOCK;"
# Створіть знімок тут
k exec mysql-pod -- mysql -e "UNLOCK TABLES;"

ПомилкаПроблемаРішення
Немає CSI-драйвераЗнімки не підтримуютьсяВстановіть CSI-драйвер з підтримкою знімків
Відсутні CRD для знімківРесурс VolumeSnapshot невідомийВстановіть CRD для знімків
Неправильний driver у SnapshotClassЗнімок тихо не вдаєтьсяУзгодьте driver з іменем CSI-драйвера
Розмір відновлення замалийPVC не надаєтьсяВикористовуйте розмір >= restoreSize
Клонування між namespaceНе дозволеноКлони повинні бути в тому самому namespace, що й джерело
Видалення вихідного PVCКлони можуть зазнати невдачіПереконайтесь, що клон завершено перед видаленням джерела

Яка ключова різниця між відновленням зі знімка та клонуванням PVC?

Відповідь

Відновлення зі знімка використовує VolumeSnapshot як посередника — ви створюєте знімок, а потім створюєте новий PVC з цього знімка. Знімок зберігається і може бути використаний багаторазово.

Клонування створює новий PVC безпосередньо з існуючого PVC без проміжного знімка. Це однокроковий процес без постійного артефакту.

Q2: Призначення VolumeSnapshotClass

Розділ «Q2: Призначення VolumeSnapshotClass»

Яку роль відіграє VolumeSnapshotClass?

Відповідь

VolumeSnapshotClass визначає як створюються знімки, подібно до того, як StorageClass визначає, як надаються PV. Він вказує:

  • Який CSI-драйвер створює знімки
  • Політику видалення (Delete або Retain)
  • Параметри, специфічні для драйвера

Q3: Передумови для знімків

Розділ «Q3: Передумови для знімків»

Які три речі повинні бути встановлені, перш ніж ви зможете використовувати знімки томів?

Відповідь
  1. CRD для знімків — визначення користувацьких ресурсів для VolumeSnapshot, VolumeSnapshotClass, VolumeSnapshotContent
  2. Контролер знімків — відстежує ресурси VolumeSnapshot та керує життєвим циклом
  3. CSI-драйвер з підтримкою знімків — фактичний драйвер, який створює знімки на бекенді сховища

Q4: Відновлення між namespace

Розділ «Q4: Відновлення між namespace»

Чи можна відновити VolumeSnapshot в іншому namespace, ніж той, де він був створений?

Відповідь

Так, тому що VolumeSnapshotContent (який містить фактичне посилання на знімок) має область видимості кластера. Ви можете створити PVC в іншому namespace, який посилається на VolumeSnapshot за допомогою dataSourceRef з полем namespace (потрібен Kubernetes 1.26+).

Яка різниця між використанням kind: VolumeSnapshot та kind: PersistentVolumeClaim у dataSource PVC?

Відповідь
  • kind: VolumeSnapshot — відновлення зі знімка (створює новий том зі знімка)
  • kind: PersistentVolumeClaim — клонування існуючого PVC (копіює дані напряму)

Обидва використовують поле dataSource, але створюють новий том по-різному.


Практична вправа: Знімок та відновлення

Розділ «Практична вправа: Знімок та відновлення»

Ця вправа потребує кластер з:

  • CSI-драйвером, що підтримує знімки
  • Встановленими контролером знімків та CRD

Якщо використовуєте kind або minikube, можливо, знадобиться встановити їх вручну.

Завдання 1: Перевірити підтримку знімків

Розділ «Завдання 1: Перевірити підтримку знімків»
Terminal window
# Перевірити існування CRD
k get crd | grep snapshot
# Перевірити наявність VolumeSnapshotClass
k get volumesnapshotclass
# Якщо немає, потрібно створити на основі вашого CSI-драйвера

Завдання 2: Створити тестові дані

Розділ «Завдання 2: Створити тестові дані»
Terminal window
# Створити namespace
k create ns snapshot-lab
# Створити PVC
cat <<EOF | k apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: source-data
namespace: snapshot-lab
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard # Використовуйте StorageClass вашого кластера
EOF
# Створити Под для запису даних
cat <<EOF | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: data-writer
namespace: snapshot-lab
spec:
containers:
- name: writer
image: busybox:1.36
command: ['sh', '-c', 'echo "Important data created at $(date)" > /data/important.txt; sleep 3600']
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: source-data
EOF
# Зачекати, поки дані будуть записані
sleep 10
k exec -n snapshot-lab data-writer -- cat /data/important.txt

Завдання 3: Створити VolumeSnapshotClass (за потреби)

Розділ «Завдання 3: Створити VolumeSnapshotClass (за потреби)»
Terminal window
# Приклад для AWS EBS CSI (змініть для вашого драйвера)
cat <<EOF | k apply -f -
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
driver: ebs.csi.aws.com # Змініть на ваш CSI-драйвер
deletionPolicy: Delete
EOF

Завдання 4: Створити знімок

Розділ «Завдання 4: Створити знімок»
Terminal window
cat <<EOF | k apply -f -
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: source-snapshot
namespace: snapshot-lab
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: source-data
EOF
# Зачекати, поки знімок буде готовий
k get volumesnapshot -n snapshot-lab -w
# Зачекайте, поки READYTOUSE покаже "true"

Завдання 5: “Пошкодити” оригінальні дані

Розділ «Завдання 5: “Пошкодити” оригінальні дані»
Terminal window
# Імітувати втрату даних
k exec -n snapshot-lab data-writer -- sh -c 'echo "Corrupted!" > /data/important.txt'
k exec -n snapshot-lab data-writer -- cat /data/important.txt
# Показує: Corrupted!

Завдання 6: Відновити зі знімка

Розділ «Завдання 6: Відновити зі знімка»
Terminal window
# Видалити Под (щоб звільнити PVC)
k delete pod -n snapshot-lab data-writer
# Створити новий PVC зі знімка
cat <<EOF | k apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restored-data
namespace: snapshot-lab
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 1Gi
dataSource:
name: source-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
EOF
# Створити Под для перевірки відновлених даних
cat <<EOF | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: data-reader
namespace: snapshot-lab
spec:
containers:
- name: reader
image: busybox:1.36
command: ['sh', '-c', 'cat /data/important.txt; sleep 3600']
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: restored-data
EOF
# Перевірити, що оригінальні дані відновлені
k logs -n snapshot-lab data-reader
# Має показати: Important data created at <оригінальна мітка часу>
  • VolumeSnapshotClass створено
  • VolumeSnapshot показує readyToUse: true
  • Новий PVC створено зі знімка
  • Відновлені дані збігаються з оригіналом (не пошкоджена версія)
Terminal window
k delete ns snapshot-lab
k delete volumesnapshotclass csi-snapclass

Вправа 1: Список ресурсів знімків (1 хв)

Розділ «Вправа 1: Список ресурсів знімків (1 хв)»
Terminal window
# Завдання: Знайти всі ресурси, пов'язані зі знімками
k api-resources | grep snapshot

Вправа 2: Створити VolumeSnapshotClass (2 хв)

Розділ «Вправа 2: Створити VolumeSnapshotClass (2 хв)»
Terminal window
# Завдання: Створити SnapshotClass для вашого CSI-драйвера з політикою Delete

Вправа 3: Перевірити статус знімка (1 хв)

Розділ «Вправа 3: Перевірити статус знімка (1 хв)»
Terminal window
# Завдання: Перевірити, що знімок готовий до використання
k get volumesnapshot <name> -o jsonpath='{.status.readyToUse}'

Вправа 4: Відновити зі знімка (2 хв)

Розділ «Вправа 4: Відновити зі знімка (2 хв)»
Terminal window
# Завдання: Створити PVC зі знімка "backup-snap"
# Ключ: dataSource з kind: VolumeSnapshot

Вправа 5: Клонувати PVC (2 хв)

Розділ «Вправа 5: Клонувати PVC (2 хв)»
Terminal window
# Завдання: Клонувати PVC "source-pvc" до "clone-pvc"
# Ключ: dataSource з kind: PersistentVolumeClaim

Вправа 6: Знайти розмір знімка (1 хв)

Розділ «Вправа 6: Знайти розмір знімка (1 хв)»
Terminal window
# Завдання: Отримати розмір відновлення знімка
k get volumesnapshot <name> -o jsonpath='{.status.restoreSize}'

Вправа 7: Перевірити VolumeSnapshotContent (1 хв)

Розділ «Вправа 7: Перевірити VolumeSnapshotContent (1 хв)»
Terminal window
# Завдання: Знайти VolumeSnapshotContent для VolumeSnapshot
k get volumesnapshot <name> -o jsonpath='{.status.boundVolumeSnapshotContentName}'

Переходьте до Модуль 4.5: Усунення несправностей зберігання, щоб дізнатися, як діагностувати та виправляти типові проблеми зберігання.