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

Підсумковий тест частини 4: Сховище

Lab Progress 0/5 completed

Складність: [СКЛАДНИЙ]

Час на проходження: 65-80 хвилин

Передумови: Модуль 4.1 Томи, Модуль 4.2 PersistentVolume та PersistentVolumeClaim, Модуль 4.3 StorageClass і динамічне виділення, Модуль 4.4 Знімки та клонування томів, Модуль 4.5 Усунення несправностей сховища

Формат оцінювання: Тест на основі сценаріїв плюс практична вправа з усунення несправностей

Цільова версія Kubernetes: 1.35+

Цей підсумковий модуль не є перевіркою пам’яті. Це репетиція того типу міркувань про сховище, який очікує CKA: читання симптомів, вибір правильної абстракції, перевірка стану ресурсів у правильному порядку та пояснення, чому одне виправлення безпечніше за інше.

Для першої команди в новій оболонці використовуйте kubectl. Після цього у прикладах застосовується короткий псевдонім k, бо швидкість важлива і на іспиті, і під час реагування на інциденти.

Terminal window
alias k=kubectl

Результати навчання

Розділ «Результати навчання»

Наприкінці цього модуля ви зможете діагностувати збої запуску Pod’ів, спричинені відсутніми заявками, невдалими монтуваннями, конфліктами режимів доступу, помилками топології та невідповідностями прав доступу до файлів, рухаючись від симптомів робочого навантаження до ресурсів сховища у продуманій послідовності.

Ви зможете оцінити, чи має робоче навантаження використовувати emptyDir, проєктовані томи, динамічно виділений PVC, статично прив’язаний PV, клон чи відновлення зі знімка, виходячи з вимог до життєвого циклу, довговічності, шаблону доступу, безпеки та відновлення.

Ви зможете спроєктувати шлях сховища для стейтфул-навантаження, що узгоджує PersistentVolumeClaim, StorageClass, режим доступу, політику повторного використання та топологію планування так, щоб Под можна було спланувати та змонтувати без прихованих конфліктів зон чи Нод.

Ви зможете порівняти варіанти відновлення сховища, зокрема клон, відновлення зі знімка, політику повторного використання Retain та ручне врятування даних, і обґрунтувати, який варіант зберігає потрібні дані на потрібний момент часу.

Ви зможете відремонтувати реалістичний зламаний сценарій сховища за допомогою команд kubectl, редагувань маніфестів, перевірки подій та кроків верифікації, що доводять здатність застосунку читати та записувати очікувані дані.


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

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

Інженер платіжної платформи випускає рутинний реліз пізно в п’ятницю. Деплоймент розгортається вперед, але нові Под’и залишаються у стані ContainerCreating, оплати клієнтів починають відмовляти за тайм-аутом, а перша подія повідомляє лише про те, що том не вдалося змонтувати. Команда застосунку питає, чи не втратила база даних дані, інфраструктурна команда питає, у якій зоні розташований том, а керівник інциденту потребує шляху відновлення, який не погіршить простій.

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

Домен сховища CKA перевіряє саме ці міркування під тиском часу. Вас рідко просять процитувати назву поля в ізоляції; вас просять змусити зламаний Под працювати, пояснити, чому PVC у стані Pending, відновитися після видаленої заявки або обрати шаблон сховища для навантаження з реальними обмеженнями довговічності та планування. Цей модуль перетворює попередні уроки частини 4 на ментальну модель оператора: почніть із симптому, визначте контракт сховища, перевірте події контролера, а потім змініть найменше, що безпечно відновлює навантаження.


1. Побудуйте модель прийняття рішень про сховище ще до того, як торкнетеся YAML

Розділ «1. Побудуйте модель прийняття рішень про сховище ще до того, як торкнетеся YAML»

Робота зі сховищем у Kubernetes починається з простого запитання: чи мають дані пережити Под? Якщо відповідь — ні, ефемерний том може бути найпростішим і найбезпечнішим вибором. Якщо відповідь — так, вам потрібна заявка, том, що підкріплює дані, і рішення про життєвий цикл щодо того, що станеться, коли заявка зникне. Ця відмінність важлива, бо багато зламаних проєктів виникає від використання довговічної абстракції для тимчасових чорнових даних або тимчасової абстракції для бізнес-даних.

Том emptyDir створюється для Под’а і видаляється, коли цей Под залишає Ноду. Він переживає перезапуски контейнерів усередині того самого Под’а, що робить його корисним для кешів, спільних чорнових каталогів та шаблонів передачі даних між сайдкарами. Він не переживає видалення Под’а, виселення чи відмову Ноди, тому це неправильне місце для завантажених файлів, стану бази даних або будь-чого, що має бути відновлене після перепланування.

emptyDir із підтримкою пам’яті швидший, але змінює ризик ресурсів. Байти, збережені в цьому томі, зараховуються до використання пам’яті, і кеш, що зростає без обмеження, може підштовхнути контейнер до виселення чи примусового завершення через брак пам’яті. Коли ви обираєте medium: Memory, також встановіть sizeLimit і переконайтеся, що запити та ліміти пам’яті Под’а відображають можливий розмір кешу.

apiVersion: v1
kind: Pod
metadata:
name: cache-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "date > /cache/started && sleep 3600"]
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir:
medium: Memory
sizeLimit: 128Mi

Проєктовані томи вирішують іншу проблему. Вони дозволяють Под’у бачити конфігурацію, секрети, токени сервісних акаунтів та вибрані метадані Под’а як файли, не вшиваючи ці значення в образ. Це потужно, бо відокремлює ідентичність і конфігурацію часу розгортання від коду застосунку, але також створює тонку поведінку оновлення. Звичайний том ConfigMap чи Secret може оновлюватися після зміни вихідного об’єкта, тоді як монтування subPath закріплює конкретний шлях до файлу й не отримує цих живих оновлень.

apiVersion: v1
kind: Pod
metadata:
name: projected-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "ls -la /projected && cat /projected/pod-name && sleep 3600"]
volumeMounts:
- name: projected
mountPath: /projected
readOnly: true
volumes:
- name: projected
projected:
sources:
- downwardAPI:
items:
- path: pod-name
fieldRef:
fieldPath: metadata.name

Том hostPath має змусити вас бути обережними. Він монтує частину файлової системи Ноди в Под, що може розкрити секрети Ноди, зламати ізоляцію та створити навантаження, які виконуються лише на Нодах із певним локальним шляхом. Він корисний для жорстко контрольованих агентів Ноди та деяких локальних лабораторій, але це не загальний шаблон сховища застосунків і зазвичай блокується суворішими політиками допуску.

Персистентне сховище додає контракт. Под не просить безпосередньо конкретний хмарний диск чи том системи зберігання; він просить PersistentVolumeClaim, а Kubernetes прив’язує цю заявку до PersistentVolume або просить провізіонер створити його. Заявка належить до простору імен, бо вона належить до межі застосунку, тоді як персистентний том має область кластера, бо ресурс сховища, що лежить в основі, існує поза одним простором імен.

+--------------------+ requests +--------------------------+
| Pod in namespace | ----------------------> | PersistentVolumeClaim |
| app | | namespace: app |
+--------------------+ +------------+-------------+
|
| binds to
v
+--------------------------+
| PersistentVolume |
| cluster-scoped resource |
+------------+-------------+
|
| represents
v
+--------------------------+
| real storage |
| disk, share, or CSI vol |
+--------------------------+

Діаграма показує, чому налагодження сховища вимагає переходу між областями. Симптом Под’а з’являється у просторі імен, PVC — у тому самому просторі імен, PV має область кластера, а сам диск чи файлова шара можуть розташовуватися у хмарній зоні або на конкретній Ноді. Якщо ви оглядаєте лише Под, ви можете пропустити рішення про прив’язку. Якщо ви оглядаєте лише PV, ви можете пропустити подію навантаження, що каже вам, чому монтування не вдалося.

Підказка для активного навчання: перш ніж читати далі, вирішіть, яке сховище ви б обрали для Под’а обробки логів, який завантажує великий вхідний файл, перетворює його, вивантажує результат до об’єктного сховища, а потім завершується. Якщо ви обрали PVC, поясніть, які дані мають пережити завершення Под’а. Якщо ви обрали emptyDir, поясніть, як ви б обмежили ризик переповнення Ноди чорновим каталогом.

Модель прийняття рішень можна підсумувати як набір компромісів, а не як перелік назв ресурсів. Ефемерні томи оптимізовані для простоти та локального для Под’а життєвого циклу. Проєктовані томи оптимізовані для впровадження конфігурації та ідентичності. PVC оптимізовані для довговічного сховища з оголошеним запитом. Знімки та клони оптимізовані для відновлення, міграції та робочих процесів із тестовими даними. Усунення несправностей пов’язує все це, питаючи, яку обіцянку було порушено.

СитуаціяКраща відправна точкаЗапитання для міркування
Чорнові файли, спільні для контейнерів в одному Под’іemptyDirЧи мають дані зникнути, коли Под замінюється?
Конфігурація застосунку чи матеріал токенаПроєктований том або том ConfigMap чи SecretЧи має значення надходити з об’єктів кластера, а не з образу?
Стан бази даних чи чергиPVC, підкріплений придатним StorageClassЯкий режим доступу, розмір, топологія та поведінка повторного використання потрібні?
Тестова копія наявних данихКлон PVC, коли підтримуєтьсяЧи розташований вихідний PVC у тому самому просторі імен і потребує прямої копії?
Відновлення на момент часуVolumeSnapshot та відновлення PVCЧи потрібна команді багаторазова точка відновлення?
Локальна продуктивність Ноди з обмеженнями плануванняЛокальний PV з прив’язкою до НодиЧи може Под витримати прив’язку до сховища однієї Ноди?

2. Розумійте прив’язку як контракт, а не як збіг

Розділ «2. Розумійте прив’язку як контракт, а не як збіг»

PVC описує те, що потрібно застосунку. Він може запитувати ємність, режими доступу, конкретний storageClassName, а іноді й джерело даних, наприклад знімок чи інший PVC. Потім Kubernetes намагається задовольнити цей запит наявним PV або через динамічне виділення. Коли PVC залишається у стані Pending, кластер каже вам, що запитаний контракт не виконано.

Режим доступу є частиною цього контракту, але його часто розуміють неправильно. ReadWriteOnce означає, що том може бути змонтований для читання-запису робочими навантаженнями на одній Ноді, а не обов’язково лише одним Под’ом у всіх випадках. ReadOnlyMany та ReadWriteMany залежать від сховища, що підтримує монтування з кількох Нод. Якщо ваш застосунок потребує активних записувачів на кількох Нодах, блоковий диск із ReadWriteOnce є неправильним примітивом, навіть якщо YAML прийнято.

Прив’язка ємності також є контрактом, а не точним замовленням. Заявка на 20Gi може прив’язатися до більшого придатного тому, але не може прив’язатися до меншого. Статична прив’язка PV зазвичай обирає найменший відповідний том, що задовольняє запит, бо використання набагато більшого тому марнує ємність. У динамічному виділенні зовнішній провізіонер створює сховище, що відповідає запитаному розміру згідно зі StorageClass та поведінкою драйвера.

Поведінка StorageClass змінюється залежно від того, коли відбувається прив’язка. За volumeBindingMode: Immediate динамічний том може бути виділений одразу після створення PVC. Це нормально для сховища, доступного по всьому кластеру, але ризиковано для зональних дисків, бо том може з’явитися в одній зоні, тоді як Под пізніше спланується в іншій. За WaitForFirstConsumer Kubernetes чекає, доки Под потребуватиме PVC, а потім враховує обмеження планування Под’а перед виділенням чи прив’язкою.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: zonal-safe
provisioner: example.csi.k8s.io
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete

reclaimPolicy описує, що станеться з PV, який підкріплює дані, після видалення заявки. Delete зручний для одноразових середовищ, бо том видаляється провізіонером. Retain зберігає PV та дані, що лежать в основі, але також залишає PV у стані Released зі старим посиланням на заявку. Це функція безпеки: Kubernetes не повинен мовчки передавати потенційно конфіденційні дані новій заявці.

PV, що зберігається, потребує свідомого поводження. Адміністратор може оглянути чи зробити резервну копію даних, очистити сховище, якщо передбачається повторне використання, а потім прибрати старий claimRef чи відтворити об’єкт PV із чистою специфікацією. Важлива екзаменаційна звичка — помічати, що Released не означає Available. Це означає, що заявка зникла, але PV досі пам’ятає стару прив’язку.

Terminal window
k get pv
k describe pv retained-pv
k patch pv retained-pv -p '{"spec":{"claimRef": null}}'

Використовуйте патч лише тоді, коли ви свідомо знову робите цей PV доступним. У реальному виробничому середовищі ви б також підтвердили право власності, статус резервної копії та очищення даних перед повторною прив’язкою. CKA часто стискає цей контекст до меншого завдання, але професійна звичка все одно полягає в тому, щоб ставитися до збережених даних як до конфіденційних, доки не доведено протилежне.

Розібраний приклад: команда повідомляє, що Под бази даних застряг у стані Pending, і PVC також Pending. PVC запитує 10Gi, режим доступу ReadWriteOnce та storageClassName: fast-zonal. Ви запускаєте k describe pvc db-data -n payments і бачите подію, яка каже про очікування першого споживача. Ця подія сама по собі не є збоєм; вона означає, що StorageClass відкладає виділення, доки Под не буде спланований.

Наступна перевірка — це Под, який споживає заявку. Якщо Под має селектор Нод для зони, де немає придатних Нод, планувальник не може обрати місце споживача, тож PVC залишається в очікуванні. Якщо Под має дійсні варіанти планування, зрештою провізіонер повинен створити том у вибраній топології. Виправленням може бути виправлення селектора Нод, виправлення толерантності чи зміна StorageClass, а не випадкове видалення PVC.

Terminal window
k describe pvc db-data -n payments
k describe pod db-0 -n payments
k get storageclass fast-zonal -o yaml
k get nodes --show-labels

Підказка для активного навчання: уявіть, що PVC в очікуванні без корисних подій, StorageClass існує, а його режим прив’язки — WaitForFirstConsumer. Що станеться, якщо ви створите лише PVC і ніколи не створите Под, який на нього посилається? Відповідь має змінити те, як ви тлумачите Pending: іноді це стан очікування, створений за задумом, а не стан помилки, спричинений відсутнім сховищем.

Прив’язка також взаємодіє зі storageClassName так, що збиває з пантелику багатьох операторів. Пропуск поля дозволяє використовувати StorageClass за замовчуванням, якщо такий є в кластері. Явне встановлення storageClassName: "" відмовляється від динамічного виділення та просить Kubernetes прив’язатися лише до вручну створеного PV без класу. Ці дві форми YAML виглядають схоже для втомленої людини, але виражають різні наміри для площини управління.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: manual-only
spec:
storageClassName: ""
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

Найбезпечніша позиція налагодження — прочитати специфікацію PVC, перш ніж припускати, що кластер зламано. Перевірте запитаний клас, ємність, режими доступу, джерело даних та події. Потім перевірте, чи існують відповідні PV, чи мало б відбутися динамічне виділення. Лише після цих перевірок слід вирішувати, чи редагувати маніфест, створювати відсутній ресурс або досліджувати зовнішній драйвер CSI.

3. Пов’яжіть симптоми Под’а з подіями сховища

Розділ «3. Пов’яжіть симптоми Под’а з подіями сховища»

Усунення несправностей сховища починається з Под’а, бо користувачі зазвичай повідомляють про симптом навантаження, а не про стан PV. Под, що застряг у стані ContainerCreating, часто означає, що контейнерний образ навіть не запустився; Kubernetes може бути заблокований на приєднанні чи монтуванні томів. Под, який запускається, а потім падає, може означати, що том успішно змонтувався, але застосунок не може прочитати, записати чи знайти очікувані файли.

Перша команда для проблеми запуску Под’а — зазвичай k describe pod. Розділ Events каже вам, чи не вдалося kubelet змонтувати том, чи не вдалося контролеру приєднання приєднати диск, чи відсутній PVC, чи не вдалося спроєктувати секрет або ключ ConfigMap. Ця команда дає вам міст між станом навантаження та станом сховища.

Terminal window
k describe pod api-0 -n prod

Якщо подія згадує відсутній PVC, огляньте заявку в тому самому просторі імен. Імена PVC локальні для простору імен, і заявка з тим самим іменем в іншому просторі імен не допоможе цьому Под’у. Якщо заявка не існує, створіть передбачуваний PVC чи виправте маніфест Под’а так, щоб він посилався на правильний. Якщо заявка існує, але в очікуванні, переходьте до k describe pvc.

Terminal window
k get pvc -n prod
k describe pvc api-data -n prod

Якщо подія згадує FailedMount для ConfigMap чи Secret, перевірте, чи існують згаданий об’єкт та ключ у просторі імен Под’а. Поширена помилка — оновити ім’я ConfigMap, але не посилання на том, або змонтувати ключ через items із помилкою в написанні цього ключа. Kubernetes продовжуватиме повторні спроби, але Под не може запуститися, доки посилання не стане дійсним.

Terminal window
k get configmap app-config -n prod -o yaml
k get secret app-secret -n prod -o yaml

Якщо подія згадує помилку множинного приєднання (multi-attach), визначте, чи приєднано том до іншої Ноди через старий Под. Це поширено з томами ReadWriteOnce після проблеми з Нодою, застряглого Под’а у стані завершення чи агресивної стратегії розгортання. Виправленням не є зміна режиму доступу на заявці. Виправлення — зупинити конкурентний шлях приєднання або дочекатися чистого від’єднання драйвером сховища.

Terminal window
k get pod -A -o wide | grep api-data
k get volumeattachment

Проблеми з правами доступу з’являються пізніше в послідовності. Под може бути у стані Running, але логи показують permission denied, коли процес записує до шляху монтування. У цьому випадку прив’язка сховища спрацювала, і монтування відбулося. Тепер ви налагоджуєте власність Linux, права групи, ідентичність користувача контейнера та контекст безпеки Под’а.

apiVersion: v1
kind: Pod
metadata:
name: writer
spec:
securityContext:
fsGroup: 1000
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "echo ok > /data/probe && sleep 3600"]
securityContext:
runAsUser: 1000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: writer-data

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

Дисциплінований шлях усунення несправностей убезпечує вас від метушні. Почніть із події Под’а, потім огляньте PVC, потім PV, потім StorageClass, потім стан Ноди чи драйвера. На кожному кроці питайте, яку обіцянку дав ресурс і чи виконав наступний ресурс у ланцюгу цю обіцянку. Це перетворює галасливий інцидент на послідовність перевірок, які можна спростувати.

+---------------------+
| User symptom |
| Pod not ready |
+----------+----------+
|
v
+---------------------+
| describe pod |
| Events: mount path |
+----------+----------+
|
v
+---------------------+
| describe pvc |
| Pending or Bound? |
+----------+----------+
|
v
+---------------------+
| inspect pv and sc |
| class, access, zone |
+----------+----------+
|
v
+---------------------+
| verify node/driver |
| attach, permissions |
+---------------------+

Той самий шлях працює для знімків і клонів, але з додатковою гілкою джерела даних. Якщо PVC має відновитися зі знімка, заявка може чекати на готовність знімка чи підтримку драйвера. Якщо PVC має клонувати інший PVC, вихідна заявка має бути в тому самому просторі імен, драйвер має підтримувати клонування, а запит призначення має задовольняти правила розміру драйвера.

4. Використовуйте знімки та клони як інструменти відновлення, а не як прикрасу

Розділ «4. Використовуйте знімки та клони як інструменти відновлення, а не як прикрасу»

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

Клон корисний, коли вам потрібна пряма копія для тестування, міграції чи ремонтних робіт поблизу вихідного навантаження. Оскільки клон використовує інший PVC як свій dataSource, він уникає створення багаторазового об’єкта знімка. Ця простота корисна, але також означає, що сама по собі ця операція не є стратегією резервного копіювання. Якщо вихідні дані пізніше зміняться чи зникнуть, клон є лише тим, що драйвер створив на момент клонування.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-copy
namespace: app
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
dataSource:
name: app-data
kind: PersistentVolumeClaim
apiGroup: ""

Знімок кращий, коли важлива точка відновлення. VolumeSnapshot належить до простору імен, VolumeSnapshotClass описує, як драйвер створює знімки, а VolumeSnapshotContent представляє фактичний дескриптор знімка. Цей шаблон нагадує PVC, StorageClass та PV, але призначення тут — стан відновлення, а не живе сховище Под’а.

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: app-data-before-upgrade
namespace: app
spec:
volumeSnapshotClassName: csi-snapshots
source:
persistentVolumeClaimName: app-data

Відновлення зі знімка створює новий PVC, чий dataSource вказує на VolumeSnapshot. Нова заявка все одно потребує сумісного StorageClass, запиту ємності, режиму доступу та підтримки драйвера. Відновлення — це не команда, що змінює старий PVC на місці; вона створює новий том із точки відновлення, який ви можете змонтувати в Под для перевірки перед перемиканням трафіку.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-restored
namespace: app
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
dataSource:
name: app-data-before-upgrade
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io

Професійна ставка тут — це узгодженість. Знімок, зроблений під час активного запису застосунку, може бути узгодженим щодо збою, але не обов’язково узгодженим щодо застосунку, залежно від застосунку та системи зберігання. Для баз даних команди часто координують знімки із промиванням на рівні застосунку, інструментами резервного копіювання чи тимчасовим призупиненням запису. CKA зазвичай не просить вас розробити корпоративну програму резервного копіювання, але може очікувати, що ви знаєте: ресурс знімка — це не те саме, що перевірене відновлення.

Коли ви усуваєте несправності невдалого знімка чи відновлення, почніть із перевірки, чи існують CRD, чи встановлено контролер знімків, чи драйвер CSI підтримує знімки і чи готовий об’єкт знімка до використання. Відновлення PVC, що залишається в очікуванні, може бути проблемою сховища, проблемою готовності знімка, невідповідністю класу чи невідповідністю ємності. Потік подій знову є найкоротшим шляхом до справжньої проблеми.

Terminal window
k get volumesnapshot -n app
k describe volumesnapshot app-data-before-upgrade -n app
k get volumesnapshotclass
k describe pvc app-data-restored -n app

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

5. Практикуйте екзаменаційні міркування про сховище

Розділ «5. Практикуйте екзаменаційні міркування про сховище»

Підсумкове оцінювання має перевіряти рішення, а не ізольований словник. У CKA важливе запитання — не «що таке PVC?», а «чому цей PVC в очікуванні і що слід змінити, щоб Под міг запуститися без порушення вимоги до сховища?». Цей розділ дає вам синтез, потрібний перед тестом.

Коли ви бачите Под у стані ContainerCreating, не кидайтеся одразу редагувати YAML. Спочатку прочитайте події Под’а та класифікуйте збій. Відсутня заявка, відсутній ConfigMap, невдале приєднання, невдале монтування та відмова в доступі — усі вказують на різні рівні. Швидкий оператор рухається швидко, бо послідовність відпрацьована, а не тому, що він пропускає спостереження.

Коли ви бачите PVC у стані Pending, порівняйте запит із середовищем. Чи існує клас? Чи є клас за замовчуванням, якщо заявка пропустила storageClassName? Чи встановила заявка явно storageClassName: "", що вимикає динамічне виділення? Чи режим прив’язки чекає на Под? Чи є відповідні статичні PV за розміром, режимом доступу, класом, селектором та режимом тому?

Коли ви бачите PV у стані Released, уповільніться. Заявка зникла, але старе посилання на прив’язку та дані, що лежать в основі, можуть залишатися. Якщо політика повторного використання — Retain, Kubernetes свідомо відмовляється передавати ці дані новій заявці автоматично. Для екзаменаційного завдання ви можете прибрати посилання на заявку патчем, коли вам сказано повторно використати том. Для реальної роботи ви також підтверджуєте право власності на дані та їх очищення.

Коли ви бачите подію множинного приєднання, опирайтеся спокусі переписати режими доступу. Том ReadWriteOnce може застрягти на попередній Ноді чи Под’і, і зміна заявки не від’єднає хмарний диск. Знайдіть старого споживача, перевірте стан завершення та огляньте об’єкти VolumeAttachment, коли це доречно. Лише після усунення конфлікту слід очікувати, що новий Под успішно змонтується.

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

Іспит винагороджує малі, оборотні дії. Описати ресурс безпечніше, ніж видалити його. Створити відсутній ключ ConfigMap безпечніше, ніж замінити всю специфікацію Под’а під тиском. Патчити посилання на заявку збереженого PV доречно лише тоді, коли завдання просить зробити його доступним і поводження з даними зрозуміле. Хороша робота зі сховищем точна, бо помилки сховища можуть зберегти неправильні дані або видалити правильні.


  1. PVC без storageClassName та PVC зі storageClassName: "" навмисно відрізняються: перший може використовувати StorageClass кластера за замовчуванням, тоді як другий відмовляється від динамічного виділення й чекає на вручну відповідний PV.

  2. WaitForFirstConsumer є функцією планування не меншою мірою, ніж функцією сховища: вона відкладає прив’язку чи виділення, щоб вибрана Нода та топологія сховища могли узгодитися до того, як буде створено зональний том.

  3. PV у стані Released не є автоматично безпечним для повторного використання: збережені дані можуть належати попередньому власнику заявки, тож Kubernetes вимагає явної адміністративної дії, перш ніж інша заявка зможе до нього прив’язатися.

  4. Успішний об’єкт знімка — це не те саме, що перевірений план відновлення: єдиний доказ того, що сховище у стилі резервної копії працює, — це відновити його в PVC і перевірити, що застосунок може використати відновлені дані.


ПомилкаЧому це шкодитьКраща практика
Ставитися до emptyDir як до довговічного сховищаДані зникають, коли Под видаляється з Ноди, тож переплановане навантаження може втратити важливі файли.Використовуйте emptyDir лише для чорнових даних, кешів та шаблонів передачі між сайдкарами, що витримують заміну Под’а.
Припускати, що PVC в очікуванні завжди означає зламане сховищеWaitForFirstConsumer може навмисно тримати PVC в очікуванні, доки Под не посилається на нього й не стануть відомі обмеження планування.Опишіть PVC, огляньте режим прив’язки StorageClass та перевірте Под, що споживає, перш ніж змінювати ресурси.
Використовувати hostPath для звичайної персистентності застосункуПод стає прив’язаним до структури файлової системи Ноди й може отримати небезпечний доступ до шляхів Ноди.Віддавайте перевагу PVC на основі CSI для даних застосунку, а hostPath залишайте для контрольованих агентів рівня Ноди чи лабораторій.
Забувати, що subPath блокує живі оновлення ConfigMap чи SecretЗмонтований файл не оновлюється при зміні вихідного об’єкта, що може залишити застосунки на застарілій конфігурації.Уникайте subPath для конфігурації, що має оновлюватися наживо, або свідомо перезапускайте Под’и після зміни вихідного об’єкта.
Повторно використовувати збережений PV без перевірки права власностіНаступна заявка може побачити дані попереднього навантаження, створюючи ризики безпеки та коректності.Огляньте, зробіть резервну копію, очистіть і лише тоді прибирайте claimRef чи відтворюйте PV для нової заявки.
Виправляти помилки множинного приєднання зміною режимів доступуСправжня проблема часто полягає у старому приєднанні на іншій Ноді, і зміна YAML може не від’єднати том.Знайдіть старий Под чи VolumeAttachment, усуньте конкурентне приєднання, а потім перевірте, що новий Под монтується.
Оголосити знімок, але ніколи не протестувати відновленняЗнімок, що існує в API, все одно може бути непридатним для відновлення застосунку, якщо припущення про відновлення хибні.Відновіть в окремий PVC, змонтуйте його в перевірочний Под і підтвердьте очікувані файли чи стан бази даних.

Q1: Кеш, що став критичним

Розділ «Q1: Кеш, що став критичним»

Ваша команда запускає воркер обробки зображень, який записує проміжні файли до /work. Под використовує emptyDir, і застосунок тепер очікує, що незавершені завдання відновляться після обслуговування Ноди. Під час осушення (drain) кілька завдань втрачають свої часткові файли. Яку зміну сховища ви б порадили і який компроміс слід пояснити команді?

Відповідь

Перемістіть стан відновлюваних завдань на PVC, бо дані тепер мають пережити видалення та перепланування Под’а. emptyDir був розумним, доки /work містив одноразові чорнові файли, але вимога змінилася, коли часткова робота стала відновлюваним станом.

Компроміс полягає в тому, що довговічне сховище додає міркування про прив’язку, виділення, режим доступу, повторне використання та продуктивність. Команда має вирішити, чи потрібна кожному воркеру власна заявка ReadWriteOnce, чи можна повторювати завдання з об’єктного сховища натомість, і як поводитися зі збереженими чи видаленими томами після завершення завдання. Якщо файли є лише оптимізацією і їх можна дешево перегенерувати, збереження emptyDir із кращою логікою повторних спроб може бути простішим.

Q2: PVC, що чекає, не зазнаючи збою

Розділ «Q2: PVC, що чекає, не зазнаючи збою»

Простір імен містить PVC на ім’я data, який перебуває у стані Pending уже кілька хвилин. k describe pvc data -n app показує подію, що вказує на очікування заявкою першого споживача. StorageClass використовує WaitForFirstConsumer, і жоден Под наразі не посилається на заявку. Що слід зробити далі і чому видалення PVC — неправильний перший крок?

Відповідь

Створіть чи огляньте Под, який має споживати PVC. За WaitForFirstConsumer кластер може навмисно відкладати виділення, доки Под не існує і не можна оцінити обмеження планування. Без споживчого Под’а Kubernetes може ще не знати топологію, де має бути створено том.

Видалення PVC — неправильний перший крок, бо спостережуваний стан відповідає політиці StorageClass. Наступні корисні перевірки — це специфікація Под’а, селектори Нод, правила прив’язки, толерантності та доступні Ноди. Якщо Под не може сплануватися, сховище продовжуватиме чекати, бо планування та виділення пов’язані за задумом.

Q3: Збережений том після випадкового видалення заявки

Розділ «Q3: Збережений том після випадкового видалення заявки»

Розробник видаляє PVC, який був прив’язаний до PV із persistentVolumeReclaimPolicy: Retain. Застосунок недоступний, PV тепер у стані Released, і команда хоче відновити обслуговування без втрати даних. Яку послідовність слід виконати, перш ніж знову зробити том доступним?

Відповідь

Спочатку огляньте PV і підтвердьте, що це очікуваний збережений том. Потім підтвердьте, що дані, які лежать в основі, мають бути повторно використані тим самим застосунком чи власником. У виробничому середовищі зробіть або підтвердьте резервну копію перед зміною стану прив’язки, бо це той момент, коли людська помилка може розкрити чи перезаписати важливі дані.

Після того, як рішення про поводження з даними стане зрозумілим, прибрати старе посилання на заявку чи відтворіть об’єкт PV, щоб він міг стати Available для нового відповідного PVC. Поширена екзаменаційна команда — k patch pv <pv-name> -p '{"spec":{"claimRef": null}}', але цю команду слід використовувати лише тоді, коли повторне використання збережених даних є наміреною дією. Нарешті, відтворіть відповідний PVC і перевірте, що Под монтує дані.

Q4: Розгортання з помилкою множинного приєднання

Розділ «Q4: Розгортання з помилкою множинного приєднання»

Оновлення Деплойменту замінює Под’и, які використовують PVC ReadWriteOnce. Новий Под потрапляє на іншу Ноду й залишається у стані ContainerCreating із помилкою множинного приєднання. Старіший Под, що використовує ту саму заявку, застряг у завершенні на попередній Ноді. Що слід перевірити та відремонтувати, перш ніж змінювати маніфест застосунку?

Відповідь

Перевірте, який Под і Нода досі утримують приєднання тому, перелічивши Под’и з широким виводом та оглянувши пов’язані події чи об’єкти VolumeAttachment. Проблема полягає в тому, що той самий том ReadWriteOnce усе ще приєднаний через старий шлях, тож новий Под не може змонтувати його на іншій Ноді.

Відремонтуйте конкурентне приєднання, дозволивши старому Под’у чисто завершитися, або, якщо контекст завдання це дозволяє і Под справді застряг, примусово видаливши старий Под. Потім перевірте, що драйвер сховища від’єднує том і новий Под може приєднати його. Зміна режиму доступу в маніфесті не є правильним першим ремонтом, бо сховище, що підкріплює дані, може не підтримувати запис з кількох Нод, а поточний конфлікт приєднання залишився б.

Q5: Оновлення Secret, що ніколи не доходить до застосунку

Розділ «Q5: Оновлення Secret, що ніколи не доходить до застосунку»

Застосунок монтує єдиний ключ із Secret до /etc/app/password через subPath. Secret ротується, але застосунок продовжує використовувати старе значення навіть через кілька хвилин. Под у решті здоровий. Яка ймовірна причина і яке експлуатаційне виправлення слід застосувати?

Відповідь

Ймовірна причина — монтування subPath. Монтування томів ConfigMap та Secret можуть отримувати оновлення з вихідного об’єкта, але файл, змонтований через subPath, не оновлюється так само, бо контейнер бачить конкретний змонтований шлях, а не оновлений проєктований каталог.

Експлуатаційне виправлення — перезапустити чи відтворити Под, щоб файл змонтувався знову з новим значенням Secret. Для майбутнього проєктування уникайте subPath для конфігурації, що має ротуватися наживо, або побудуйте явний процес розгортання, що перезапускає Под’и при зміні Secret. Важливе міркування полягає в тому, що об’єкт Secret змінився правильно, але обраний шаблон монтування заблокував очікуване поширення.

Q6: Відновлення зі знімка, що залишається в очікуванні

Розділ «Q6: Відновлення зі знімка, що залишається в очікуванні»

Команда створює VolumeSnapshot перед оновленням і пізніше створює новий PVC із dataSource, що вказує на цей знімок. PVC відновлення залишається у стані Pending. Що слід оглянути, щоб відрізнити проблему готовності знімка від звичайної проблеми виділення PVC?

Відповідь

Спочатку огляньте VolumeSnapshot, щоб підтвердити, що він існує в тому самому просторі імен, готовий до використання та посилається на відповідний VolumeSnapshotClass. Потім опишіть PVC відновлення, щоб прочитати події про джерело даних, StorageClass, ємність та поведінку провізіонера. Якщо знімок не готовий або відсутні контролер знімків і підтримка знімків CSI, PVC не може відновитися успішно, навіть якщо специфікація PVC виглядає розумною.

Якщо знімок готовий, продовжуйте звичайні перевірки PVC: запитаний розмір, режим доступу, ім’я StorageClass, поведінка класу за замовчуванням та режим прив’язки. Відмінність важлива, бо заявка на відновлення має дві залежності: джерело відновлення має бути дійсним, а запит сховища призначення — здійсненним.

Q7: Под, що працює, але не може записати

Розділ «Q7: Под, що працює, але не може записати»

Под успішно запускається й монтує свій PVC до /data, але логи застосунку показують permission denied при записі /data/state.db. Контейнер виконується від імені користувача з ідентифікатором 1000. Що слід змінити і як ви б довели, що ремонт спрацював?

Відповідь

Додайте чи виправте контекст безпеки Под’а так, щоб змонтований том був доступним для ідентичності процесу. Поширене виправлення — встановити под-рівня fsGroup: 1000 та контейнер-рівня runAsUser: 1000, припускаючи, що тип тому та драйвер шанують поводження з власністю групи. Ключове те, що це не збій прив’язки, бо Под уже працює, а том змонтований.

Доведіть ремонт, виконавши тест запису та читання проти змонтованого шляху, наприклад k exec <pod> -- sh -c 'echo ok > /data/probe && cat /data/probe'. Самого робочого Под’а недостатньо як доказу, бо первинний збій стався всередині межі прав файлової системи.


У цій вправі ви створите простір імен із кількома шаблонами сховища, діагностуєте навмисно зламаний Под, відремонтуєте посилання на заявку та перевірите, що навантаження може записувати до змонтованого сховища. Мета — не запам’ятати команди; мета — попрактикувати рух від симптому Под’а до стану PVC і до ремонту маніфеста.

Ваша команда розгортає невеликий генератор звітів. Йому потрібні тимчасовий кеш, проєктований файл з іменем Под’а для діагностики та персистентний каталог виводу. Колега швидко створив маніфест Под’а, але Под застряг, бо ім’я заявки неправильне. Ваше завдання — визначити зламане посилання на сховище, виправити його та довести, що контейнер може записувати до персистентного монтування.

Крок 1: Створіть простір імен та робочий PVC

Розділ «Крок 1: Створіть простір імен та робочий PVC»

Застосуйте простір імен і PVC. Цей PVC використовує StorageClass кластера за замовчуванням, коли такий є. Якщо ваш лабораторний кластер не має StorageClass за замовчуванням, PVC може залишитися у стані Pending; це все одно корисно, бо ви можете попрактикувати читання події та пояснення відсутнього шляху виділення.

Terminal window
k create namespace storage-review
k apply -n storage-review -f - <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: report-output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF

Перевірте, чи прив’язується PVC. Якщо він залишається в очікуванні, опишіть його та вирішіть, чи причина — відсутній StorageClass за замовчуванням, WaitForFirstConsumer, чи інша проблема виділення.

Terminal window
k get pvc -n storage-review
k describe pvc report-output -n storage-review

Крок 2: Створіть зламаний Под, що посилається на неправильну заявку

Розділ «Крок 2: Створіть зламаний Под, що посилається на неправильну заявку»

Наступний Под навмисно посилається на report-output-wrong, якого не існує. Под також використовує кеш emptyDir та проєктований файл downward API, щоб ви могли побачити кілька типів томів в одному навантаженні.

Terminal window
k apply -n storage-review -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: report-generator
spec:
securityContext:
fsGroup: 1000
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- |
echo "pod=$(cat /meta/pod-name)" > /cache/report.txt
cp /cache/report.txt /output/report.txt
cat /output/report.txt
sleep 3600
securityContext:
runAsUser: 1000
volumeMounts:
- name: cache
mountPath: /cache
- name: output
mountPath: /output
- name: pod-meta
mountPath: /meta
readOnly: true
volumes:
- name: cache
emptyDir:
sizeLimit: 64Mi
- name: output
persistentVolumeClaim:
claimName: report-output-wrong
- name: pod-meta
downwardAPI:
items:
- path: pod-name
fieldRef:
fieldPath: metadata.name
EOF

Опишіть Под і знайдіть подію сховища. Не виправляйте маніфест, доки не зможете вказати, який том зазнав збою і який об’єкт Kubernetes відсутній.

Terminal window
k get pod report-generator -n storage-review
k describe pod report-generator -n storage-review

Крок 3: Відремонтуйте посилання на заявку

Розділ «Крок 3: Відремонтуйте посилання на заявку»

Оскільки посилання на томи Под’а є частиною специфікації Под’а, практичний ремонт — видалити й відтворити Под із правильним іменем заявки. У навантаженнях, керованих контролером, ви б замість цього оновили шаблон Деплойменту, StatefulSet чи Job, а не редагували окремий Под вручну.

Terminal window
k delete pod report-generator -n storage-review
k apply -n storage-review -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: report-generator
spec:
securityContext:
fsGroup: 1000
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- |
echo "pod=$(cat /meta/pod-name)" > /cache/report.txt
cp /cache/report.txt /output/report.txt
cat /output/report.txt
sleep 3600
securityContext:
runAsUser: 1000
volumeMounts:
- name: cache
mountPath: /cache
- name: output
mountPath: /output
- name: pod-meta
mountPath: /meta
readOnly: true
volumes:
- name: cache
emptyDir:
sizeLimit: 64Mi
- name: output
persistentVolumeClaim:
claimName: report-output
- name: pod-meta
downwardAPI:
items:
- path: pod-name
fieldRef:
fieldPath: metadata.name
EOF

Дочекайтеся запуску Под’а. Якщо PVC усе ще в очікуванні, бо вашому кластеру бракує динамічного виділення, опишіть PVC і запишіть відсутню умову сховища замість того, щоб форсувати непов’язані зміни.

Terminal window
k get pod report-generator -n storage-review -w

Крок 4: Перевірте поведінку читання та запису

Розділ «Крок 4: Перевірте поведінку читання та запису»

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

Terminal window
k exec -n storage-review report-generator -- cat /output/report.txt
k exec -n storage-review report-generator -- sh -c 'echo verified >> /output/report.txt && cat /output/report.txt'

Крок 5: Приберіть лабораторні ресурси

Розділ «Крок 5: Приберіть лабораторні ресурси»

Приберіть простір імен, коли завершите. Якщо ваш кластер створив динамічно виділений том із політикою повторного використання Delete, сховище, що підкріплює дані, має бути видалене провізіонером. Якщо ваше середовище використовує іншу політику повторного використання, огляньте PV після прибирання.

Terminal window
k delete namespace storage-review
k get pv
  • Ви можете пояснити, чому перший Под залишився у стані ContainerCreating, та визначити точне відсутнє посилання на заявку з подій Под’а.

  • Ви можете розрізнити томи emptyDir, downward API та підкріплений PVC у специфікації Под’а й пояснити, який життєвий цикл має кожен із них.

  • Ви можете описати стан PVC і вирішити, чи Pending означає реальну проблему виділення, чи очікувану поведінку WaitForFirstConsumer.

  • Ви можете відтворити Под із правильним claimName і перевірити, що змонтований шлях виводу приймає записи від не-root-користувача контейнера.

  • Ви можете пояснити, що сталося б із персистентними даними, якби прив’язаний PV PVC використовував Delete проти Retain як свою політику повторного використання.


Переходьте до Частини 5: Усунення несправностей, щоб побудувати ширший діагностичний робочий процес для збоїв кластера та навантажень Kubernetes.

  • cncf.io: cka — Сторінка CNCF CKA прямо описує іспит як орієнтований на продуктивність, командний рядок, і визначає Storage у 10%.
  • kubernetes.io: volumes — Документ Volumes прямо описує життєвий цикл emptyDir та його поведінку при збоях контейнерів.
  • kubernetes.io: pod security standards — Сторінка Pod Security Standards прямо перелічує томи hostPath як заборонені в політиці Baseline.
  • kubernetes.io: persistent volumes — Документ Persistent Volumes стверджує, що PV є ресурсами кластера, а заявки мають існувати в тому самому просторі імен, що й Под, який їх використовує.
  • kubernetes.io: storage classes — Документ StorageClass прямо пояснює WaitForFirstConsumer та його топологічно-обізнану поведінку планування.
  • kubernetes.io: volume pvc datasource — Документ CSI Volume Cloning прямо описує модель dataSource, залежність від CSI та вимогу того самого простору імен.
  • kubernetes.io: volume snapshots — Документ Volume Snapshots прямо каже, що об’єкти API є CRD, підтримка знімків можлива лише через CSI, а компоненти на боці контролера є обов’язковими.
  • kubernetes.io: kubernetes 1.20 volume snapshot moves to ga — Офіційний допис Kubernetes про GA знімків прямо каже, що відновлення зі знімка виділяє новий том і не підтримує повернення наявного PVC.
  • kubernetes.io: security context — Сторінка завдання Security Context документує ефекти fsGroup та зазначає специфічну для драйвера CSI підтримку поводження з власністю та правами.