Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.
Сховища інформації
- 1: Томи
- 2: Постійні томи
- 3: Проєкційні томи
- 4: Ефемерні томи
- 5: Класи атрибутів томів
- 6: Класи сховищ
- 7: Динамічне надання томів
- 8: Знімки томів
- 9: Класи знімків томів
- 10: Клонування томів CSI
- 11: Наповнювачі томів та джерела даних
- 12: Місткість сховища
- 13: Обмеження томів на вузлі
- 14: Локальне тимчасове сховище
- 15: Моніторинг справності томів
- 16: Сховище у Windows
1 - Томи
Томи Kubernetes дають контейнерам у Podʼі змогу отримувати доступ до даних і обмінюватися ними через файлову систему. Існують різні види томів, які можна використовувати для різних цілей, зокрема:
- заповнення файлу конфігурації на основі ConfigMap або Secret
- надання Podʼу тимчасового робочого простору
- спільне використання файлової системи двома різними контейнерами в одному Podʼі
- спільне використання файлової системи двома різними Podʼами (навіть якщо ці Podʼи працюють на різних вузлах)
- надійне зберігання даних, щоб вони залишалися доступними, навіть якщо Pod перезапускається або замінюється
- передавання конфігураційної інформації застосунку, що працює в контейнері, на основі відомостей про Pod, у якому перебуває контейнер (наприклад, повідомлення sidecar-контейнеру, у якому просторі імен працює Pod)
- надання доступу лише для читання до даних в іншому образі контейнера
Обмін даними може відбуватися між різними локальними процесами всередині контейнера, або між різними контейнерами, або між Podʼами.
Чому томи важливі
Збереження даних: Файли на диску в контейнері є ефемерними, що створює певні проблеми для нетривіальних застосунків, які працюють у контейнерах. Одна з проблем виникає, коли контейнер аварійно завершує роботу або зупиняється: стан контейнера не зберігається, тому всі файли, створені або змінені протягом життя контейнера, втрачаються. Після аварійного завершення kubelet перезапускає контейнер із чистим станом.
Спільне сховище: Ще одна проблема виникає, коли в
Podпрацює кілька контейнерів, яким потрібно спільно використовувати файли. Налаштувати спільну файлову систему для всіх контейнерів і отримати до неї доступ може бути складно.
Абстракція тому в Kubernetes може допомогти розвʼязати обидві ці проблеми.
Перш ніж дізнатися про томи, PersistentVolumes та PersistentVolumeClaims, вам слід прочитати про Podʼи і переконатися, що ви розумієте, як Kubernetes використовує Podʼи для запуску контейнерів.
Як томи працюють
Kubernetes підтримує багато типів томів. Pod може використовувати будь-яку кількість типів томів одночасно. Типи ефемерних томів мають життєвий цикл, повʼязаний із конкретним Podʼом, а постійні томи існують довше за будь-який окремий Pod. Коли Pod припиняє існування, Kubernetes знищує ефемерні томи; однак Kubernetes не знищує постійні томи. Для будь-якого виду тому в певному Podʼі дані зберігаються під час перезапусків контейнерів.
По суті, том — це тека, можливо, з деякими даними, доступна контейнерам у Podʼі. Те, як ця тека зʼявляється, який носій її підтримує і який вона має вміст, визначається конкретним типом тому.
Щоб використати том, вкажіть томи, які потрібно надати Podʼу, у .spec.volumes і вкажіть, куди монтувати ці томи в контейнерах, у .spec.containers[*].volumeMounts.
Коли Pod запускається, процес у контейнері бачить файлову систему, складену з початкового вмісту образу контейнера і томів (якщо їх визначено), змонтованих усередині контейнера. Процес бачить кореневу файлову систему, яка спочатку відповідає вмісту образу контейнера. Будь-які записи в цій ієрархії файлової системи, якщо їх дозволено, впливають на те, що процес бачить під час наступного доступу до файлової системи. Томи монтуються за вказаними шляхами у файловій системі контейнера. Для кожного контейнера, визначеного в Podʼі, потрібно окремо вказати, куди монтувати кожен том, який він використовує.
Томи не можуть монтуватися всередині інших томів (але дивіться Використання subPath про споріднений механізм). Також том не може містити жорстке посилання на щось в іншому томі.
Типи томів
Kubernetes підтримує кілька типів томів.
configMap
ConfigMap надає спосіб вставляти конфігураційні дані в Podʼи. На дані, збережені в ConfigMap, можна посилатися в томі типу configMap, а потім їх використовуватимуть контейнеризовані застосунки, що працюють у Podʼі.
Посилаючись на ConfigMap, ви вказуєте в томі назву ConfigMap. Ви можете налаштувати шлях для конкретного запису в ConfigMap. Наведена нижче конфігурація показує, як змонтувати ConfigMap log-config у Pod з назвою configmap-pod:
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level.conf
ConfigMap log-config монтується як том, і весь вміст, збережений у його записі log_level, монтується в Pod за шляхом /etc/config/log_level.conf. Зверніть увагу, що цей шлях утворюється з mountPath тому та path із ключем log_level.
Примітка:
Ви повинні створити ConfigMap, перш ніж ви зможете його використовувати.
ConfigMap завжди монтується як
readOnly.Контейнер, який використовує ConfigMap як монтування тому
subPath, не отримуватиме оновлень, коли ConfigMap змінюється.Текстові дані надаються у вигляді файлів у кодуванні UTF-8. Для інших кодувань символів використовуйте
binaryData.
downwardAPI
Том downwardAPI робить дані downward API доступними для застосунків. У томі ви можете знайти надані дані у вигляді файлів лише для читання у форматі звичайного тексту.
Примітка:
Контейнер, який використовує downward API як монтування томуsubPath, не отримує оновлень, коли значення полів змінюються.Докладніше дивіться в Передавання інформації про Pod контейнерам через файли.
emptyDir
Для Podʼа, який визначає том emptyDir, том створюється, коли Pod призначається вузлу. Як випливає з назви, том emptyDir спочатку порожній. Усі контейнери в Podʼі можуть читати й записувати ті самі файли в томі emptyDir, хоча цей том може бути змонтований за однаковими або різними шляхами в кожному контейнері. Коли Pod вилучається з вузла з будь-якої причини, дані в emptyDir видаляються назавжди.
Примітка:
Аварійне завершення контейнера не вилучає Pod із вузла. Дані в томіemptyDir зберігаються під час аварійних завершень контейнера.Деякі способи використання emptyDir:
- робочий простір, наприклад, для сортування злиттям на диску
- контрольні точки тривалих обчислень для відновлення після збоїв
- зберігання файлів, які отримує контейнер менеджера вмісту, поки контейнер вебсервера обслуговує ці дані
Поле emptyDir.medium визначає, де зберігаються томи emptyDir. Стандартно томи emptyDir зберігаються на носії вузла, наприклад, на диску, SSD або в мережевому сховищі, залежно від вашого середовища. Якщо встановити поле emptyDir.medium у "Memory", Kubernetes натомість монтує tmpfs (файлову систему в оперативній памʼяті). Хоча tmpfs дуже швидкий, памʼятайте, що, на відміну від дисків, файли, які ви записуєте, враховуються в обмеженні памʼяті контейнера, який їх записав.
Для стандартного носія можна вказати обмеження розміру, яке обмежує місткість тому emptyDir. Простір виділяється з тимчасового сховища вузла. Якщо воно заповниться з іншого джерела (наприклад, файлами логів або накладеннями образів), місце в emptyDir може закінчитися раніше, ніж буде досягнуто цього обмеження. Якщо розмір не вказано, томи в памʼяті отримують розмір, що дорівнює памʼяті вузла, доступній для розподілу.
Увага:
Перегляньте тут моменти, які слід врахувати щодо керування ресурсами під час використанняemptyDir у памʼяті.More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the EmptyDirVolumeMode feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Поле emptyDir.mode дозволяє встановити біти дозволів Unix на теці emptyDir, вказавши значення від 0000 до 01777 (у вісімковій системі). Це відповідає тому самому шаблону, що й поле defaultMode у томах Secret і ConfigMap. Якщо mode не вказано, тека створюється зі стандартними дозволами 0777.
Встановлення власного режиму корисне, коли ви хочете обмежити доступ лише власником і групою (наприклад, 0750) або встановити sticky bit на спільній теці, щоб лише власники файлів могли видаляти свої файли (наприклад, 01777).
Примітка:
ЯкщоfsGroup встановлено в контексті безпеки Podʼа, групові дозволи, застосовані fsGroup, перевизначають mode, вказаний тут. Поле mode не впливає на Windows.Приклад конфігурації emptyDir
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
Приклад конфігурації emptyDir у памʼяті
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
medium: Memory
emptyDir і зміна розміру Podʼа на місці
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the InPlacePodVerticalScalingMemoryBackedVolumes feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Коли функціональну можливість InPlacePodVerticalScalingMemoryBackedVolumes ввімкнено, ви можете динамічно змінювати sizeLimit томів emptyDir у памʼяті (medium: Memory) без перезапуску Podʼа або його контейнерів.
Докладніше дивіться в Зміна розміру ресурсів CPU та памʼяті, призначених контейнерам.
Приклад конфігурації дозволів emptyDir
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
mode: 01777
fc (fibre channel)
Тип тому fc дозволяє монтувати в Pod наявний блоковий том сховища Fibre Channel. Ви можете вказати одне чи кілька цільових всесвітніх імен (world wide names, WWN) за допомогою параметра targetWWNs у конфігурації тому. Якщо вказано кілька WWN, targetWWNs очікує, що ці WWN належать до багатошляхових зʼєднань.
Примітка:
Ви повинні заздалегідь налаштувати зонування FC SAN, щоб виділити та маскувати ці LUN (томи) для цільових WWN, щоб хости Kubernetes могли отримати до них доступ.gcePersistentDisk (застаріло)
У Kubernetes 1.37 усі операції для вбудованого типу gcePersistentDisk перенаправляються на драйвер CSI pd.csi.storage.gke.io.
Вбудований драйвер сховища gcePersistentDisk визнано застарілим у випуску Kubernetes v1.17, а потім повністю вилучено у випуску v1.28.
Проєкт Kubernetes пропонує натомість використовувати сторонній драйвер сховища Google Compute Engine Persistent Disk CSI.
gitRepo (вимкнено)
Попередження:
Kubernetes 1.37 не містить драйвера томів gitRepo. Останньою версією, яка надавала можливість використовувати цей драйвер, була Kubernetes v1.35, а застарілим він став із мінорного випуску v1.11.
Щоб надати Pod зі змонтованим репозиторієм Git, ви можете змонтувати том emptyDir в init-контейнер, який клонує репозиторій за допомогою Git, а потім змонтувати EmptyDir у контейнер Podʼа.
Ви можете обмежити використання томів gitRepo у своєму кластері за допомогою політик, таких як ValidatingAdmissionPolicy. Ви можете використати наведений нижче вираз Common Expression Language (CEL) як частину політики, щоб відхиляти використання томів gitRepo:
!has(object.spec.volumes) || !object.spec.volumes.exists(v, has(v.gitRepo))
hostPath
Том hostPath монтує файл або теку з файлової системи вузла-хоста у ваш Pod. Більшості Podʼів це не потрібно, але це потужний запасний вихід для деяких застосунків.
Попередження:
Використання типу тому hostPath створює багато ризиків для безпеки. Якщо можете уникнути використання тому hostPath, зробіть це. Наприклад, натомість визначте й використовуйте local PersistentVolume.
Якщо ви обмежуєте доступ до певних тек на вузлі за допомогою перевірки під час допуску, це обмеження є ефективним лише тоді, коли ви додатково вимагаєте, щоб усі монтування цього тому hostPath були лише для читання. Якщо ви дозволяєте ненадійному Podʼу монтувати будь-який шлях хоста для читання й запису, контейнери цього Podʼа можуть зловжити цим монтуванням хоста для читання й запису.
Будьте обережні, використовуючи томи hostPath, незалежно від того, чи монтуються вони лише для читання, чи для читання й запису, оскільки:
- Доступ до файлової системи хоста може розкрити привілейовані системні облікові дані (наприклад, для kubelet) або привілейовані API (наприклад, сокет середовища виконання контейнерів), які можна використати для виходу з контейнера або для атаки на інші частини кластера.
- Podʼи з однаковою конфігурацією (наприклад, створені з PodTemplate) можуть поводитися по-різному на різних вузлах через різні файли на вузлах.
- Використання тому
hostPathне вважається використанням ефемерного сховища. Ви маєте самостійно стежити за використанням диска, оскільки надмірне використання диска томамиhostPathпризведе до тиску на диск вузла.
Деякі способи використання hostPath:
- запуск контейнера, якому потрібен доступ до системних компонентів рівня вузла (наприклад, контейнера, який передає системні логи до центрального місця, отримуючи доступ до цих логів через монтування
/var/logлише для читання) - надання конфігураційного файлу, що зберігається на хост-системі, у режимі лише для читання статичному Podʼу; на відміну від звичайних Podʼів, статичні Podʼи не можуть отримувати доступ до ConfigMaps
Типи томів hostPath
Крім обовʼязкової властивості path, ви можете за потреби вказати type для тому hostPath.
Доступні значення для type:
| Значення | Поведінка |
|---|---|
"" | Порожній рядок (стандартно) призначений для зворотної сумісності й означає, що перед монтуванням тому hostPath перевірки не виконуватимуться. |
DirectoryOrCreate | Якщо за вказаним шляхом нічого немає, там за потреби буде створено порожню теку з дозволами 0755, з тією самою групою та власником, що й у kubelet. |
Directory | Тека має існувати за вказаним шляхом. |
FileOrCreate | Якщо за вказаним шляхом нічого немає, там за потреби буде створено порожній файл із дозволами 0644, з тією самою групою та власником, що й у kubelet. |
File | Повинен існувати файл за вказаним шляхом. |
Socket | Має існувати UNIX-сокет за вказаним шляхом. |
CharDevice | (Лише вузли Linux) Має існувати символьний пристрій за вказаним шляхом. |
BlockDevice | (Лише вузли Linux) Має існувати блоковий пристрій за вказаним шляхом. |
Увага:
РежимFileOrCreate не створює батьківську теку файлу. Якщо батьківської теки змонтованого файлу не існує, Podʼу не вдасться запуститися. Щоб забезпечити роботу цього режиму, можна спробувати монтувати теки та файли окремо, як показано в прикладі FileOrCreate для hostPath.Деякі файли або теки, створені на базових хостах, можуть бути доступні лише користувачу root. Тоді вам потрібно або запускати процес як root у привілейованому контейнері, або змінити дозволи файлів на хості, щоб читати з тому hostPath або записувати в нього.
Приклад конфігурації hostPath
---
# Цей маніфест монтує /data/foo на вузлі як /foo всередині
# єдиного контейнера, який працює в межах Podʼа hostpath-example-linux
#
# Монтування в контейнер тільки для читання
apiVersion: v1
kind: Pod
metadata:
name: hostpath-example-linux
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: example-container
image: registry.k8s.io/test-webserver
volumeMounts:
- mountPath: /foo
name: example-volume
readOnly: true
volumes:
- name: example-volume
# монтувати /data/foo, але тільки якщо ця тека вже існує
hostPath:
path: /data/foo # розташування теки на вузлі
type: Directory # це поле є необовʼязковим
---
# Цей маніфест монтує C:\Data\foo на вузлі як C:\foo всередині
# єдиного контейнера, який працює в межах Podʼа hostpath-example-windows
#
# Монтування в контейнер тільки для читання
apiVersion: v1
kind: Pod
metadata:
name: hostpath-example-windows
spec:
os: { name: windows }
nodeSelector:
kubernetes.io/os: windows
containers:
- name: example-container
image: microsoft/windowsservercore:1709
volumeMounts:
- name: example-volume
mountPath: "C:\\foo"
readOnly: true
volumes:
# монтувати C:\Data\foo з вузла, але тільки якщо ця тека вже існує
- name: example-volume
hostPath:
path: "C:\\Data\\foo" # розташування теки на вузлі
type: Directory # це поле є необовʼязковим
Приклад конфігурації hostPath для FileOrCreate
У наведеному нижче маніфесті визначено Pod, який монтує /var/local/aaa всередині єдиного контейнера Podʼа. Якщо на вузлі ще немає шляху /var/local/aaa, kubelet створює його як теку, а потім монтує в Pod.
Якщо /var/local/aaa вже існує, але не є текою, Pod завершується збоєм. Крім того, kubelet намагається створити файл /var/local/aaa/1.txt усередині цієї теки (з погляду хоста); якщо за цим шляхом уже щось існує і це не звичайний файл, Pod завершується збоєм.
Ось приклад маніфесту:
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: test-webserver
image: registry.k8s.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Переконайтеся, що теку файлу створено.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
image
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.36. It was first available in the v1.31 release.
Джерело тому image представляє обʼєкт OCI (образ контейнера або артефакт), який доступний на хост-машині kubelet.
Ось приклад використання джерела тому image:
apiVersion: v1
kind: Pod
metadata:
name: image-volume
spec:
containers:
- name: shell
command: ["sleep", "infinity"]
image: debian
volumeMounts:
- name: volume
mountPath: /volume
volumes:
- name: volume
image:
reference: quay.io/crio/artifact:v2
pullPolicy: IfNotPresent
Том розвʼязується під час запуску Podʼа залежно від значення pullPolicy:
Always- kubelet завжди намагається завантажити посилання. Якщо завантаження не вдається, kubelet переводить Pod у стан
Failed. Never- kubelet ніколи не завантажує посилання й використовує лише локальний образ або артефакт. Pod переходить у стан
Failed, якщо будь-які шари образу ще не присутні локально або якщо маніфест цього образу ще не закешовано. IfNotPresent- kubelet завантажує посилання, якщо його ще немає на диску. Pod переходить у стан
Failed, якщо посилання немає й завантаження не вдається.
Том розвʼязується повторно, якщо Pod видаляють і створюють заново, тобто новий віддалений вміст стане доступним після повторного створення Podʼа. Збій розвʼязання або завантаження образу під час запуску Podʼа заблокує запуск контейнерів і може додати значну затримку. Спроби після збоїв повторюватимуться за звичайним механізмом backoff для томів, а про збої буде повідомлено в полях reason і message Podʼа.
Типи обʼєктів, які може монтувати цей том, визначаються реалізацією середовища виконання контейнерів на хост-машині. Вони мають включати щонайменше всі дійсні типи, які підтримує поле образу контейнера. Обʼєкт OCI монтується в одну теку (spec.containers[*].volumeMounts[*].mountPath) і лише для читання.
Крім того:
- Монтування
subPathабоsubPathExprдля контейнерів (spec.containers[*].volumeMounts[*].subPath,spec.containers[*].volumeMounts[*].subPathExpr) підтримуються лише починаючи з Kubernetes v1.33. - Поле
spec.securityContext.fsGroupChangePolicyне має жодного ефекту для цього типу тому. - Контролер допуску
AlwaysPullImagesтакож працює для цього джерела тому, як і для образів контейнерів.
Для типу image доступні такі поля:
reference- Посилання на артефакт, який слід використовувати. Наприклад, ви можете вказати
registry.k8s.io/conformance:v1.37.0, щоб завантажити файли з образу тестів на відповідність Kubernetes. Працює так само, якpod.spec.containers[*].image. Секрети завантаження образів збираються так само, як для образу контейнера: шляхом пошуку облікових даних вузла, секретів завантаження образів ServiceAccount і секретів завантаження образів зі специфікації Podʼа. Це поле є необовʼязковим, щоб керування конфігурацією вищого рівня могло задавати стандартні значення або перевизначати образи контейнерів у контролерах робочих навантажень, таких як Deployments і StatefulSets. Докладніше про образи контейнерів. pullPolicy- Політика завантаження обʼєктів OCI. Можливі значення:
Always,NeverабоIfNotPresent. СтандартноAlways, якщо вказано теґ:latest, інакшеIfNotPresent.
Докладніше про використання цього джерела тому дивіться в прикладі Використання тому image з Podʼом.
Статус Podʼа та томи image
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the ImageVolumeWithDigest feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Якщо у вашому кластері ввімкнено функціональну можливість ImageVolumeWithDigest, то щоразу, коли ви вказуєте том image для Podʼа, kubelet оновлює статус Podʼа, щоб записати digest образу контейнера, який використовується як джерело тому.
Ось спрощений приклад запущеного Podʼа у вигляді YAML, зокрема з оновленням статусу. Зверніть увагу на нове поле ImageRef у volumeMounts у статусі контейнера.
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: default
spec:
containers:
- name: shell
command: ["sleep", "infinity"]
image: docker.io/library/debian:12
volumeMounts:
- name: artifact
mountPath: /data
volumes:
- name: artifact
image:
reference: quay.io/crio/artifact:v2
pullPolicy: IfNotPresent
status:
containerStatuses:
- containerID: containerd://examplecontainerid1234567890abcdef
image: docker.io/library/debian:12
imageID: docker-pullable://docker.io/library/debian@sha256:3f1d6c17773a45c97bd8f158d665c9709d7b29ed7917ac934086ad96f92e4510
volumeMounts:
- name: artifact
mountPath: /data
readOnly: true
imageRef: quay.io/crio/artifact@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
iscsi
Том iscsi дозволяє монтувати наявний том iSCSI (SCSI через IP) у ваш Pod. На відміну від emptyDir, який стирається, коли Pod вилучається, вміст тому iscsi зберігається, а том лише розмонтовується. Це означає, що том iSCSI можна попередньо заповнити даними, і ці дані можна спільно використовувати між Podʼами.
Примітка:
Вам потрібно мати власний сервер iSCSI, на якому створено том, перш ніж ви зможете його використовувати.Особливість iSCSI полягає в тому, що його можуть одночасно монтувати кілька споживачів лише для читання. Це означає, що ви можете попередньо заповнити том своїм набором даних, а потім паралельно надавати його зі стількох Podʼів, скільки потрібно. На жаль, томи iSCSI може монтувати лише один споживач у режимі читання й запису. Одночасний запис не дозволений.
local
Том local представляє змонтований локальний пристрій зберігання, такий як диск, розділ або тека.
Локальні томи можна використовувати лише як статично створені PersistentVolume. Динамічне надання не підтримується.
Порівняно з томами hostPath, томи local використовуються довговічно й переносно, без ручного планування Podʼів на вузли. Система знає про обмеження вузла для тому, переглядаючи спорідненість вузла в PersistentVolume.
Однак томи local залежать від доступності базового вузла й підходять не для всіх застосунків. Якщо вузол стає несправним, том local стає недоступним для Podʼа. Pod, який використовує цей том, не може працювати. Застосунки, що використовують томи local, мають бути здатні витримувати таку знижену доступність, а також потенційну втрату даних, залежно від характеристик надійності базового диска.
У наведеному нижче прикладі показано PersistentVolume, що використовує том local і nodeAffinity:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
Під час використання томів local потрібно встановити nodeAffinity у PersistentVolume. Планувальник Kubernetes використовує nodeAffinity PersistentVolume, щоб планувати ці Podʼи на правильний вузол.
volumeMode PersistentVolume можна встановити в "Block" (замість стандартного значення "Filesystem"), щоб надати локальний том як необроблений блоковий пристрій.
Під час використання локальних томів рекомендується створити StorageClass із volumeBindingMode, встановленим у WaitForFirstConsumer. Докладніше дивіться в прикладі StorageClass для локальних томів. Відкладена привʼязка томів гарантує, що рішення про привʼязку PersistentVolumeClaim також враховуватиме інші обмеження вузла, які може мати Pod, такі як вимоги до ресурсів вузла, селектори вузлів, спорідненість і антиспорідненість Podʼів.
Для кращого керування життєвим циклом локального тому можна окремо запустити зовнішній статичний provisioner. Зверніть увагу, що цей provisioner поки не підтримує динамічне надання. Приклад запуску зовнішнього локального provisioner дивіться в посібнику користувача local volume provisioner.
Примітка:
Локальний PersistentVolume потребує ручного очищення й видалення користувачем, якщо для керування життєвим циклом тому не використовується зовнішній статичний provisioner.nfs
Том nfs дозволяє монтувати наявний спільний ресурс NFS (Network File System) у Pod. На відміну від emptyDir, який стирається, коли Pod вилучається, вміст тому nfs зберігається, а том лише розмонтовується. Це означає, що том NFS можна попередньо заповнити даними, і ці дані можна спільно використовувати між Podʼами. NFS можуть одночасно монтувати кілька записувачів.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
Примітка:
Щоб використовувати NFS, потрібно мати власний запущений сервер NFS з експортованим спільним ресурсом.
Також зверніть увагу, що ви не можете вказувати параметри монтування NFS у специфікації Podʼа. Ви можете встановити параметри монтування на боці сервера або використовувати /etc/nfsmount.conf. Ви також можете монтувати томи NFS через PersistentVolumes, які дозволяють встановлювати параметри монтування.
persistentVolumeClaim
Том persistentVolumeClaim використовується для монтування PersistentVolume у Pod. PersistentVolumeClaims — це спосіб для користувачів «запросити» надійне сховище (наприклад, том iSCSI), не знаючи деталей конкретного хмарного середовища.
Докладніше дивіться в інформації про PersistentVolumes.
portworxVolume (застаріло)
portworxVolume — це еластичний рівень блокового сховища, який працює в гіперконвергентному режимі з Kubernetes. Portworx визначає відбитки сховища на сервері, розподіляє його за рівнями на основі можливостей і агрегує місткість на кількох серверах. Portworx працює в гостьовій системі віртуальних машин або на вузлах Linux без віртуалізації (bare metal).
portworxVolume можна створити динамічно через Kubernetes або попередньо надати й послатися на нього в Podʼі. Ось приклад Podʼа, який посилається на попередньо наданий том Portworx:
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# Цей том Portworx повинен вже існувати.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
Примітка:
Переконайтеся, що у вас є наявний PortworxVolume з назвоюpxvol, перш ніж використовувати його в Podʼі.Міграція на Portworx CSI
This is a stable feature in Kubernetes, and has been since the 1.33 release. You can no longer toggle this feature (the associated feature gate has been removed).
У Kubernetes 1.37 усі операції для вбудованих томів Portworx стандартно перенаправляються на драйвер Container Storage Interface (CSI) pxd.portworx.com. Portworx CSI Driver має бути встановлений у кластері.
projected
Проєкційний том зіставляє кілька наявних джерел томів з однією текою. Докладніше дивіться проєкційні томи.
secret
Том secret використовується для передавання конфіденційної інформації, такої як паролі, у Podʼи. Ви можете зберігати Secrets в API Kubernetes і монтувати їх як файли для використання Podʼами без прямої привʼязки до Kubernetes. Томи secret підтримуються tmpfs (файловою системою в оперативній памʼяті), тому вони ніколи не записуються на енергонезалежне сховище.
Примітка:
Ви повинні створити Secret в API Kubernetes, перш ніж ви зможете його використовувати.
Secret завжди монтується як
readOnly.Контейнер, який використовує Secret як монтування тому
subPath, не отримуватиме оновлень Secret.
Докладніше дивіться Налаштування Secrets.
Використання subPath
Іноді корисно спільно використовувати один том для кількох цілей в одному Podʼі. Властивість volumeMounts[*].subPath задає підшлях усередині вказаного тому замість його кореня.
У наведеному нижче прикладі показано, як налаштувати Pod зі стеком LAMP (Linux, Apache, MySQL, PHP) за допомогою одного спільного тому. Цю конфігурацію subPath не рекомендується використовувати в промисловому середовищі.
Код і ресурси PHP-застосунку зіставляються з текою html тому, а база даних MySQL зберігається в теці mysql тому. Наприклад:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
Використання subPath із розширеними змінними середовища
Використовуйте поле subPathExpr, щоб будувати назви тек subPath зі змінних середовища downward API. Властивості subPath та subPathExpr є взаємовиключними.
У цьому прикладі Pod використовує subPathExpr, щоб створити теку pod1 усередині тому hostPath /var/log/pods. Том hostPath отримує назву Pod із downwardAPI. Тека хоста /var/log/pods/pod1 монтується в /logs у контейнері.
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox:1.28
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
# Для змінних використовуються круглі дужки (не фігурні).
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
Ресурси
Носій (наприклад, диск або SSD) тому emptyDir визначається носієм файлової системи, на якій розташована коренева тека kubelet (зазвичай /var/lib/kubelet). Немає обмежень на те, скільки місця може використовувати том emptyDir або hostPath, і немає ізоляції між контейнерами або Podʼами.
Щоб дізнатися про запит місця за допомогою специфікації ресурсів, дивіться як керувати ресурсами.
Зовнішні втулки томів
До зовнішніх втулків томів належать Container Storage Interface (CSI), а також FlexVolume (застарілий). Ці втулки дозволяють постачальникам сховищ створювати власні втулки сховища, не додаючи їхній вихідний код до репозиторію Kubernetes.
Раніше всі втулки томів були «вбудованими». «Вбудовані» втулки збиралися, компонувалися, компілювалися й постачалися разом з основними бінарними файлами Kubernetes. Це означало, що додавання нової системи зберігання до Kubernetes (втулка томів) вимагало внесення коду в основний репозиторій коду Kubernetes.
І CSI, і FlexVolume дозволяють розробляти втулки томів незалежно від кодової бази Kubernetes і розгортати (встановлювати) їх у кластерах Kubernetes як розширення.
Постачальникам сховищ, які хочуть створити зовнішній втулок томів, варто звернутися до FAQ про втулки томів.
csi
Container Storage Interface (CSI) визначає стандартний інтерфейс для систем оркестрування контейнерів (таких як Kubernetes), щоб надавати довільні системи зберігання своїм контейнерним робочим навантаженням.
Докладніше читайте в проєктній пропозиції CSI.
Примітка:
Підтримку версій специфікації CSI 0.2 та 0.3 визнано застарілою в Kubernetes v1.13, і її буде вилучено в майбутньому випуску.Примітка:
Драйвери CSI можуть бути сумісними не з усіма випусками Kubernetes. Перевірте в документації конкретного драйвера CSI підтримувані кроки розгортання для кожного випуску Kubernetes і матрицю сумісності.Після розгортання сумісного з CSI драйвера томів у кластері Kubernetes користувачі можуть використовувати тип тому csi, щоб підʼєднувати або монтувати томи, які надає драйвер CSI.
Том csi можна використовувати в Podʼі трьома різними способами:
- через посилання на PersistentVolumeClaim
- з загальним ефемерним томом
- з ефемерним томом CSI, якщо драйвер це підтримує
Адміністратори сховища можуть використовувати такі поля для налаштування постійного тому CSI:
driver: Рядкове значення, яке задає назву драйвера томів. Це значення має відповідати значенню, яке драйвер CSI повертає вGetPluginInfoResponse, як визначено в специфікації CSI. Kubernetes використовує його, щоб визначити, який драйвер CSI викликати, а компоненти драйвера CSI — щоб визначити, які обʼєкти PV належать цьому драйверу CSI.volumeHandle: Рядкове значення, яке унікально ідентифікує том. Це значення має відповідати значенню, яке драйвер CSI повертає в поліvolume.idвідповідіCreateVolumeResponse, як визначено в специфікації CSI. Значення передається якvolume_idв усіх викликах драйвера томів CSI під час посилання на том.readOnly: Необовʼязкове булеве значення, яке вказує, чи має том бути "ControllerPublished" (підʼєднаний) лише для читання. Стандартно false. Це значення передається драйверу CSI через полеreadonlyуControllerPublishVolumeRequest.fsType: ЯкщоVolumeModePV має значенняFilesystem, це поле можна використати для вказання файлової системи, яку слід використовувати для монтування тому. Якщо том не відформатовано й форматування підтримується, це значення буде використано для форматування тому. Це значення передається драйверу CSI через полеVolumeCapabilityуControllerPublishVolumeRequest,NodeStageVolumeRequestтаNodePublishVolumeRequest.volumeAttributes: Мапа рядків на рядки, яка задає статичні властивості тому. Ця мапа має відповідати мапі, яку драйвер CSI повертає в поліvolume.attributesвідповідіCreateVolumeResponse, як визначено в специфікації CSI. Мапа передається драйверу CSI через полеvolume_contextуControllerPublishVolumeRequest,NodeStageVolumeRequestтаNodePublishVolumeRequest.controllerPublishSecretRef: Посилання на обʼєкт Secret, що містить конфіденційну інформацію, яку слід передати драйверу CSI для завершення викликів CSIControllerPublishVolumeтаControllerUnpublishVolume. Це поле є необовʼязковим і може бути порожнім, якщо Secret не потрібен. Якщо Secret містить більше одного секрету, передаються всі секрети.nodeExpandSecretRef: Посилання на Secret, що містить конфіденційну інформацію, яку слід передати драйверу CSI для завершення виклику CSINodeExpandVolume. Це поле є необовʼязковим і може бути порожнім, якщо Secret не потрібен. Якщо обʼєкт містить більше одного секрету, передаються всі секрети. Коли ви налаштували секретні дані для розширення тому, ініційованого вузлом, kubelet передає ці дані драйверу CSI через викликNodeExpandVolume(). Усі підтримувані версії Kubernetes пропонують полеnodeExpandSecretRefі стандартно роблять його доступним. Випуски Kubernetes до v1.25 не мали цієї підтримки.- Увімкніть функціональну можливість
CSINodeExpandSecretдля кожного kube-apiserver і для kubelet на кожному вузлі. Починаючи з Kubernetes 1.27, цю можливість стандартно ввімкнено, і явно вмикати функціональну можливість не потрібно. Ви також повинні використовувати драйвер CSI, який підтримує або потребує секретних даних під час операцій зміни розміру сховища, ініційованих вузлом. nodePublishSecretRef: Посилання на обʼєкт Secret, що містить конфіденційну інформацію, яку слід передати драйверу CSI для завершення виклику CSINodePublishVolume. Це поле є необовʼязковим і може бути порожнім, якщо Secret не потрібен. Якщо обʼєкт Secret містить більше одного секрету, передаються всі секрети.nodeStageSecretRef: Посилання на обʼєкт Secret, що містить конфіденційну інформацію, яку слід передати драйверу CSI для завершення виклику CSINodeStageVolume. Це поле є необовʼязковим і може бути порожнім, якщо Secret не потрібен. Якщо Secret містить більше одного секрету, передаються всі секрети.
Підтримка необроблених блокових томів CSI
Постачальники зовнішніх драйверів CSI можуть реалізувати підтримку необроблених блокових томів у робочих навантаженнях Kubernetes.
Ви можете налаштувати свій PersistentVolume/PersistentVolumeClaim із підтримкою необроблених блокових томів як зазвичай, без будь-яких змін, специфічних для CSI.
Ефемерні томи CSI
Ви можете безпосередньо налаштувати томи CSI у специфікації Podʼа. Томи, вказані таким способом, є ефемерними й не зберігаються після перезапуску Podʼа. Докладніше дивіться в Ефемерні томи.
Докладніше про розроблення драйвера CSI дивіться в документації kubernetes-csi
Проксі CSI для Windows
Втулки вузла CSI мають виконувати різні привілейовані операції, такі як сканування дискових пристроїв і монтування файлових систем. Ці операції відрізняються для кожної операційної системи хоста. На робочих вузлах Linux контейнеризовані втулки вузла CSI зазвичай розгортаються як привілейовані контейнери. На робочих вузлах Windows привілейовані операції для контейнеризованих втулків вузла CSI підтримуються за допомогою csi-proxy — автономного бінарного файлу, що підтримується спільнотою й має бути попередньо встановлений на кожному вузлі Windows.
Докладніше дивіться в посібнику з розгортання втулка CSI, який ви хочете розгорнути.
Міграція на драйвери CSI з вбудованих втулків
Можливість CSIMigration спрямовує операції щодо наявних вбудованих втулків до відповідних втулків CSI (які мають бути встановлені й налаштовані). Завдяки цьому операторам не потрібно змінювати конфігурацію наявних класів сховища, PersistentVolumes або PersistentVolumeClaims (які посилаються на вбудовані втулки) під час переходу на драйвер CSI, що замінює вбудований втулок.
Примітка:
Наявні PV, створені вбудованим втулком томів, можна й надалі використовувати без будь-яких змін конфігурації, навіть після завершення міграції на CSI для цього типу тому і навіть після оновлення до версії Kubernetes, у якій немає вкомпільованої підтримки цього типу сховища.
У межах цієї міграції ви або інший адміністратор кластера повинні встановити й налаштувати відповідний драйвер CSI для цього сховища. Ядро Kubernetes не встановлює це програмне забезпечення за вас.
Після цієї міграції ви також можете визначати нові PVC і PV, які посилаються на застарілі вбудовані інтеграції сховищ. Якщо відповідний драйвер CSI встановлено й налаштовано, створення PV і далі працює, навіть для зовсім нових томів. Фактичне керування сховищем тепер відбувається через драйвер CSI.
Підтримувані операції та можливості включають: надання/видалення, підʼєднання/відʼєднання, монтування/розмонтування та зміну розміру томів.
Вбудовані втулки, які підтримують CSIMigration і мають відповідний реалізований драйвер CSI, перелічено в розділі Типи томів.
flexVolume (застаріло)
FlexVolume — це інтерфейс зовнішніх втулків, який використовує модель на основі exec для взаємодії з драйверами сховища. Бінарні файли драйверів FlexVolume мають бути встановлені в попередньо визначеному шляху втулків томів на кожному вузлі, а в деяких випадках і на вузлах панелі управління.
Podʼи взаємодіють із драйверами FlexVolume через вбудований втулок томів flexVolume.
Такі втулки FlexVolume, розгорнуті як сценарії PowerShell на хості, підтримують вузли Windows:
Примітка:
FlexVolume застарів. Рекомендований спосіб інтеграції зовнішнього сховища з Kubernetes — використовувати зовнішній драйвер CSI.
Супровідники драйвера FlexVolume мають реалізувати драйвер CSI й допомогти користувачам драйверів FlexVolume перейти на CSI. Користувачі FlexVolume мають перевести свої робочі навантаження на еквівалентний драйвер CSI.
Поширення монтування
Увага:
Поширення монтування — це низькорівнева можливість, яка не працює однаково на всіх типах томів. Проєкт Kubernetes рекомендує використовувати поширення монтування лише з томамиhostPath або emptyDir у памʼяті. Докладніше дивіться в issue Kubernetes #95049.Поширення монтування дозволяє надавати томи, змонтовані контейнером, іншим контейнерам у тому самому Podʼі або навіть іншим Podʼам на тому самому вузлі.
Поширення монтування тому контролюється полем mountPropagation у containers[*].volumeMounts. Його значення:
None— Це монтування тому не отримуватиме жодних подальших монтувань, які хост монтує в цей том або будь-яку його підтеку. Так само жодні монтування, створені контейнером, не будуть видимі на хості. Це стандартний режим.Цей режим еквівалентний поширенню монтування
rprivate, як описано вmount(8)Однак середовище виконання CRI може вибрати поширення монтування
rslave(тобтоHostToContainer), коли поширенняrprivateнезастосовне. Відомо, що cri-dockerd (Docker) вибирає поширення монтуванняrslave, коли джерело монтування містить кореневу теку демона Docker (/var/lib/docker).HostToContainer— Це монтування тому отримуватиме всі подальші монтування, які монтуються в цей том або будь-яку його підтеку.Іншими словами, якщо хост монтує щось усередині монтування тому, контейнер побачить, що це там змонтовано.
Так само, якщо будь-який Pod із поширенням монтування
Bidirectionalна той самий том монтує туди щось, контейнер із поширенням монтуванняHostToContainerце побачить.Цей режим еквівалентний поширенню монтування
rslave, як описано вmount(8)Bidirectional— Це монтування тому поводиться так само, як монтуванняHostToContainer. Крім того, усі монтування томів, створені контейнером, поширюватимуться назад на хост і на всі контейнери всіх Podʼів, які використовують той самий том.Звичайний випадок використання цього режиму — Pod із драйвером FlexVolume або CSI чи Pod, якому потрібно щось змонтувати на хості за допомогою тому
hostPath.Цей режим еквівалентний поширенню монтування
rshared, як описано вmount(8)Попередження:
Поширення монтуванняBidirectionalможе бути небезпечним. Воно може пошкодити операційну систему хоста, тому дозволене лише в привілейованих контейнерах. Наполегливо рекомендується знати поведінку ядра Linux. Крім того, усі монтування томів, створені контейнерами в Podʼах, мають бути знищені (розмонтовані) контейнерами під час завершення роботи.
Монтування лише для читання
Монтування можна зробити лише для читання, встановивши поле .spec.containers[*].volumeMounts[*].readOnly у true. Це не робить сам том доступним лише для читання, але конкретний контейнер не зможе записувати в нього. Інші контейнери в Podʼі можуть монтувати той самий том для читання й запису.
У Linux монтування лише для читання стандартно не є рекурсивними. Наприклад, розгляньмо Pod, який монтує /mnt хоста як том hostPath. Якщо в /mnt/<SUBMOUNT> змонтовано для читання й запису іншу файлову систему (таку як tmpfs, NFS або USB-сховище), том, змонтований у контейнері(ах), також матиме /mnt/<SUBMOUNT> із можливістю запису, навіть якщо саме монтування вказано як лише для читання.
Рекурсивні монтування лише для читання
More information about this feature
This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.30 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate RecursiveReadOnlyMounts, Kubernetes ignores it but does not report any error.
Рекурсивні монтування лише для читання можна ввімкнути, встановивши функціональну можливість RecursiveReadOnlyMounts для kubelet і kube-apiserver та встановивши поле .spec.containers[*].volumeMounts[*].recursiveReadOnly для Podʼа.
Допустимі значення:
Disabled(стандартно): без ефекту.Enabled: робить монтування рекурсивно лише для читання. Потрібно виконати всі такі вимоги:readOnlyвстановлено вtruemountPropagationне встановлено або встановлено вNone- Хост працює з ядром Linux v5.12 або новіше
- Середовище виконання контейнерів рівня CRI підтримує рекурсивні монтування лише для читання
- Середовище виконання контейнерів рівня OCI підтримує рекурсивні монтування лише для читання.
Якщо хоча б одна з цих умов не виконується, монтування завершиться збоєм.
IfPossible: намагається застосуватиEnabledі повертається доDisabled, якщо можливість не підтримується ядром або класом середовища виконання.
Приклад:
apiVersion: v1
kind: Pod
metadata:
name: rro
spec:
volumes:
- name: mnt
hostPath:
# tmpfs is mounted on /mnt/tmpfs
path: /mnt
containers:
- name: busybox
image: busybox
args: ["sleep", "infinity"]
volumeMounts:
# /mnt-rro/tmpfs is not writable
- name: mnt
mountPath: /mnt-rro
readOnly: true
mountPropagation: None
recursiveReadOnly: Enabled
# /mnt-ro/tmpfs is writable
- name: mnt
mountPath: /mnt-ro
readOnly: true
# /mnt-rw/tmpfs is writable
- name: mnt
mountPath: /mnt-rw
Коли цю властивість розпізнають kubelet і kube-apiserver, поле .status.containerStatuses[*].volumeMounts[*].recursiveReadOnly встановлюється в Enabled або Disabled.
Власник файлу
Групова власність (GID)
Групова власність файлів тому (GID) контролюється полем spec.securityContext.fsGroup Podʼа.
Докладні кроки налаштування дивіться в Налаштування контексту безпеки для Podʼа або контейнера.
Власність користувача (UID)
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the AtomicWriteVolumeUserFields feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Встановлення функціональної можливості AtomicWriteVolumeUserFields вмикає поля власності користувача файлів (UID) томів configMap, secret, downwardAPI та projected.
Коли defaultUser вказано на рівні тому, він встановлює UID власника для всіх його файлів даних під час створення. На рівні елемента поле user контролює UID власника окремого файлу та має перевагу над defaultUser.
Приклад:
apiVersion: v1
kind: Pod
metadata:
name: volume-user-fields-example
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: volA
mountPath: /mnt/volA
- name: volB
mountPath: /mnt/volB
- name: volC
mountPath: /mnt/volC
volumes:
- name: volA
configMap:
defaultUser: 1000
name: cm1
items:
- key: foo # Owner=defaultUser
path: foo
- key: bar # Owner=user
path: bar
user: 1001
- name: volB
secret: # Owner=defaultUser
defaultUser: 1000
secretName: secret1
- name: volC
projected:
sources:
- secret:
name: secret2
items:
- key: moo # Owner=root
path: moo
- key: baa # Owner=user
path: baa
user: 1000
Реалізації
Відомо, що такі середовища виконання контейнерів підтримують рекурсивні монтування лише для читання.
Рівень CRI:
- containerd, починаючи з v2.0
- CRI-O, починаючи з v1.30
Рівень OCI:
Параметри bind mount
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the VolumeBindMountOptions feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Поле .spec.containers[*].volumeMounts[*].bindMountOptions дозволяє вам застосовувати повʼязані з безпекою прапорці bind mount Linux до будь-якого монтування тому. Допустимі значення:
noexec— запобігає виконанню бінарних файлів на змонтованому томіnodev— ігнорує спеціальні файли пристроїв на змонтованому томіnosuid— ігнорує біти set-user-identifier або set-group-identifier на змонтованому томі
Ці параметри застосовуються для кожного контейнера, тому різні контейнери в одному Podʼі можуть монтувати той самий том із різними параметрами bind mount. Поле не підтримується з томами образів.
Примітка:
Середовище виконання контейнерів (таке як containerd або CRI-O) повинно підтримувати полеmount_options у повідомленні CRI Mount. Якщо середовище виконання не повідомляє про підтримку, kubelet відхиляє Podʼи, які використовують bindMountOptions. Це поле не впливає на вузли Windows.Що далі
Ознайомтеся з прикладом розгортання WordPress і MySQL із постійними томами.
2 - Постійні томи
У цьому документі описано постійні томи в Kubernetes. Рекомендується ознайомитися з томами, StorageClasses та VolumeAttributesClasses.
Вступ
Керування сховищем — це окреме завдання, відмінне від керування обчислювальними екземплярами. Підсистема PersistentVolume надає користувачам та адміністраторам API, який абстрагує деталі того, як сховище надається, від того, як воно споживається. Для цього ми запроваджуємо два нові ресурси API: PersistentVolume і PersistentVolumeClaim.
PersistentVolume (PV) — це частина сховища в кластері, надана адміністратором або динамічно за допомогою класів сховищ. Це ресурс у кластері, так само як вузол є ресурсом кластера. PV — це втулки томів, як і Volumes, але їхній життєвий цикл не залежить від будь-якого окремого Podʼа, який використовує PV. Цей обʼєкт API містить деталі реалізації сховища, чи то NFS, iSCSI, чи специфічна для хмарного провайдера система зберігання.
PersistentVolumeClaim (PVC) — це запит користувача на сховище. Він схожий на Pod. Podʼи споживають ресурси вузла, а PVC споживають ресурси PV. Podʼи можуть запитувати певні обсяги ресурсів (CPU та памʼять). PVC можуть запитувати певний розмір і режими доступу (наприклад, їх можна монтувати як ReadWriteOnce, ReadOnlyMany, ReadWriteMany або ReadWriteOncePod, дивіться AccessModes).
Хоча PersistentVolumeClaims дозволяють користувачам споживати абстрактні ресурси сховища, для різних завдань користувачам часто потрібні PersistentVolumes із різними властивостями, наприклад, продуктивністю. Адміністратори кластера мають бути здатні пропонувати різноманітні PersistentVolumes, які відрізняються не лише розміром і режимами доступу, не розкриваючи користувачам деталей реалізації цих томів. Для цих потреб існує ресурс StorageClass.
Дивіться докладний покроковий опис із робочими прикладами.
Життєвий цикл тому та PVC
PV — це ресурси в кластері. PVC — це запити на ці ресурси, які також діють як квитанції на ресурс. Взаємодія між PV та PVC відбувається за таким життєвим циклом:
Надання
Існує два способи надання PV: статично або динамічно.
Статичне
Адміністратор кластера створює певну кількість PV. Вони містять відомості про реальне сховище, доступне для використання користувачами кластера. Вони існують в API Kubernetes і доступні для споживання.
Динамічне
Коли жоден зі статичних PV, створених адміністратором, не відповідає PersistentVolumeClaim користувача, кластер може спробувати динамічно надати том спеціально для цього PVC. Це надання ґрунтується на StorageClasses: PVC має запитати клас сховища, а адміністратор має створити й налаштувати цей клас, щоб динамічне надання могло відбутися. PVC, які запитують клас "", фактично вимикають для себе динамічне надання.
Щоб увімкнути динамічне надання сховища на основі класу сховища, адміністратор кластера має ввімкнути DefaultStorageClass контролер допуску на API-сервері. Це можна зробити, наприклад, переконавшись, що DefaultStorageClass є серед значень упорядкованого списку, розділеного комами, у прапорці --enable-admission-plugins компонента API-сервера. Докладніше про прапорці командного рядка API-сервера дивіться в документації kube-apiserver.
Привʼязка
Користувач створює або, у разі динамічного надання, уже створив PersistentVolumeClaim із певним запитаним обсягом сховища та певними режимами доступу. Цикл управління в панелі управління стежить за новими PVC, знаходить відповідний PV (якщо це можливо) і привʼязує їх один до одного. Якщо PV було динамічно надано для нового PVC, цикл завжди привʼязуватиме цей PV до PVC. Інакше користувач завжди отримає принаймні те, що запитував, але том може перевищувати запитаний обсяг. Після привʼязки PersistentVolumeClaim є ексклюзивними, незалежно від того, як їх було привʼязано. Привʼязка PVC до PV — це зіставлення один до одного за допомогою ClaimRef, який є двоспрямованою привʼязкою між PersistentVolume і PersistentVolumeClaim.
PVC залишатимуться непривʼязаними необмежено довго, якщо відповідного тому не існує. PVC будуть привʼязані, коли відповідні томи стануть доступними. Наприклад, кластер, забезпечений багатьма PV розміром 50Gi, не відповідатиме PVC, який запитує 100Gi. PVC можна буде привʼязати, коли до кластера буде додано PV розміром 100Gi.
Використання
Podʼи використовують PVC як томи. Кластер перевіряє PVC, щоб знайти привʼязаний том, і монтує цей том для Podʼа. Для томів, які підтримують кілька режимів доступу, користувач вказує бажаний режим, коли використовує свій PVC як том у Podʼі.
Щойно користувач має PVC і цей PVC привʼязано, привʼязаний PV належить користувачеві стільки, скільки потрібно. Користувачі планують Podʼи та отримують доступ до своїх PV, додаючи розділ persistentVolumeClaim у блок volumes Podʼа. Докладніше дивіться в розділі PVC як томи.
Захист обʼєктів сховища, що використовуються
Мета можливості захисту обʼєктів сховища, що використовуються, — гарантувати, що PersistentVolumeClaims (PVC), які активно використовуються Podʼом, і PersistentVolume (PV), привʼязані до PVC, не вилучаються із системи, оскільки це може призвести до втрати даних.
Примітка:
PVC активно використовується Podʼом, коли існує обʼєкт Pod, який використовує PVC.Якщо користувач видаляє PVC, який активно використовується Podʼом, PVC вилучається не одразу. Вилучення PVC відкладається, доки PVC більше не використовуватиметься активно жодним Podʼом. Так само, якщо адміністратор видаляє PV, привʼязаний до PVC, PV вилучається не одразу. Вилучення PV відкладається, доки PV більше не буде привʼязаний до PVC.
Ви можете побачити, що PVC захищено, коли статус PVC — Terminating, а список Finalizers містить kubernetes.io/pvc-protection:
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
Ви можете побачити, що PV захищено, коли статус PV — Terminating, а список Finalizers також містить kubernetes.io/pv-protection:
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Повторне використання
Коли користувач закінчує роботу зі своїм томом, він може видалити обʼєкти PVC з API, що дозволяє повторно використати ресурс. Політика повторного використання PersistentVolume вказує кластеру, що робити з томом після того, як його звільнено від PVC. Наразі томи можна зберегти (Retain), переробити (Recycle) або видалити (Delete).
Retain
Політика повторного використання Retain дозволяє повторно використати ресурс вручну. Коли PersistentVolumeClaim видаляють, PersistentVolume все ще існує, і том вважається «звільненим». Але він ще не доступний для іншого PVC, оскільки на томі залишаються дані попереднього власника PVC. Адміністратор може вручну повторно використати том, виконавши такі кроки.
- Видаліть PersistentVolume. Повʼязаний ресурс сховища в зовнішній інфраструктурі все ще існує після видалення PV.
- Вручну очистіть дані на повʼязаному ресурсі сховища.
- Вручну видаліть повʼязаний ресурс сховища.
Якщо ви хочете повторно використати той самий ресурс сховища, створіть новий PersistentVolume із таким самим визначенням ресурсу сховища.
Delete
Для втулків томів, які підтримують політику повторного використання Delete, видалення вилучає і обʼєкт PersistentVolume з Kubernetes, і повʼязаний ресурс сховища в зовнішній інфраструктурі. Томи, надані динамічно, успадковують політику повторного використання свого StorageClass, стандартним значенням якої є Delete. Адміністратор має налаштувати StorageClass відповідно до очікувань користувачів; інакше PV потрібно відредагувати або змінити за допомогою patch після створення. Дивіться Зміна політики повторного використання PersistentVolume.
Recycle
Попередження:
Політика повторного використанняRecycle застаріла. Натомість рекомендовано використовувати динамічне надання.Якщо це підтримує базовий втулок томів, політика повторного використання Recycle виконує базове очищення (rm -rf /thevolume/*) тому й знову робить його доступним для нового PVC.
Однак адміністратор може налаштувати власний шаблон Podʼа recycler за допомогою аргументів командного рядка менеджера контролерів Kubernetes, як описано в довіднику. Власний шаблон Podʼа recycler має містити специфікацію volumes, як показано в наведеному нижче прикладі:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "registry.k8s.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
Однак конкретний шлях, вказаний у частині volumes власного шаблону Podʼа recycler, замінюється конкретним шляхом тому, що переробляється.
Завершувач захисту від видалення PersistentVolume
This is a stable feature in Kubernetes, and has been since the 1.33 release. You can no longer toggle this feature (the associated feature gate has been removed).
До PersistentVolume можна додавати завершувачі, щоб PersistentVolumes із політикою повторного використання Delete видалялися лише після видалення базового сховища.
Завершувач external-provisioner.volume.kubernetes.io/finalizer (запроваджений у v1.31) додається як до динамічно, так і до статично наданих томів CSI.
Завершувач kubernetes.io/pv-controller (запроваджений у v1.31) додається до динамічно наданих томів вбудованих втулків і пропускається для статично наданих томів вбудованих втулків.
Ось приклад динамічно наданого тому вбудованого втулка:
kubectl describe pv pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Name: pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Labels: <none>
Annotations: kubernetes.io/createdby: vsphere-volume-dynamic-provisioner
pv.kubernetes.io/bound-by-controller: yes
pv.kubernetes.io/provisioned-by: kubernetes.io/vsphere-volume
Finalizers: [kubernetes.io/pv-protection kubernetes.io/pv-controller]
StorageClass: vcp-sc
Status: Bound
Claim: default/vcp-pvc-1
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity: <none>
Message:
Source:
Type: vSphereVolume (a Persistent Disk resource in vSphere)
VolumePath: [vsanDatastore] d49c4a62-166f-ce12-c464-020077ba5d46/kubernetes-dynamic-pvc-74a498d6-3929-47e8-8c02-078c1ece4d78.vmdk
FSType: ext4
StoragePolicyName: vSAN Default Storage Policy
Events: <none>
Завершувач external-provisioner.volume.kubernetes.io/finalizer додається для томів CSI. Ось приклад:
Name: pvc-2f0bab97-85a8-4552-8044-eb8be45cf48d
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: csi.vsphere.vmware.com
Finalizers: [kubernetes.io/pv-protection external-provisioner.volume.kubernetes.io/finalizer]
StorageClass: fast
Status: Bound
Claim: demo-app/nginx-logs
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 200Mi
Node Affinity: <none>
Message:
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: csi.vsphere.vmware.com
FSType: ext4
VolumeHandle: 44830fa8-79b4-406b-8b58-621ba25353fd
ReadOnly: false
VolumeAttributes: storage.kubernetes.io/csiProvisionerIdentity=1648442357185-8081-csi.vsphere.vmware.com
type=vSphere CNS Block Volume
Events: <none>
Коли для конкретного вбудованого втулка томів увімкнено прапорець можливості CSIMigration{provider}, завершувач kubernetes.io/pv-controller замінюється завершувачем external-provisioner.volume.kubernetes.io/finalizer.
Завершувачі гарантують, що обʼєкт PV вилучається лише після видалення тому з бекенду сховища, якщо політика повторного використання PV — Delete. Це також гарантує, що том буде видалено з бекенду сховища незалежно від порядку видалення PV і PVC.
Резервування PersistentVolume
Панель управління може привʼязувати PersistentVolumeClaims до відповідних PersistentVolumes у кластері. Однак, якщо ви хочете, щоб PVC привʼязався до певного PV, потрібно попередньо їх привʼязати.
Вказавши PersistentVolume у PersistentVolumeClaim, ви оголошуєте привʼязку між цими конкретними PV та PVC. Якщо PersistentVolume існує і не зарезервував PersistentVolumeClaims через своє поле claimRef, PersistentVolume і PersistentVolumeClaim буде привʼязано.
Привʼязка відбувається незалежно від деяких критеріїв зіставлення томів, зокрема спорідненості вузла. Панель управління все ще перевіряє, що клас сховища, режими доступу та запитаний розмір сховища є дійсними.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # Порожній рядок потрібно вказати явно, інакше буде встановлено стандартний StorageClass
volumeName: foo-pv
...
Цей метод не гарантує жодних привілеїв привʼязки для PersistentVolume. Якщо інші PersistentVolumeClaims можуть використовувати вказаний вами PV, спочатку потрібно зарезервувати цей том сховища. Вкажіть відповідний PersistentVolumeClaim у полі claimRef PV, щоб інші PVC не могли до нього привʼязатися.
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
Це корисно, якщо ви хочете використовувати PersistentVolumes, у яких persistentVolumeReclaimPolicy має значення Retain, зокрема у випадках, коли ви повторно використовуєте наявний PV.
Розширення PersistentVolumeClaims
Підтримку розширення PersistentVolumeClaims (PVC) стандартно ввімкнено. Ви можете розширювати такі типи томів:
- csi (зокрема деякі типи томів, перенесені на CSI)
- flexVolume (застаріло)
- portworxVolume (застаріло)
Ви можете розширити PVC, лише якщо поле allowVolumeExpansion його класу сховища має значення true.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-vol-default
provisioner: vendor-name.example/magicstorage
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
Щоб запросити більший том для PVC, відредагуйте обʼєкт PVC і вкажіть більший розмір. Це запускає розширення тому, що стоїть за базовим PersistentVolume. Новий PersistentVolume для задоволення PVC ніколи не створюється. Натомість змінюється розмір наявного тому.
Попередження:
Пряме редагування розміру PersistentVolume може завадити автоматичній зміні розміру цього тому. Якщо ви редагуєте місткість PersistentVolume, а потім редагуєте.spec відповідного PersistentVolumeClaim, щоб розмір PersistentVolumeClaim збігався з PersistentVolume, зміна розміру сховища не відбудеться. Панель управління Kubernetes побачить, що бажаний стан обох ресурсів збігається, і зробить висновок, що розмір базового тому було збільшено вручну й зміна розміру не потрібна.Розширення томів CSI
Підтримку розширення томів CSI стандартно ввімкнено, але вона також вимагає, щоб конкретний драйвер CSI підтримував розширення томів. Докладніше дивіться в документації конкретного драйвера CSI.
Зміна розміру тому, що містить файлову систему
Ви можете змінювати розмір томів, що містять файлову систему, лише якщо це XFS, Ext3 або Ext4.
Коли том містить файлову систему, її розмір змінюється лише тоді, коли новий Pod використовує PersistentVolumeClaim у режимі ReadWrite. Розширення файлової системи виконується або під час запуску Podʼа, або коли Pod працює і базова файлова система підтримує онлайн-розширення.
FlexVolumes (застаріли з Kubernetes v1.23) дозволяють змінювати розмір, якщо драйвер налаштовано з можливістю RequiresFSResize, встановленою в true. Розмір FlexVolume можна змінити під час перезапуску Podʼа.
Зміна розміру PersistentVolumeClaim, що використовується
У цьому випадку вам не потрібно видаляти й повторно створювати Pod або Deployment, який використовує наявний PVC. Будь-який PVC, що використовується, автоматично стає доступним для свого Podʼа, щойно його файлову систему буде розширено. Ця можливість не впливає на PVC, які не використовуються Podʼом або Deployment. Ви повинні створити Pod, який використовує PVC, щоб розширення могло завершитися.
Як і інші типи томів, томи FlexVolume також можна розширювати, коли їх використовує Pod.
Примітка:
Змінити розмір FlexVolume можна лише тоді, коли це підтримує базовий драйвер.Відновлення після збою під час розширення томів
Якщо користувач вказує новий розмір, надто великий для базової системи зберігання, розширення PVC повторюватиметься постійно, доки користувач або адміністратор кластера не вживе заходів. Це може бути небажаним, тому Kubernetes надає такі методи відновлення після таких збоїв.
Якщо розширення базового сховища не вдається, адміністратор кластера може вручну відновити стан PersistentVolumeClaim (PVC) і скасувати запити на зміну розміру. Інакше контролер постійно повторюватиме запити на зміну розміру без втручання адміністратора.
- Позначте PersistentVolume (PV), привʼязаний до PersistentVolumeClaim (PVC), політикою повторного використання
Retain. - Видаліть PVC. Оскільки PV має політику повторного використання
Retain, ми не втратимо жодних даних під час повторного створення PVC. - Видаліть запис
claimRefзі специфікації PV, щоб новий PVC міг до нього привʼязатися. Це має зробити PVAvailable. - Створіть PVC заново з меншим розміром, ніж у PV, і встановіть у поле
volumeNamePVC назву PV. Це має привʼязати новий PVC до наявного PV. - Не забудьте відновити політику повторного використання PV.
Якщо розширення PVC не вдалося, ви можете повторити його з меншим розміром, ніж запитане раніше значення. Щоб запросити нову спробу розширення з меншим запропонованим розміром, відредагуйте .spec.resources цього PVC і виберіть значення, менше за попереднє. Це корисно, якщо розширення до більшого значення не вдалося через обмеження місткості. Якщо це сталося або ви підозрюєте, що могло статися, ви можете повторити розширення, вказавши розмір у межах місткості базового провайдера сховища. Ви можете стежити за статусом операції зміни розміру через .status.allocatedResourceStatuses та Events на PVC.
Зверніть увагу, що, хоча ви можете вказати менший обсяг сховища, ніж запитували раніше, нове значення все одно має бути більшим за .status.capacity. Kubernetes не підтримує зменшення PVC до розміру, меншого за поточний.
Типи постійних томів
Типи PersistentVolume реалізовано як втулки. Наразі Kubernetes підтримує такі втулки:
csi— Container Storage Interface (CSI)fc— Сховище Fibre Channel (FC)hostPath— том HostPath (лише для тестування на одному вузлі; НЕ ПРАЦЮВАТИМЕ в кластері з кількома вузлами; натомість розгляньте використання томуlocal)iscsi— Сховище iSCSI (SCSI через IP)local— локальні пристрої зберігання, змонтовані на вузлах.nfs— сховище Network File System (NFS)
Такі типи PersistentVolume застаріли, але все ще доступні. Якщо ви використовуєте ці типи томів, крім flexVolume, cephfs та rbd, встановіть відповідні драйвери CSI.
awsElasticBlockStore— AWS Elastic Block Store (EBS) (міграцію стандартно ввімкнено починаючи з v1.23)azureDisk— Azure Disk (міграцію стандартно ввімкнено починаючи з v1.23)azureFile— Azure File (міграцію стандартно ввімкнено починаючи з v1.24)cinder— Cinder (блочне сховище OpenStack) (міграцію стандартно ввімкнено починаючи з v1.21)flexVolume— FlexVolume (застаріло починаючи з версії v1.23, план міграції відсутній, планів припинення підтримки немає)gcePersistentDisk— GCE Persistent Disk (міграцію стандартно ввімкнено починаючи з v1.23)portworxVolume— Том Portworx (міграцію стандартно ввімкнено починаючи з v1.31)vsphereVolume— том vSphere VMDK (міграцію стандартно ввімкнено починаючи з v1.25)
Старіші версії Kubernetes також підтримували такі типи вбудованих PersistentVolume:
cephfs(недоступно починаючи з версії v1.31)flocker— Flocker storage. (недоступно починаючи з версії v1.25)glusterfs— GlusterFS storage. (недоступно починаючи з версії v1.26)photonPersistentDisk— Photon controller persistent disk. (недоступно починаючи з версії v1.15)quobyte— Том Quobyte. (недоступно починаючи з версії v1.25)rbd— Rados Block Device (RBD) volume (недоступно починаючи з версії v1.31)scaleIO— Том ScaleIO. (недоступно починаючи з версії v1.21)storageos— Том StorageOS. (недоступно починаючи з версії v1.25)
Постійні томи
Кожен PV містить spec і status, тобто специфікацію та статус тому. Назва обʼєкта PersistentVolume має бути дійсним іменем DNS-піддомену.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Примітка:
Для використання PersistentVolume у кластері можуть знадобитися допоміжні програми, повʼязані з типом тому. У цьому прикладі PersistentVolume має тип NFS, і для підтримки монтування файлових систем NFS потрібна допоміжна програма /sbin/mount.nfs.Місткість
Зазвичай PV має певну місткість сховища. Вона задається атрибутом capacity PV, який є значенням Quantity.
Наразі розмір сховища — єдиний ресурс, який можна встановити або запитати. Майбутні атрибути можуть включати IOPS, пропускну здатність тощо.
Режим тому
Kubernetes підтримує два значення volumeModes для PersistentVolumes: Filesystem та Block.
volumeMode є необовʼязковим параметром API. Filesystem — стандартний режим, який використовується, коли параметр volumeMode пропущено.
Том із volumeMode: Filesystem монтується в Podʼи в теку. Якщо том підкріплений блоковим пристроєм і пристрій порожній, Kubernetes створює на ньому файлову систему перед першим монтуванням.
Ви можете встановити volumeMode у Block, щоб використовувати том як необроблений блоковий пристрій. Такий том подається в Pod як блоковий пристрій без файлової системи. Цей режим корисний, щоб надати Podʼу найшвидший можливий доступ до тому без будь-якого шару файлової системи між Podʼом і томом. З іншого боку, застосунок, що працює в Podʼі, має знати, як працювати з необробленим блоковим пристроєм. Приклад використання тому з volumeMode: Block у Podʼі дивіться в розділі Підтримка необроблених блокових томів.
Режими доступу
PersistentVolume можна змонтувати на хості будь-яким способом, який підтримує провайдер ресурсу. Як показано в таблиці нижче, провайдери мають різні можливості, а режими доступу кожного PV встановлюються відповідно до режимів, які підтримує цей конкретний том. Наприклад, NFS може підтримувати кількох клієнтів для читання й запису, але конкретний PV NFS може бути експортований на сервері лише для читання. Кожен PV отримує власний набір режимів доступу, що описує можливості саме цього PV.
Режими доступу такі:
ReadWriteOnce- том можна змонтувати для читання й запису на одному вузлі. Режим доступу ReadWriteOnce все ще може дозволяти кільком Podʼам доступ до цього тому (читання з нього або запис у нього), якщо ці Podʼи працюють на одному вузлі. Про доступ для одного Podʼа дивіться ReadWriteOncePod.
ReadOnlyMany- том можна змонтувати лише для читання на багатьох вузлах.
ReadWriteMany- том можна змонтувати для читання й запису на багатьох вузлах.
ReadWriteOncePod- СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.29том можна змонтувати для читання й запису одним Podʼом. Використовуйте режим доступу ReadWriteOncePod, якщо хочете гарантувати, що лише один Pod у всьому кластері може читати цей PVC або записувати в нього.
Примітка:
Режим доступу ReadWriteOncePod підтримується лише для томів CSI і Kubernetes версії 1.22+. Щоб використовувати цю можливість, вам потрібно оновити такі sidecar-контейнери CSI до цих або новіших версій:
У командному рядку режими доступу скорочуються так:
- RWO — ReadWriteOnce
- ROX — ReadOnlyMany
- RWX — ReadWriteMany
- RWOP — ReadWriteOncePod
Примітка:
Kubernetes використовує режими доступу до томів для зіставлення PersistentVolumeClaims і PersistentVolumes. У деяких випадках режими доступу до томів також обмежують, де можна змонтувати PersistentVolume. Режими доступу до томів не забезпечують захист від запису після монтування сховища. Навіть якщо вказано режими доступу ReadWriteOnce, ReadOnlyMany або ReadWriteMany, вони не встановлюють жодних обмежень на том. Наприклад, навіть якщо PersistentVolume створено як ReadOnlyMany, це не гарантує, що він буде доступний лише для читання. Якщо вказано режим доступу ReadWriteOncePod, том обмежений і може бути змонтований лише одним Podʼом.Важливо! Том можна монтувати одночасно лише в одному режимі доступу, навіть якщо він підтримує кілька.
| Втулок томів | ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod |
|---|---|---|---|---|
| AzureFile | ✓ | ✓ | ✓ | - |
| CephFS | ✓ | ✓ | ✓ | - |
| CSI | залежить від драйвера | залежить від драйвера | залежить від драйвера | залежить від драйвера |
| FC | ✓ | ✓ | - | - |
| FlexVolume | ✓ | ✓ | залежить від драйвера | - |
| HostPath | ✓ | - | - | - |
| iSCSI | ✓ | ✓ | - | - |
| NFS | ✓ | ✓ | ✓ | - |
| RBD | ✓ | ✓ | - | - |
| VsphereVolume | ✓ | - | - (працює, коли Podʼи розташовані разом) | - |
| PortworxVolume | ✓ | - | ✓ | - |
Клас
PV може мати клас, який задається встановленням атрибута storageClassName на назву StorageClass. PV певного класу можна привʼязати лише до PVC, які запитують цей клас. PV без storageClassName не має класу, і його можна привʼязати лише до PVC, які не запитують жодного конкретного класу.
У минулому замість атрибута storageClassName використовувалася анотація volume.beta.kubernetes.io/storage-class. Ця анотація все ще працює; однак у майбутньому випуску Kubernetes вона стане повністю застарілою.
Політика повторного використання
Поточні політики повторного використання:
- Retain — ручне повторне використання
- Recycle — базове очищення (
rm -rf /thevolume/*) - Delete — видалити том
У Kubernetes 1.37 переробку підтримують лише типи томів nfs та hostPath.
Параметри монтування
Адміністратор Kubernetes може вказати додаткові параметри монтування для випадку, коли постійний том монтується на вузлі.
Примітка:
Не всі типи постійних томів підтримують параметри монтування.Такі типи томів підтримують параметри монтування:
csi(зокрема типи томів, перенесені на CSI)iscsinfs
Параметри монтування не перевіряються. Якщо параметр монтування недійсний, монтування завершиться невдачею.
У минулому замість атрибута mountOptions використовувалася анотація volume.beta.kubernetes.io/mount-options. Ця анотація все ще працює; однак у майбутньому випуску Kubernetes вона стане повністю застарілою.
Спорідненість вузла
Примітка:
Для більшості типів томів вам не потрібно встановлювати це поле. Вам слід явно встановити його для томів local.PV може вказувати спорідненість вузла, щоб визначити обмеження, з яких вузлів можна отримати доступ до цього тому. Podʼи, які використовують PV, плануватимуться лише на вузли, вибрані спорідненістю вузла. Щоб вказати спорідненість вузла, встановіть nodeAffinity у .spec PV. Докладніше про це поле дивіться в довіднику API PersistentVolume.
Оновлення спорідненості вузла
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the MutablePVNodeAffinity feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Якщо у вашому кластері ввімкнено функціональну можливість MutablePVNodeAffinity, поле .spec.nodeAffinity PersistentVolume можна змінювати. Це дозволяє адміністраторам кластера або зовнішньому контролеру сховища оновлювати спорідненість вузла PersistentVolume під час міграції даних, не перериваючи роботу запущених Podʼів.
Під час оновлення спорідненості вузла переконайтеся, що нова спорідненість вузла все ще відповідає вузлам, на яких том наразі використовується. Podʼи, що порушують нову спорідненість, якщо вони вже працюють, можуть продовжувати працювати. Але Kubernetes не підтримує таку конфігурацію. Слід якнайшвидше завершити Podʼи, що її порушують. Через кешування в памʼяті Podʼи, створені після оновлення, протягом короткого часу все ще можуть плануватися за старою спорідненістю вузла.
Щоб скористатися цією можливістю, увімкніть функціональну можливість MutablePVNodeAffinity у таких компонентах:
kube-apiserverkubelet
Фаза
PersistentVolume перебуватиме в одній із таких фаз:
Available- вільний ресурс, ще не привʼязаний до PVC
Bound- том привʼязано до PVC
Released- PVC видалено, але кластер ще не повторно використав повʼязаний ресурс сховища
Failed- автоматичне повторне використання тому завершилося збоєм
Ви можете побачити назву PVC, привʼязаного до PV, за допомогою kubectl describe persistentvolume <name>.
Час переходу фази
This is a stable feature in Kubernetes, and has been since the 1.31 release. You can no longer toggle this feature (the associated feature gate has been removed).
Поле .status PersistentVolume може містити альфа-поле lastPhaseTransitionTime. Це поле фіксує час останнього переходу тому між фазами. Для новостворених томів фаза встановлюється в Pending, а lastPhaseTransitionTime — на поточний час.
PersistentVolumeClaims
Кожен PVC містить spec і status, тобто специфікацію та статус PVC. Назва обʼєкта PersistentVolumeClaim має бути дійсним іменем DNS-піддомену.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Режими доступу
PVC використовують ті самі домовленості, що й томи, запитуючи сховище з певними режимами доступу.
Режими томів
PVC використовують ту саму домовленість, що й томи, щоб вказати споживання тому як файлової системи або блокового пристрою.
Назва тому
PVC можуть використовувати поле volumeName, щоб явно привʼязатися до певного PersistentVolume. Ви також можете залишити volumeName невстановленим, вказавши, що хочете, щоб Kubernetes налаштував новий PersistentVolume, який відповідає PVC. Якщо вказаний PV уже привʼязаний до іншого PVC, привʼязка застрягне в стані очікування.
Ресурси
PVC, як і Podʼи, можуть запитувати певні кількості ресурсу. У цьому випадку запит стосується сховища. До томів і PVC застосовується та сама модель ресурсів.
Примітка:
Для томівFilesystem запит сховища стосується «зовнішнього» розміру тому (тобто розміру, виділеного бекендом сховища). Це означає, що розмір, доступний для запису, може бути дещо меншим у провайдерів, які будують файлову систему поверх блокового пристрою, через накладні витрати файлової системи. Це особливо помітно з XFS, де стандартно ввімкнено багато можливостей метаданих.Селектор
PVC можуть вказати селектор міток, щоб додатково відфільтрувати набір томів. До PVC можна привʼязати лише томи, мітки яких відповідають селектору. Селектор може складатися з двох полів:
matchLabels— том повинен мати мітку з таким значеннямmatchExpressions— список вимог, які визначаються за допомогою ключа, списку значень та оператора, який повʼязує ключ і значення. Допустимі оператори включаютьIn,NotIn,ExistsтаDoesNotExist.
Усі вимоги з matchLabels і matchExpressions обʼєднуються логічним «І» — для збігу всі вони мають бути виконані.
Клас
PVC може запитати певний клас, вказавши назву StorageClass в атрибуті storageClassName. До PVC можна привʼязати лише PV запитаного класу, тобто ті, що мають такий самий storageClassName, як і PVC.
PVC не обовʼязково мають запитувати клас. PVC зі storageClassName, встановленим у "", завжди інтерпретується як такий, що запитує PV без класу, тому його можна привʼязати лише до PV без класу (без анотації або з анотацією, встановленою в ""). PVC без storageClassName — це не зовсім те саме, і кластер обробляє його по-різному залежно від того, чи ввімкнено втулок допуску DefaultStorageClass.
- Якщо втулок допуску ввімкнено, адміністратор може вказати стандартний StorageClass. Усі PVC без
storageClassNameможна привʼязати лише до PV цього стандартного класу. Стандартний StorageClass задається встановленням анотаціїstorageclass.kubernetes.io/is-default-classуtrueв обʼєкті StorageClass. Якщо адміністратор не вказав стандартний клас, кластер реагує на створення PVC так, ніби втулок допуску вимкнено. Якщо вказано кілька стандартних StorageClass, під час динамічного надання PVC використовується найновіший. - Якщо втулок допуску вимкнено, поняття стандартного StorageClass немає. Усі PVC зі
storageClassName, встановленим у"", можна привʼязати лише до PV, у якихstorageClassNameтакож встановлено в"". Однак PVC безstorageClassNameможна оновити пізніше, коли стандартний StorageClass стане доступним. Якщо PVC оновлено, він більше не привʼязуватиметься до PV, у якихstorageClassNameтакож встановлено в"".
Докладніше дивіться в розділі ретроактивне призначення стандартного StorageClass.
Залежно від способу встановлення, менеджер надбудов може розгорнути стандартний StorageClass у кластері Kubernetes під час встановлення.
Коли PVC вказує selector на додаток до запиту StorageClass, вимоги обʼєднуються логічним «І»: до PVC можна привʼязати лише PV запитаного класу із запитаними мітками.
Примітка:
Наразі для PVC з непорожнімselector не можна динамічно надати PV.У минулому замість атрибута storageClassName використовувалася анотація volume.beta.kubernetes.io/storage-class. Ця анотація все ще працює; однак у майбутньому випуску Kubernetes вона більше не підтримуватиметься.
Ретроактивне призначення стандартного StorageClass
Ви можете створити PersistentVolumeClaim, не вказуючи storageClassName для нового PVC, навіть якщо у вашому кластері немає стандартного StorageClass. У цьому випадку новий PVC створюється так, як ви його визначили, а storageClassName цього PVC залишається невстановленим, доки не стане доступним стандартний клас.
Коли стандартний StorageClass стає доступним, панель управління визначає всі наявні PVC без storageClassName. Для PVC, які мають порожнє значення storageClassName або не мають цього ключа, панель управління оновлює storageClassName відповідно до нового стандартного StorageClass. Якщо у вас є наявний PVC, де storageClassName має значення "", і ви налаштовуєте стандартний StorageClass, цей PVC не буде оновлено.
Щоб і надалі привʼязуватися до PV із storageClassName, встановленим у "" (за наявності стандартного StorageClass), вам потрібно встановити storageClassName повʼязаного PVC у "".
Така поведінка допомагає адміністраторам змінювати стандартний StorageClass: спочатку вилучити старий, а потім створити або встановити інший. Через це коротке вікно без стандартного класу PVC без storageClassName, створені в цей час, не матимуть стандартного класу, але завдяки ретроактивному призначенню стандартного StorageClass такий спосіб зміни стандартних значень безпечний.
Відстеження невикористаних PVC
Коли цю можливість увімкнено, контролер захисту PVC додає до кожного PersistentVolumeClaim стан Unused, щоб показати, чи посилається на нього зараз якийсь нетермінальний Pod.
Цей стан має два значення:
Unusedзі статусом"True"(причинаNoPodsUsingPVC)- Жоден нетермінальний Pod не посилається на цей PVC.
lastTransitionTimeфіксує час, коли PVC перестав використовуватися. Unusedзі статусом"False"(причинаPodUsingPVC)- Принаймні один нетермінальний Pod наразі посилається на цей PVC.
lastTransitionTimeфіксує час, коли PVC почав використовуватися.
Pod вважається нетермінальним, якщо його фаза не Succeeded і не Failed. Це означає, що Pod в очікуванні (навіть ще не запланований) вважається таким, що використовує PVC.
lastTransitionTime стану Unused можуть використовувати адміністратори кластера, інструменти моніторингу та зовнішні контролери, щоб визначати PVC, які не використовуються тривалий час. Наприклад, щоб знайти всі PVC, які не використовуються понад 30 днів, можна вибрати PVC, у яких стан Unused має status: "True", а lastTransitionTime старший за 30 днів.
Примітка:
Тривалість невикористання, показана цим станом, може бути коротшою за фактичний час невикористання через затримки обробки в контролері або через те, що можливість було ввімкнено, коли PVC уже не використовувався. Стан не оновлюється, коли в PVC встановленоdeletionTimestamp (тобто для PVC, що видаляються).PVC як томи
Podʼи отримують доступ до сховища, використовуючи PVC як том. PVC має існувати в тому самому просторі імен, що й Pod, який його використовує. Кластер знаходить PVC у просторі імен Podʼа і використовує його, щоб отримати PersistentVolume, що стоїть за PVC. Потім том монтується на хост і в Pod.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Примітка щодо просторів імен
Привʼязки PersistentVolumes є ексклюзивними, а оскільки PersistentVolumeClaims є обʼєктами в просторі імен, монтування PVC у режимах "Many" (ROX, RWX) можливе лише в межах одного простору імен.
PersistentVolumes типу hostPath
PersistentVolume типу hostPath використовує файл або теку на вузлі для емуляції мережевого сховища. Дивіться приклад тому типу hostPath.
Підтримка необроблених блокових томів
Такі втулки томів підтримують необроблені блокові томи, зокрема динамічне надання, де це застосовно:
- CSI (зокрема деякі типи томів, перенесені на CSI)
- FC (Fibre Channel)
- iSCSI
- Локальний том
PersistentVolume, що використовує необроблений блоковий том
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
PersistentVolumeClaim, який запитує необроблений блоковий том
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
Специфікація Podʼа з додаванням шляху необробленого блокового пристрою в контейнері
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
Примітка:
Під час додавання необробленого блокового пристрою для Podʼа ви вказуєте шлях до пристрою в контейнері замість шляху монтування.Привʼязка блокових томів
Якщо користувач запитує необроблений блоковий том, вказавши це в полі volumeMode у специфікації PersistentVolumeClaim, правила привʼязки дещо відрізняються від попередніх випусків, які не враховували цей режим як частину специфікації. Нижче наведено таблицю можливих комбінацій, які користувач і адміністратор можуть вказати для запиту необробленого блокового пристрою. Таблиця показує, чи буде том привʼязано за цих комбінацій: Матриця привʼязки томів для статично наданих томів:
| PV volumeMode | PVC volumeMode | Результат |
|---|---|---|
| не вказано | не вказано | ПРИВʼЯЗАНИЙ |
| не вказано | Block | НЕ ПРИВʼЯЗАНИЙ |
| не вказано | Filesystem | ПРИВʼЯЗАНИЙ |
| Block | не вказано | НЕ ПРИВʼЯЗАНИЙ |
| Block | Block | ПРИВʼЯЗАНИЙ |
| Block | Filesystem | НЕ ПРИВʼЯЗАНИЙ |
| Filesystem | Filesystem | ПРИВʼЯЗАНИЙ |
| Filesystem | Block | НЕ ПРИВʼЯЗАНИЙ |
| Filesystem | не вказано | ПРИВʼЯЗАНИЙ |
Примітка:
Для альфа-випуску підтримуються лише статично надані томи. Адміністратори мають враховувати ці значення під час роботи з необробленими блоковими пристроями.Підтримка знімків томів та відновлення тому зі знімка
Знімки томів підтримують лише зовнішні втулки томів CSI. Докладніше дивіться в Знімки томів. Вбудовані втулки томів застаріли. Про застарілі втулки томів читайте в FAQ про втулки томів.
Створення PersistentVolumeClaim зі знімка тому
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Клонування томів
Клонування томів доступне лише для втулків томів CSI.
Створення PersistentVolumeClaim з наявного PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Наповнювачі томів та джерела даних
Клонування томів та відновлення зі знімка попередньо заповнюють новий том із вбудованого джерела даних. Наповнювачі томів розширюють цей механізм, щоб PersistentVolumeClaim можна було попередньо заповнити з інших видів джерел (власного ресурсу), на які він посилається через поле dataSourceRef:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: populated-pvc
spec:
dataSourceRef:
name: example-name
kind: ExampleDataSource
apiGroup: example.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Докладніше, зокрема про джерела даних між просторами імен, дивіться в Наповнювачі томів та джерела даних.
Створення переносної конфігурації
Якщо ви пишете шаблони конфігурації або приклади, які працюють на широкому спектрі кластерів і потребують постійного сховища, рекомендується використовувати такий підхід:
- Додавайте обʼєкти PersistentVolumeClaim до свого набору конфігурації (поряд із Deployments, ConfigMaps тощо).
- Не додавайте обʼєкти PersistentVolume до конфігурації, оскільки користувач, який застосовує конфігурацію, може не мати дозволу на створення PersistentVolumes.
- Дайте користувачеві можливість вказати назву класу сховища під час застосування шаблону.
- Якщо користувач вказує назву класу сховища, запишіть це значення в поле
persistentVolumeClaim.storageClassName. Це приведе до зіставлення PVC з правильним класом сховища, якщо адміністратор увімкнув StorageClasses у кластері. - Якщо користувач не вказує назву класу сховища, залиште поле
persistentVolumeClaim.storageClassNameзі значенням nil. Це призведе до автоматичного надання PV для користувача зі стандартним StorageClass кластера. Багато кластерних середовищ мають встановлений стандартний StorageClass, або адміністратори можуть створити власний стандартний StorageClass.
- Якщо користувач вказує назву класу сховища, запишіть це значення в поле
- У своїх інструментах стежте за PVC, які не привʼязуються протягом певного часу, і показуйте це користувачеві, оскільки це може означати, що кластер не має підтримки динамічного сховища (у цьому випадку користувач має створити відповідний PV) або не має системи зберігання (у цьому випадку користувач не може розгорнути конфігурацію, яка потребує PVC).
Що далі
- Дізнайтеся більше про створення PersistentVolume.
- Дізнайтеся більше про створення PersistentVolumeClaim.
- Прочитайте проєктний документ Persistent Storage.
Довідники API
Дізнайтеся більше про описані на цій сторінці API:
3 - Проєкційні томи
У цьому документі описано проєкційні томи в Kubernetes. Рекомендується ознайомитися з томами.
Вступ
Том projected зіставляє кілька наявних джерел томів з однією текою.
Наразі можна проєцювати такі типи джерел томів:
Усі джерела мають бути в тому самому просторі імен, що й Pod. Докладніше дивіться в проєктному документі all-in-one volume.
Приклад конфігурації із secret, downwardAPI та configMap
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
Приклад конфігурації: secrets із нестандартним режимом дозволів
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 0777
Кожне джерело проєкційного тому перелічено в специфікації в розділі sources. Параметри майже такі самі, за двома винятками:
- Для secrets поле
secretNameзмінено наname, щоб узгодити його з іменуванням ConfigMap. defaultModeможна вказати лише на рівні projected, а не для кожного джерела тому. Однак, як показано вище, ви можете явно встановитиmodeдля кожної окремої проєкції.
Проєкційні томи serviceAccountToken
Ви можете вставити токен поточного ServiceAccount у Pod за вказаним шляхом. Наприклад:
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
Pod із прикладу має проєкційний том, що містить вставлений токен ServiceAccount. Контейнери в цьому Podʼі можуть використовувати цей токен для доступу до API-сервера Kubernetes, автентифікуючись від імені ServiceAccount цього Podʼа. Поле audience містить цільову аудиторію токена. Отримувач токена повинен ідентифікувати себе ідентифікатором, вказаним в аудиторії токена, інакше він має відхилити токен. Це поле є необовʼязковим, і його стандартним значенням є ідентифікатор API-сервера.
Поле expirationSeconds містить очікуваний термін дії токена ServiceAccount. Стандартно він становить 1 годину і має бути не меншим за 10 хвилин (600 секунд). Адміністратор також може обмежити його максимальне значення, вказавши параметр --service-account-max-token-expiration для API-сервера. Поле path задає шлях відносно точки монтування проєкційного тому.
Примітка:
Контейнер, що використовує джерело проєкційного тому як монтування томуsubPath, не отримуватиме оновлень для цих джерел томів.Проєкційні томи clusterTrustBundle
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.37. It was first available in the v1.29 release.
Джерело проєкційного тому clusterTrustBundle вставляє вміст одного або кількох обʼєктів ClusterTrustBundle як файл, що автоматично оновлюється, у файлову систему контейнера.
ClusterTrustBundles можна вибрати за назвою або за назвою підписувача.
Щоб вибрати за назвою, використовуйте поле name, щоб вказати один обʼєкт ClusterTrustBundle.
Щоб вибрати за назвою підписувача, використовуйте поле signerName (і, за потреби, поле labelSelector), щоб вказати набір обʼєктів ClusterTrustBundle, які використовують задану назву підписувача. Якщо labelSelector відсутній, вибираються всі ClusterTrustBundles цього підписувача.
kubelet вилучає дублікати сертифікатів у вибраних обʼєктах ClusterTrustBundle, нормалізує подання PEM (відкидаючи коментарі та заголовки), змінює порядок сертифікатів і записує їх у файл, вказаний у path. Коли змінюється набір вибраних ClusterTrustBundles або їхній вміст, kubelet підтримує файл в актуальному стані.
Стандартно kubelet не дає Podʼу запуститися, якщо вказаний ClusterTrustBundle не знайдено або якщо signerName / labelSelector не відповідають жодному ClusterTrustBundle. Якщо така поведінка вам не підходить, встановіть поле optional у true, і Pod запуститься з порожнім файлом за шляхом path.
apiVersion: v1
kind: Pod
metadata:
name: sa-ctb-name-test
spec:
containers:
- name: container-test
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: token-vol
mountPath: "/root-certificates"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- clusterTrustBundle:
name: example
path: example-roots.pem
- clusterTrustBundle:
signerName: "example.com/mysigner"
labelSelector:
matchLabels:
version: live
path: mysigner-roots.pem
optional: true
Проєкційні томи podCertificate
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.37. It was first available in the v1.34 release.
Джерело проєкційного тому podCertificate безпечно надає приватний ключ і ланцюжок сертифікатів X.509, які Pod використовує як клієнтські або серверні облікові дані. Потім kubelet оновлює приватний ключ і ланцюжок сертифікатів, коли наближається завершення їхнього терміну дії. Застосунку потрібно лише своєчасно перезавантажувати файл, коли він змінюється, за допомогою механізму на кшталт inotify або опитування.
Кожна проєкція podCertificate підтримує такі конфігураційні поля:
signerName: підписувач, який має видати сертифікат. Зверніть увагу, що підписувачі можуть мати власні вимоги до доступу та можуть відмовитися видавати сертифікати вашому Podʼу.keyType: Тип приватного ключа, який повинен бути згенерований. Дійсні значення:ED25519,ECDSAP256,ECDSAP384,ECDSAP521,RSA3072іRSA4096.maxExpirationSeconds: Максимальний термін дії сертифіката, виданого Podʼу, який ви приймете. Якщо не вказано, стандартно використовується86400(24 години). Має бути не менше3600(1 година) і не більше7862400(91 день). Вбудовані підписувачі Kubernetes обмежені максимальним терміном дії86400(1 день). Підписувач може видати сертифікат із терміном дії, коротшим за вказаний вами.credentialBundlePath: Відносний шлях у межах проєкції, куди слід записати пакет облікових даних. Пакет облікових даних — це файл у форматі PEM, де перший блок — це блок "PRIVATE KEY", що містить приватний ключ, серіалізований у PKCS#8, а решта блоків — це блоки "CERTIFICATE", які утворюють ланцюжок сертифікатів (кінцевий сертифікат і всі проміжні).keyPathіcertificateChainPath: Окремі шляхи, куди kubelet має записати лише приватний ключ або ланцюжок сертифікатів.userAnnotations: мапа, яка дозволяє передавати додаткову інформацію до реалізації підписувача. Вона дослівно копіюється в полеspec.unverifiedUserAnnotationsобʼєктів PodCertificateRequest, які створює kubelet. Записи проходять ту саму перевірку, що й анотації метаданих обʼєкта, але додатково всі ключі повинні мати доменний префікс. На значення не накладаються жодні обмеження, крім загального обмеження розміру всього поля. Окрім цих базових перевірок, API-сервер не виконує жодних додаткових. Реалізації підписувача мають бути дуже обережними під час використання цих даних. Підписувачі не повинні довіряти цим даним без попереднього виконання відповідних кроків перевірки. Підписувачі мають документувати ключі та значення, які вони підтримують. Підписувачі мають відхиляти запити з ключами, які вони не розпізнають.
Примітка:
Більшість застосунків мають віддавати перевагуcredentialBundlePath, якщо їм не потрібні ключ і сертифікати в окремих файлах з міркувань сумісності. kubelet використовує стратегію атомарного запису на основі символічних посилань, щоб під час відкриття файлів, які він проєцює, ви читали або старий, або новий вміст. Однак якщо ви читаєте ключ і ланцюжок сертифікатів з окремих файлів, kubelet може змінити облікові дані після першого читання й до другого, і ваш застосунок завантажить ключ і сертифікат, що не збігаються.# Sample Pod spec that uses a podCertificate projection to request an ED25519
# private key, a certificate from the `coolcert.example.com/foo` signer, and
# write the results to `/var/run/my-x509-credentials/credentialbundle.pem`.
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: podcertificate-pod
spec:
serviceAccountName: default
containers:
- image: debian
name: main
command: ["sleep", "infinity"]
volumeMounts:
- name: my-x509-credentials
mountPath: /var/run/my-x509-credentials
volumes:
- name: my-x509-credentials
projected:
defaultMode: 0644
sources:
- podCertificate:
keyType: ED25519
signerName: coolcert.example.com/foo
credentialBundlePath: credentialbundle.pem
userAnnotations:
example.com/annotation1: "value1"
example.com/annotation2: "value2"
Взаємодія із SecurityContext
Пропозиція щодо обробки дозволів файлів у вдосконаленні проєкційних томів ServiceAccount запровадила встановлення правильних дозволів власника для спроєцьованих файлів.
Linux
У Podʼах Linux, які мають проєкційний том і RunAsUser, встановлений у Pod SecurityContext, спроєцьовані файли мають правильно встановленого власника, зокрема власника-користувача контейнера.
Коли всі контейнери в Podʼі мають однакове значення runAsUser у своєму PodSecurityContext або SecurityContext контейнера, kubelet гарантує, що вміст тому serviceAccountToken належить цьому користувачеві, а файл токена має режим дозволів 0600.
Примітка:
Ефемерні контейнери, додані до Podʼа після його створення, не змінюють дозволи томів, встановлені під час створення Podʼа.
Якщо дозволи тому serviceAccountToken Podʼа було встановлено на 0600, оскільки всі інші контейнери в Podʼі мають однакове значення runAsUser, ефемерні контейнери повинні використовувати той самий runAsUser, щоб мати змогу прочитати токен.
Windows
У Podʼах Windows, які мають проєкційний том і RunAsUsername, встановлений у Pod SecurityContext, власність не застосовується через те, як у Windows керуються облікові записи користувачів. Windows зберігає локальні облікові записи користувачів і груп у файлі бази даних Security Account Manager (SAM) і керує ними. Кожен контейнер має власний екземпляр бази даних SAM, який хост не бачить під час роботи контейнера. Контейнери Windows призначені для запуску частини ОС у режимі користувача ізольовано від хоста, тому вони підтримують віртуальну базу даних SAM. Як наслідок, kubelet, що працює на хості, не може динамічно налаштовувати власність файлів хоста для віртуалізованих облікових записів контейнерів. Якщо файли на хост-машині потрібно спільно використовувати з контейнером, рекомендується розмістити їх у власному монтуванні тому поза C:\.
Стандартно спроєцьовані файли матимуть такого власника, як показано для прикладу файлу проєкційного тому:
PS C:\> Get-Acl C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt | Format-List
Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)
Це означає, що всі користувачі-адміністратори, такі як ContainerAdministrator, матимуть доступ на читання, запис і виконання, а користувачі, які не є адміністраторами, — на читання й виконання.
Примітка:
Загалом не рекомендується надавати контейнеру доступ до хоста, оскільки це може відкрити двері для потенційних експлойтів безпеки.
Створення Podʼа Windows із RunAsUser у його SecurityContext призведе до того, що Pod назавжди застрягне на ContainerCreating. Тому не рекомендується використовувати параметр RunAsUser, призначений лише для Linux, з Podʼами Windows.
4 - Ефемерні томи
У цьому документі описано ефемерні томи в Kubernetes. Рекомендується ознайомитися з томами, зокрема з PersistentVolumeClaim та PersistentVolume.
Деяким застосункам потрібне додаткове сховище, але їм не важливо, чи зберігаються ці дані постійно між перезапусками. Наприклад, сервіси кешування часто обмежені обсягом памʼяті й можуть переміщувати рідко використовувані дані в сховище, повільніше за памʼять, майже не впливаючи на загальну продуктивність.
Інші застосунки очікують, що у файлах будуть певні вхідні дані лише для читання, наприклад, конфігураційні дані або секретні ключі.
Ефемерні томи призначені для таких сценаріїв використання. Оскільки томи живуть стільки ж, скільки Pod, і створюються та видаляються разом із ним, Podʼи можна зупиняти й перезапускати, не обмежуючись місцем, де доступний певний постійний том.
Ефемерні томи вказуються inline у специфікації Podʼа, що спрощує розгортання застосунків і керування ними.
Типи ефемерних томів
Kubernetes підтримує кілька різновидів ефемерних томів для різних цілей:
- emptyDir: порожній під час запуску Podʼа, сховище надається локально з базової теки kubelet (зазвичай кореневий диск) або з оперативної памʼяті
- configMap, downwardAPI, secret: вставляють різні види даних Kubernetes у Pod
- image: дозволяє монтувати файли образів контейнерів або артефакти безпосередньо в Pod.
- ефемерні томи CSI: схожі на попередні види томів, але надаються спеціальними драйверами CSI, які спеціально підтримують цю можливість
- загальні ефемерні томи, які можуть надавати всі драйвери сховища, що також підтримують постійні томи
emptyDir, configMap, downwardAPI, secret надаються як локальне тимчасове сховище. Ними керує kubelet на кожному вузлі.
Ефемерні томи CSI повинні надаватися сторонніми драйверами сховища CSI.
Загальні ефемерні томи можуть надаватися сторонніми драйверами сховища CSI, а також будь-яким іншим драйвером сховища, який підтримує динамічне надання. Деякі драйвери CSI написані спеціально для ефемерних томів CSI і не підтримують динамічне надання: їх не можна використовувати для загальних ефемерних томів.
Перевага сторонніх драйверів полягає в тому, що вони можуть пропонувати функціональність, яку сам Kubernetes не підтримує, наприклад, сховище з іншими характеристиками продуктивності, ніж диск, яким керує kubelet, або вставлення інших даних.
Ефемерні томи CSI
Примітка:
Ефемерні томи CSI підтримує лише частина драйверів CSI. Список драйверів Kubernetes CSI показує, які драйвери підтримують ефемерні томи.Концептуально ефемерні томи CSI схожі на типи томів configMap, downwardAPI та secret: сховище керується локально на кожному вузлі й створюється разом з іншими локальними ресурсами після того, як Pod заплановано на вузол. На цьому етапі Kubernetes уже не має поняття про перепланування Podʼів. Створення тому має бути таким, щоб збій був малоймовірним, інакше запуск Podʼа застрягне. Зокрема, планування Podʼів з урахуванням місткості сховища для цих томів не підтримується. Наразі на них також не поширюються обмеження використання ресурсів сховища Podʼа, оскільки kubelet може застосовувати їх лише до сховища, яким керує сам.
Ось приклад маніфесту для Podʼа, який використовує ефемерне сховище CSI:
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: [ "sleep", "1000000" ]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
volumeAttributes визначають, який том готує драйвер. Ці атрибути специфічні для кожного драйвера й не стандартизовані. Додаткові інструкції дивіться в документації кожного драйвера CSI.
Обмеження драйверів CSI
Ефемерні томи CSI дозволяють користувачам передавати volumeAttributes безпосередньо драйверу CSI як частину специфікації Podʼа. Драйвер CSI, який дозволяє volumeAttributes, що зазвичай доступні лише адміністраторам, НЕ підходить для використання в inline-ефемерному томі. Наприклад, параметри, які зазвичай визначаються в StorageClass, не слід відкривати користувачам через inline-ефемерні томи.
Адміністратори кластера, яким потрібно обмежити драйвери CSI, дозволені для використання як inline-томи у специфікації Podʼа, можуть зробити це так:
- Вилучити
EphemeralізvolumeLifecycleModesу специфікації CSIDriver, що не дасть використовувати драйвер як inline-ефемерний том. - Використати вебхук допуску, щоб обмежити використання цього драйвера.
Загальні ефемерні томи
Загальні ефемерні томи схожі на томи emptyDir у тому сенсі, що надають кожному Podʼу теку для робочих даних, яка зазвичай порожня після надання. Але вони також можуть мати додаткові можливості:
- Сховище може бути локальним або мережевим.
- Томи можуть мати фіксований розмір, який Podʼи не можуть перевищити.
- Томи можуть мати певні початкові дані, залежно від драйвера та параметрів.
- Підтримуються звичайні операції з томами, якщо їх підтримує драйвер, зокрема створення знімків, клонування, зміна розміру та відстеження місткості сховища.
Приклад:
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
command: [ "sleep", "1000000" ]
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
Життєвий цикл та PersistentVolumeClaim
Ключова ідея дизайну полягає в тому, що параметри для PersistentVolumeClaim дозволені всередині джерела тому Podʼа. Підтримуються мітки, анотації та весь набір полів PersistentVolumeClaim. Коли такий Pod створюється, контролер ефемерних томів створює фактичний обʼєкт PersistentVolumeClaim у тому самому просторі імен, що й Pod, і забезпечує видалення PersistentVolumeClaim під час видалення Podʼа.
Це запускає привʼязку та/або надання тому: або негайно, якщо StorageClass використовує негайну привʼязку томів, або коли Pod попередньо заплановано на вузол (режим привʼязки томів WaitForFirstConsumer). Другий варіант рекомендовано для загальних ефемерних томів, оскільки тоді планувальник може вільно вибрати придатний вузол для Podʼа. За негайної привʼязки планувальник змушений вибрати вузол, який має доступ до тому, щойно том стає доступним.
З погляду власності на ресурси Pod, який має загальне ефемерне сховище, є власником PersistentVolumeClaim(ів), що надають це ефемерне сховище. Коли Pod видаляють, збирач сміття Kubernetes видаляє PVC, що зазвичай спричиняє видалення тому, оскільки стандартна політика повторного використання класів сховища — видаляти томи. Ви можете створити квазіефемерне локальне сховище за допомогою StorageClass із політикою повторного використання retain: сховище переживає Pod, і в цьому випадку потрібно подбати про окреме очищення тому.
Поки ці PVC існують, їх можна використовувати, як будь-який інший PVC. Зокрема, на них можна посилатися як на джерело даних під час клонування томів або створення знімків. Обʼєкт PVC також містить поточний статус тому.
Іменування PersistentVolumeClaim
Назви автоматично створених PVC є детермінованими: назва є комбінацією назви Podʼа та назви тому з дефісом (-) посередині. У наведеному вище прикладі назва PVC буде my-app-scratch-volume. Таке детерміноване іменування полегшує взаємодію з PVC, оскільки його не потрібно шукати, якщо відомі назва Podʼа та назва тому.
Детерміноване іменування також створює потенційний конфлікт між різними Podʼами (Pod "pod-a" з томом "scratch" та інший Pod з назвою "pod" і томом "a-scratch" отримають однакову назву PVC "pod-a-scratch"), а також між Podʼами та PVC, створеними вручну.
Такі конфлікти виявляються: PVC використовується для ефемерного тому, лише якщо його створено для цього Podʼа. Ця перевірка базується на відносинах власності. Наявний PVC не перезаписується і не змінюється. Але це не розвʼязує конфлікт, оскільки без правильного PVC Pod не може запуститися.
Увага:
Будьте обережні, називаючи Podʼи й томи в тому самому просторі імен, щоб таких конфліктів не виникало.Безпека
Використання загальних ефемерних томів дозволяє користувачам створювати PVC опосередковано, якщо вони можуть створювати Podʼи, навіть якщо в них немає дозволу створювати PVC безпосередньо. Адміністратори кластера мають про це знати. Якщо це не відповідає їхній моделі безпеки, вони повинні використовувати вебхук допуску, який відхиляє обʼєкти, такі як Podʼи, що мають загальний ефемерний том.
Звичайна квота простору імен для PVC однаково застосовується, тому навіть якщо користувачам дозволено використовувати цей новий механізм, вони не можуть обходити з його допомогою інші політики.
Що далі
Ефемерні томи, керовані kubelet
Дивіться локальне тимчасове сховище.
Ефемерні томи CSI
- Докладніше про дизайн читайте в Ephemeral Inline CSI volumes KEP.
- Докладніше про подальший розвиток цієї можливості читайте в issue для відстеження вдосконалення #596.
Загальні ефемерні томи
- Докладніше про дизайн читайте в Generic ephemeral inline volumes KEP.
5 - Класи атрибутів томів
More information about this feature
This is a stable feature in Kubernetes, and has been since version v1.36. It was first available in the v1.29 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate VolumeAttributesClass, Kubernetes ignores it but does not report any error.
На цій сторінці передбачається, що ви знайомі зі StorageClasses, томами та PersistentVolumes у Kubernetes.
VolumeAttributesClass надає адміністраторам можливість описати змінні «класи» сховища, які вони пропонують. Різні класи можуть відповідати різним рівням якості обслуговування. Сам Kubernetes не має власної думки щодо того, що представляють ці класи.
Ця можливість загальнодоступна (GA) з версії 1.34, і користувачі можуть вимкнути її.
Крім того, VolumeAttributesClasses можна використовувати лише зі сховищем на основі Container Storage Interface і лише там, де відповідний драйвер CSI реалізує API ModifyVolume.
API VolumeAttributesClass
Кожен VolumeAttributesClass містить driverName та parameters, які використовуються, коли PersistentVolume (PV), що належить до цього класу, потрібно динамічно надати або змінити.
Назва обʼєкта VolumeAttributesClass є важливою: саме за нею користувачі можуть запитати певний клас. Адміністратори встановлюють назву та інші параметри класу під час першого створення обʼєктів VolumeAttributesClass. Хоча назву обʼєкта VolumeAttributesClass у PersistentVolumeClaim можна змінювати, параметри наявного класу є незмінними.
apiVersion: storage.k8s.io/v1
kind: VolumeAttributesClass
metadata:
name: silver
driverName: csi.storage.example.com
parameters:
iops: "3000"
throughput: "50Mi"
Provisioner
Кожен VolumeAttributesClass має provisioner, який визначає, який втулок томів використовується для надання PV. Поле driverName є обовʼязковим.
Підтримку цієї можливості для VolumeAttributesClass реалізовано в kubernetes-csi/external-provisioner.
Ви не обмежені вказанням kubernetes-csi/external-provisioner. Ви також можете запускати та вказувати зовнішні provisioners — незалежні програми, які відповідають специфікації, визначеній Kubernetes. Автори зовнішніх provisioners мають повну свободу щодо того, де розміщено їхній код, як постачається provisioner, як його потрібно запускати, який втулок томів він використовує тощо.
Щоб зрозуміти, як provisioner працює з VolumeAttributesClass, зверніться до документації CSI external-provisioner.
Resizer
Кожен VolumeAttributesClass має resizer, який визначає, який втулок томів використовується для зміни PV. Поле driverName є обовʼязковим.
Підтримку зміни томів для VolumeAttributesClass реалізовано в kubernetes-csi/external-resizer.
Наприклад, наявний PersistentVolumeClaim використовує VolumeAttributesClass з назвою silver:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pv-claim
spec:
…
volumeAttributesClassName: silver
…
У кластері доступний новий VolumeAttributesClass gold:
apiVersion: storage.k8s.io/v1
kind: VolumeAttributesClass
metadata:
name: gold
driverName: csi.storage.example.com
parameters:
iops: "4000"
throughput: "60Mi"
Кінцевий користувач може оновити PVC, вказавши новий VolumeAttributesClass gold, і застосувати зміни:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pv-claim
spec:
…
volumeAttributesClassName: gold
…
Щоб зрозуміти, як resizer працює з VolumeAttributesClass, зверніться до документації CSI external-resizer.
Параметри
VolumeAttributeClasses мають параметри, які описують томи, що до них належать. Залежно від provisioner або resizer можуть прийматися різні параметри. Наприклад, значення 4000 для параметра iops і параметр throughput є специфічними для GCE PD. Якщо параметр пропущено, під час надання тому використовується стандартне значення. Якщо користувач застосовує PVC з іншим VolumeAttributesClass із пропущеними параметрами, стандартне значення параметрів може використовуватися залежно від реалізації драйвера CSI. Докладніше дивіться в документації відповідного драйвера CSI.
Для VolumeAttributesClass можна визначити не більше 512 параметрів. Загальна довжина обʼєкта параметрів, включно з ключами та значеннями, не може перевищувати 256 KiB.
6 - Класи сховищ
У цьому документі описано концепцію StorageClass у Kubernetes. Рекомендується ознайомитися з томами та постійними томами.
StorageClass надає адміністраторам можливість описати класи сховища, які вони пропонують. Різні класи можуть відповідати рівням якості обслуговування, політикам резервного копіювання або довільним політикам, визначеним адміністраторами кластера. Сам Kubernetes не має власної думки щодо того, що представляють класи.
Концепція класу сховища в Kubernetes схожа на «профілі» в дизайні деяких інших систем зберігання.
Обʼєкти StorageClass
Кожен StorageClass містить поля provisioner, parameters та reclaimPolicy, які використовуються, коли PersistentVolume, що належить до цього класу, потрібно надати динамічно, щоб задовольнити PersistentVolumeClaim (PVC).
Назва обʼєкта StorageClass є важливою: саме за нею користувачі можуть запитати певний клас. Адміністратори встановлюють назву та інші параметри класу під час першого створення обʼєктів StorageClass.
Як адміністратор, ви можете вказати стандартний StorageClass, який застосовується до будь-яких PVC, що не запитують конкретний клас. Докладніше дивіться концепцію PersistentVolumeClaim.
Ось приклад StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: low-latency
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi-driver.example-vendor.example
reclaimPolicy: Retain # default value is Delete
allowVolumeExpansion: true
mountOptions:
- discard # this might enable UNMAP / TRIM at the block storage layer
volumeBindingMode: WaitForFirstConsumer
parameters:
guaranteedReadWriteLatency: "true" # provider-specific
Стандартний StorageClass
Ви можете позначити StorageClass як стандартний для свого кластера. Інструкції щодо встановлення стандартного StorageClass дивіться в Зміна стандартного StorageClass.
Якщо PVC не вказує storageClassName, використовується стандартний StorageClass.
Якщо ви встановите анотацію storageclass.kubernetes.io/is-default-class у true для кількох StorageClass у своєму кластері, а потім створите PersistentVolumeClaim без встановленого storageClassName, Kubernetes використає найновіший стандартний StorageClass.
Примітка:
Намагайтеся мати у своєму кластері лише один StorageClass, позначений як стандартний. Kubernetes дозволяє мати кілька стандартних StorageClasses, щоб забезпечити безшовну міграцію.Ви можете створити PersistentVolumeClaim, не вказуючи storageClassName для нового PVC, навіть якщо у вашому кластері немає стандартного StorageClass. У цьому випадку новий PVC створюється так, як ви його визначили, а storageClassName цього PVC залишається невстановленим, доки не стане доступним стандартний клас.
Ви можете мати кластер без стандартного StorageClass. Якщо ви не позначите жоден StorageClass як стандартний (і його не встановлено для вас, наприклад, хмарним провайдером), Kubernetes не зможе застосувати це стандартне значення до PersistentVolumeClaims, яким воно потрібне.
Якщо або коли стандартний StorageClass стає доступним, панель управління визначає всі наявні PVC без storageClassName. Для PVC, які мають порожнє значення storageClassName або не мають цього ключа, панель управління оновлює storageClassName відповідно до нового стандартного StorageClass. Якщо у вас є наявний PVC, де storageClassName має значення "", і ви налаштовуєте стандартний StorageClass, цей PVC не буде оновлено.
Щоб і надалі привʼязуватися до PV із storageClassName, встановленим у "" (за наявності стандартного StorageClass), вам потрібно встановити storageClassName повʼязаного PVC у "".
Provisioner
Кожен StorageClass має provisioner, який визначає, який втулок томів використовується для надання PV. Це поле є обовʼязковим.
| Втулок томів | Внутрішній provisioner | Приклад конфігурації |
|---|---|---|
| AzureFile | ✓ | Azure File |
| CephFS | - | - |
| FC | - | - |
| FlexVolume | - | - |
| iSCSI | - | - |
| Local | - | Local |
| NFS | - | NFS |
| PortworxVolume | ✓ | Portworx Volume |
| RBD | - | Ceph RBD |
| VsphereVolume | ✓ | vSphere |
Ви не обмежені вказанням перелічених тут «внутрішніх» provisioners (назви яких мають префікс "kubernetes.io" і які постачаються разом із Kubernetes). Ви також можете запускати та вказувати зовнішні provisioners — незалежні програми, які відповідають специфікації, визначеній Kubernetes. Автори зовнішніх provisioners мають повну свободу щодо того, де розміщено їхній код, як постачається provisioner, як його потрібно запускати, який втулок томів він використовує (зокрема Flex) тощо. У репозиторії kubernetes-sigs/sig-storage-lib-external-provisioner розміщено бібліотеку для написання зовнішніх provisioners, яка реалізує більшу частину специфікації. Деякі зовнішні provisioners перелічено в репозиторії kubernetes-sigs/sig-storage-lib-external-provisioner.
Наприклад, NFS не надає внутрішнього provisioner, але можна використовувати зовнішній. Також трапляється, що сторонні постачальники сховищ надають власний зовнішній provisioner.
Політика повторного використання
PersistentVolumes, які динамічно створюються за допомогою StorageClass, матимуть політику повторного використання, вказану в полі reclaimPolicy класу, яка може бути Delete або Retain. Якщо reclaimPolicy не вказано під час створення обʼєкта StorageClass, стандартним значенням буде Delete.
PersistentVolumes, створені вручну та керовані за допомогою StorageClass, матимуть ту політику повторного використання, яку їм було призначено під час створення.
Розширення томів
PersistentVolumes можна налаштувати як розширювані. Це дозволяє змінювати розмір тому, редагуючи відповідний обʼєкт PVC і запитуючи новий, більший обсяг сховища.
Такі типи томів підтримують розширення, коли базовий StorageClass має поле allowVolumeExpansion зі значенням true.
| Тип тому | Потрібна версія Kubernetes для розширення тому |
|---|---|
| Azure File | 1.11 |
| CSI | 1.24 |
| FlexVolume | 1.13 |
| Portworx | 1.11 |
| rbd | 1.11 |
Примітка:
Можливість розширення томів можна використовувати лише для збільшення тому, але не для його зменшення.Параметри монтування
PersistentVolumes, які динамічно створюються за допомогою StorageClass, матимуть параметри монтування, вказані в полі mountOptions класу.
Якщо втулок томів не підтримує параметри монтування, але їх вказано, надання завершиться невдачею. Параметри монтування не перевіряються ні на рівні класу, ні на рівні PV. Якщо параметр монтування недійсний, монтування PV завершиться невдачею.
Режим привʼязки тому
Поле volumeBindingMode визначає, коли мають відбуватися привʼязка томів і динамічне надання. Якщо його не встановлено, стандартно використовується режим Immediate.
Режим Immediate означає, що привʼязка томів і динамічне надання відбуваються одразу після створення PersistentVolumeClaim. Для бекендів сховища, які обмежені топологією й не доступні глобально з усіх вузлів кластера, PersistentVolumes будуть привʼязані або надані без урахування вимог планування Podʼа. Це може призвести до Podʼів, не придатних для планування.
Адміністратор кластера може розвʼязати цю проблему, вказавши режим WaitForFirstConsumer, який відкладає привʼязку та надання PersistentVolume до створення Podʼа, що використовує PersistentVolumeClaim. PersistentVolumes будуть вибрані або надані відповідно до топології, заданої обмеженнями планування Podʼа. Це, зокрема, вимоги до ресурсів, селектори вузлів, спорідненість та антиспорідненість Podʼів, а також taints і tolerations.
Такі втулки підтримують WaitForFirstConsumer із динамічним наданням:
- Томи CSI, за умови, що конкретний драйвер CSI це підтримує
Такі втулки підтримують WaitForFirstConsumer із привʼязкою попередньо створених PersistentVolume:
- Томи CSI, за умови, що конкретний драйвер CSI це підтримує
local
Примітка:
Якщо ви вирішили використовувати WaitForFirstConsumer, не використовуйте nodeName у специфікації Podʼа для задання спорідненості вузла. Якщо в цьому випадку використати nodeName, планувальник буде оминуто, а PVC залишиться в стані pending.
Натомість ви можете використати селектор вузла для kubernetes.io/hostname:
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
nodeSelector:
kubernetes.io/hostname: kube-01
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Дозволені топології
Коли оператор кластера вказує режим привʼязки томів WaitForFirstConsumer, у більшості випадків більше не потрібно обмежувати надання конкретними топологіями. Однак, якщо це все ще потрібно, можна вказати allowedTopologies.
У цьому прикладі показано, як обмежити топологію наданих томів конкретними зонами; це слід використовувати як заміну параметрам zone та zones для підтримуваних втулків.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: example.com/example
parameters:
type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/zone
values:
- us-central-1a
- us-central-1b
Параметри
StorageClasses мають параметри, які описують томи, що належать до класу сховища. Залежно від provisioner можуть прийматися різні параметри. Якщо параметр пропущено, використовується певне стандартне значення.
Для StorageClass можна визначити не більше 512 параметрів. Загальна довжина обʼєкта параметрів, включно з ключами та значеннями, не може перевищувати 256 KiB.
AWS EBS
Kubernetes 1.37 не містить типу тому awsElasticBlockStore.
Вбудований драйвер сховища AWSElasticBlockStore визнано застарілим у випуску Kubernetes v1.19, а потім повністю вилучено у випуску v1.27.
Проєкт Kubernetes пропонує натомість використовувати зовнішній драйвер сховища AWS EBS.
Ось приклад StorageClass для драйвера CSI AWS EBS:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
csi.storage.k8s.io/fstype: xfs
type: io1
iopsPerGB: "50"
encrypted: "true"
tagSpecification_1: "key1=value1"
tagSpecification_2: "key2=value2"
allowedTopologies:
- matchLabelExpressions:
- key: topology.ebs.csi.aws.com/zone
values:
- us-east-2c
tagSpecification: Теґи з цим префіксом застосовуються до динамічно наданих томів EBS.
AWS EFS
Щоб налаштувати сховище AWS EFS, можна використовувати зовнішній драйвер AWS_EFS_CSI_DRIVER.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-92107410
directoryPerms: "700"
provisioningMode: Тип тому, який надає Amazon EFS. Наразі підтримується лише надання на основі точки доступу (efs-ap).fileSystemId: Файлова система, під якою створюється точка доступу.directoryPerms: Дозволи кореневої теки, створеної точкою доступу.
Докладніше дивіться в документації AWS_EFS_CSI_Driver Dynamic Provisioning.
NFS
Щоб налаштувати сховище NFS, можна використовувати вбудований драйвер або драйвер CSI для NFS у Kubernetes (рекомендовано).
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-nfs
provisioner: example.com/external-nfs
parameters:
server: nfs-server.example.com
path: /share
readOnly: "false"
server: Server — це імʼя хоста або IP-адреса сервера NFS.path: Шлях, який експортується сервером NFS.readOnly: Прапорець, який вказує, чи буде сховище змонтовано лише для читання (стандартно false).
Kubernetes не містить внутрішнього provisioner для NFS. Щоб створити StorageClass для NFS, потрібно використовувати зовнішній provisioner. Ось кілька прикладів:
vSphere
Існує два типи provisioners для класів сховища vSphere:
- Provisioner CSI:
csi.vsphere.vmware.com - Provisioner vCP:
kubernetes.io/vsphere-volume
Вбудовані provisioners застаріли. Докладніше про provisioner CSI дивіться в Kubernetes vSphere CSI Driver та міграції vSphereVolume на CSI.
Provisioner CSI
Provisioner StorageClass для vSphere CSI працює з кластерами Tanzu Kubernetes. Приклад дивіться в репозиторії vSphere CSI.
Provisioner vCP
У наведених нижче прикладах використовується provisioner StorageClass VMware Cloud Provider (vCP).
Створіть StorageClass із форматом диска, вказаним користувачем.
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthickdiskformat:thin,zeroedthickтаeagerzeroedthick. Стандартно:"thin".Створіть StorageClass із форматом диска на вказаному користувачем сховищі даних.
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick datastore: VSANDatastoredatastore: Користувач також може вказати datastore у StorageClass. Том буде створено в datastore, вказаному в StorageClass, у цьому випадку —VSANDatastore. Це поле є необовʼязковим. Якщо datastore не вказано, том буде створено в datastore, вказаному у файлі конфігурації vSphere, який використовується для ініціалізації хмарного провайдера vSphere.Керування політикою сховища в Kubernetes
Використання наявної політики SPBM vCenter
Однією з найважливіших можливостей vSphere для керування сховищем є керування на основі політик. Керування сховищем на основі політик (Storage Policy Based Management, SPBM) — це фреймворк політик сховища, який надає єдину уніфіковану панель управління для широкого спектра сервісів даних і рішень зберігання. SPBM дозволяє адміністраторам vSphere долати початкові проблеми надання сховища, такі як планування місткості, диференційовані рівні обслуговування та керування запасом місткості.
Політики SPBM можна вказати в StorageClass за допомогою параметра
storagePolicyName.Підтримка політики Virtual SAN всередині Kubernetes
Адміністратори Vsphere Infrastructure (VI) матимуть змогу вказувати власні можливості сховища Virtual SAN під час динамічного надання томів. Тепер ви можете визначати вимоги до сховища, такі як продуктивність і доступність, у вигляді можливостей сховища під час динамічного надання томів. Вимоги до можливостей сховища перетворюються на політику Virtual SAN, яка потім передається на рівень Virtual SAN під час створення постійного тому (віртуального диска). Віртуальний диск розподіляється по сховищу даних Virtual SAN відповідно до вимог.
Докладніше про використання політик сховища для керування постійними томами дивіться в Storage Policy Based Management for dynamic provisioning of volumes.
Ceph RBD (застаріло)
Примітка:
Цей внутрішній provisioner Ceph RBD застарів. Використовуйте CephFS RBD CSI driver.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/rbd # This provisioner is deprecated
parameters:
monitors: 198.19.254.105:6789
adminId: kube
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-secret-user
userSecretNamespace: default
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
monitors: Монітори Ceph, розділені комою. Цей параметр є обовʼязковим.adminId: Ідентифікатор клієнта Ceph, який може створювати образи в пулі. Стандартно "admin".adminSecretName: Назва Secret дляadminId. Цей параметр є обовʼязковим. Наданий Secret повинен мати тип "kubernetes.io/rbd".adminSecretNamespace: Простір імен дляadminSecretName. Стандартно "default".pool: Пул Ceph RBD. Стандартно "rbd".userId: Ідентифікатор клієнта Ceph, який використовується для зіставлення образу RBD. Стандартно такий самий, якadminId.userSecretName: Назва Ceph Secret дляuserIdдля зіставлення образу RBD. Він має існувати в тому самому просторі імен, що й PVC. Цей параметр є обовʼязковим. Наданий Secret повинен мати тип "kubernetes.io/rbd", наприклад, створений таким чином:kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ --namespace=kube-systemuserSecretNamespace: Простір імен дляuserSecretName.fsType: fsType, який підтримує Kubernetes. Стандартно:"ext4".imageFormat: Формат образу Ceph RBD, "1" або "2". Стандартно "2".imageFeatures: Цей параметр є необовʼязковим, і його слід використовувати лише тоді, коли ви встановилиimageFormatу "2". Наразі підтримується лише можливістьlayering. Стандартно "", і жодну можливість не ввімкнено.
Azure Disk
Kubernetes 1.37 не містить типу тому azureDisk.
Вбудований драйвер сховища azureDisk визнано застарілим у випуску Kubernetes v1.19, а потім повністю вилучено у випуску v1.27.
Проєкт Kubernetes пропонує натомість використовувати сторонній драйвер сховища Azure Disk.
Azure File (застаріло)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name # example value
skuName: Рівень SKU облікового запису Azure Storage. Стандартно порожній.location: Розташування облікового запису Azure Storage. Стандартно порожнє.storageAccount: Назва облікового запису Azure Storage. Стандартно порожня. Якщо обліковий запис сховища не вказано, серед усіх облікових записів сховища, повʼязаних із групою ресурсів, шукається той, що відповідаєskuNameтаlocation. Якщо обліковий запис сховища вказано, він має бути в тій самій групі ресурсів, що й кластер, аskuNameтаlocationігноруються.secretNamespace: Простір імен Secret, що містить назву та ключ облікового запису Azure Storage. Стандартно той самий, що й у Podʼа.secretName: Назва Secret, що містить назву та ключ облікового запису Azure Storage. Стандартноazure-storage-account-<accountName>-secret.readOnly: Прапорець, який вказує, чи буде сховище змонтовано лише для читання. Стандартно false, що означає монтування для читання й запису. Це налаштування також впливає на налаштуванняReadOnlyу VolumeMounts.
Під час надання сховища для облікових даних монтування створюється Secret із назвою secretName. Якщо в кластері ввімкнено і RBAC, і ролі контролерів, додайте дозвіл create на ресурс secret для clusterrole system:controller:persistent-volume-binder.
У контексті багатоорендності наполегливо рекомендується явно встановлювати значення secretNamespace, інакше облікові дані облікового запису сховища можуть прочитати інші користувачі.
Portworx volume (застаріло)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume # This provisioner is deprecated
parameters:
repl: "1"
snap_interval: "70"
priority_io: "high"
fs: файлова система для створення:none/xfs/ext4(стандартно:ext4).block_size: розмір блоку в кілобайтах (стандартно:32).repl: кількість синхронних реплік у формі коефіцієнта реплікації1..3(стандартно:1). Тут очікується рядок, тобто"1", а не1.priority_io: визначає, чи буде том створено зі сховища вищої продуктивності чи нижчого пріоритету:high/medium/low(стандартно:low).snap_interval: інтервал у хвилинах для запуску знімків. Знімки є інкрементними на основі різниці з попереднім знімком, 0 вимикає знімки (стандартно:0). Тут очікується рядок, тобто"70", а не70.aggregation_level: вказує кількість частин, на які буде розподілено том, 0 означає неагрегований том (стандартно:0). Тут очікується рядок, тобто"0", а не0.ephemeral: вказує, чи слід очищати том після відмонтування, чи він має бути постійним. Для випадку використанняemptyDirце значення можна встановити в true, а для випадкуpersistent volumes, наприклад, для баз даних на кшталт Cassandra, слід установити false:true/false(стандартноfalse). Тут очікується рядок, тобто"true", а неtrue.
Локальне сховище
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner # indicates that this StorageClass does not support automatic provisioning
volumeBindingMode: WaitForFirstConsumer
Локальні томи не підтримують динамічне надання в Kubernetes 1.37; однак StorageClass однаково слід створити, щоб відкласти привʼязку тому до фактичного планування Podʼа на відповідний вузол. Це задається режимом привʼязки томів WaitForFirstConsumer.
Відкладення привʼязки тому дозволяє планувальнику враховувати всі обмеження планування Podʼа під час вибору відповідного PersistentVolume для PersistentVolumeClaim.
7 - Динамічне надання томів
Динамічне надання томів дозволяє створювати томи сховища на вимогу. Без динамічного надання адміністратори кластера змушені вручну звертатися до свого хмарного провайдера або постачальника сховища, щоб створити нові томи сховища, а потім створювати обʼєкти PersistentVolume, які представляють їх у Kubernetes. Можливість динамічного надання усуває потребу адміністраторів кластера заздалегідь надавати сховище. Натомість сховище надається автоматично, коли користувачі створюють обʼєкти PersistentVolumeClaim.
Загальні відомості
Реалізація динамічного надання томів базується на обʼєкті API StorageClass із групи API storage.k8s.io. Адміністратор кластера може визначити стільки обʼєктів StorageClass, скільки потрібно, і кожен із них вказує втулок томів (також відомий як provisioner), який надає том, і набір параметрів, які слід передати цьому provisioner під час надання. Адміністратор кластера може визначити та зробити доступними кілька різновидів сховища (з однієї або різних систем зберігання) у межах кластера, кожен із власним набором параметрів. Така архітектура також гарантує, що кінцевим користувачам не потрібно перейматися складністю та нюансами надання сховища, але вони все одно можуть вибирати з кількох варіантів сховища.
Докладніше дивіться в концепції Класи сховищ.
Увімкнення динамічного надання
Щоб увімкнути динамічне надання, адміністратор кластера має заздалегідь створити для користувачів один або кілька обʼєктів StorageClass. Обʼєкти StorageClass визначають, який provisioner слід використовувати та які параметри потрібно передати цьому provisioner під час виклику динамічного надання. Назва обʼєкта StorageClass має бути дійсним іменем DNS-піддомену.
Наведений нижче маніфест створює клас сховища "slow", який надає стандартні постійні диски, подібні до звичайних дисків.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
Наведений нижче маніфест створює клас сховища "fast", який надає постійні диски, подібні до SSD.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
Використання динамічного надання
Користувачі запитують динамічно надане сховище, вказуючи клас сховища у своєму PersistentVolumeClaim. До Kubernetes v1.6 це робилося за допомогою анотації volume.beta.kubernetes.io/storage-class. Однак ця анотація застаріла з версії v1.9. Тепер користувачі можуть і повинні використовувати натомість поле storageClassName обʼєкта PersistentVolumeClaim. Значення цього поля має збігатися з назвою StorageClass, налаштованого адміністратором (дивіться Увімкнення динамічного надання).
Наприклад, щоб вибрати клас сховища "fast", користувач створює такий PersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 30Gi
Цей PersistentVolumeClaim призводить до автоматичного надання постійного диска, подібного до SSD. Коли PersistentVolumeClaim видаляють, том знищується.
Стандартна поведінка
Динамічне надання можна ввімкнути в кластері так, щоб усі PersistentVolumeClaims надавалися динамічно, якщо клас сховища не вказано. Адміністратор кластера може ввімкнути таку поведінку таким чином:
- Позначити один обʼєкт
StorageClassяк стандартний. - Переконатися, що контролер допуску
DefaultStorageClassувімкнено на API-сервері.
Адміністратор може позначити певний StorageClass як стандартний, додавши до нього анотацію storageclass.kubernetes.io/is-default-class. Коли в кластері є стандартний StorageClass і користувач створює PersistentVolumeClaim без вказаного storageClassName, контролер допуску DefaultStorageClass автоматично додає поле storageClassName, що вказує на стандартний клас сховища.
Зверніть увагу, що якщо ви встановите анотацію storageclass.kubernetes.io/is-default-class у true для кількох StorageClass у своєму кластері, а потім створите PersistentVolumeClaim без встановленого storageClassName, Kubernetes використає найновіший стандартний StorageClass.
Урахування топології
У кластерах із кількома зонами Podʼи можуть бути розподілені між зонами регіону. Однозонні бекенди сховища слід надавати в тих зонах, де заплановано Podʼи. Цього можна досягти, встановивши режим привʼязки тому.
8 - Знімки томів
У Kubernetes VolumeSnapshot представляє знімок тому в системі зберігання. У цьому документі передбачається, що ви вже знайомі з постійними томами Kubernetes.
Вступ
Подібно до того, як ресурси API PersistentVolume та PersistentVolumeClaim використовуються для надання томів користувачам і адміністраторам, ресурси API VolumeSnapshotContent та VolumeSnapshot призначені для створення знімків томів для користувачів і адміністраторів.
VolumeSnapshotContent — це знімок, зроблений із тому в кластері, наданого адміністратором. Це ресурс у кластері, так само як PersistentVolume є ресурсом кластера.
VolumeSnapshot — це запит на знімок тому від користувача. Він схожий на PersistentVolumeClaim.
VolumeSnapshotClass дозволяє вказати різні атрибути, що належать до VolumeSnapshot. Ці атрибути можуть відрізнятися для знімків, зроблених з одного й того самого тому в системі зберігання, і тому їх не можна виразити за допомогою того самого StorageClass у PersistentVolumeClaim.
Знімки томів надають користувачам Kubernetes стандартизований спосіб копіювання вмісту тому на певний момент часу без створення цілком нового тому. Ця функціональність дозволяє, наприклад, адміністраторам баз даних створювати резервні копії баз даних перед внесенням змін або видаленням.
Під час використання цієї можливості користувачі повинні знати таке:
- API-обʼєкти
VolumeSnapshot,VolumeSnapshotContentтаVolumeSnapshotClassє CRDs, а не частиною основного API. - Підтримка
VolumeSnapshotдоступна лише для драйверів CSI. - У межах процесу розгортання
VolumeSnapshotкоманда Kubernetes надає контролер знімків, який розгортається в панелі управління, і допоміжний sidecar-контейнер csi-snapshotter, який розгортається разом із драйвером CSI. Контролер знімків стежить за обʼєктамиVolumeSnapshotтаVolumeSnapshotContentі відповідає за створення та видалення обʼєктаVolumeSnapshotContent. Sidecar-контейнер csi-snapshotter стежить за обʼєктамиVolumeSnapshotContentі запускає операціїCreateSnapshotтаDeleteSnapshotдля точки доступу CSI. - Також існує сервер валідаційного вебхука, який забезпечує посилену валідацію обʼєктів знімків. Його мають встановлювати дистрибутиви Kubernetes разом із контролером знімків і CRDs, а не драйвери CSI. Його слід встановити в усіх кластерах Kubernetes, де ввімкнено можливість знімків.
- Драйвери CSI можуть реалізовувати функціональність знімків томів, а можуть і не реалізовувати. Драйвери CSI, які надають підтримку знімків томів, імовірно, використовуватимуть csi-snapshotter. Докладніше дивіться в документації драйверів CSI.
- За встановлення CRDs та контролера знімків відповідає дистрибутив Kubernetes.
Для складніших випадків використання, таких як створення групових знімків кількох томів, дивіться зовнішню документацію CSI Volume Group Snapshot.
У кластерах, де знімок можна використовувати лише з частини кластера (наприклад, знімок тому в одній зоні багатозонового кластера без спільного сховища), топологію знімка можна записати та враховувати під час відновлення з нього. Докладніше дивіться у зовнішній документації CSI.
Життєвий цикл знімка тому та вмісту знімка тому
VolumeSnapshotContents — це ресурси в кластері. VolumeSnapshots — це запити на ці ресурси. Взаємодія між VolumeSnapshotContents та VolumeSnapshots відбувається за таким життєвим циклом:
Надання знімків томів
Знімки можна надавати двома способами: попередньо або динамічно.
Попереднє надання
Адміністратор кластера створює певну кількість VolumeSnapshotContents. Вони містять відомості про реальний знімок тому в системі зберігання, доступний для використання користувачами кластера. Вони існують в API Kubernetes і доступні для використання.
Динамічне надання
Замість використання наявного знімка ви можете запросити динамічне створення знімка з PersistentVolumeClaim. VolumeSnapshotClass вказує специфічні для постачальника сховища параметри, які слід використовувати під час створення знімка.
Привʼязка
Контролер знімків відповідає за привʼязку обʼєкта VolumeSnapshot до відповідного обʼєкта VolumeSnapshotContent як за попереднього, так і за динамічного надання. Привʼязка є зіставленням один до одного.
У випадку попереднього надання VolumeSnapshot залишається непривʼязаним, доки не буде створено запитаний обʼєкт VolumeSnapshotContent.
Захист PersistentVolumeClaim як джерела знімка
Мета цього захисту — гарантувати, що обʼєкти API PersistentVolumeClaim, які використовуються, не вилучаються із системи, поки з них робиться знімок (оскільки це може призвести до втрати даних).
Поки з PersistentVolumeClaim робиться знімок, цей PersistentVolumeClaim вважається таким, що використовується. Якщо ви видалите обʼєкт API PersistentVolumeClaim, який активно використовується як джерело знімка, обʼєкт PersistentVolumeClaim вилучається не одразу. Натомість його вилучення відкладається, доки знімок не стане readyToUse або не буде перерваний.
Видалення
Видалення запускається видаленням обʼєкта VolumeSnapshot, і далі діє DeletionPolicy. Якщо DeletionPolicy має значення Delete, базовий знімок сховища буде видалено разом з обʼєктом VolumeSnapshotContent. Якщо DeletionPolicy має значення Retain, то і базовий знімок, і VolumeSnapshotContent залишаються.
VolumeSnapshots
Кожен VolumeSnapshot містить spec і status.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: new-snapshot-test
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: pvc-test
persistentVolumeClaimName — це назва обʼєкта PersistentVolumeClaim, який є джерелом даних для знімка. Це поле є обовʼязковим для динамічного створення знімка.
Знімок тому може запитати певний клас, вказавши назву VolumeSnapshotClass в атрибуті volumeSnapshotClassName. Якщо нічого не вказано, використовується стандартний клас, якщо він доступний.
Для попередньо наданих знімків потрібно вказати volumeSnapshotContentName як джерело знімка, як показано в наведеному нижче прикладі. Поле джерела volumeSnapshotContentName є обовʼязковим для попередньо наданих знімків.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: test-snapshot
spec:
source:
volumeSnapshotContentName: test-content
Вміст знімків томів
Кожен VolumeSnapshotContent містить spec і status. Під час динамічного надання загальний контролер знімків створює обʼєкти VolumeSnapshotContent. Ось приклад:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: snapcontent-72d9a349-aacd-42d2-a240-d775650d2455
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
volumeHandle: ee0cfb94-f8d4-11e9-b2d8-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotClassName: csi-hostpath-snapclass
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
uid: 72d9a349-aacd-42d2-a240-d775650d2455
volumeHandle — це унікальний ідентифікатор тому, створеного в бекенді сховища й повернутого драйвером CSI під час створення тому. Це поле є обовʼязковим для динамічного надання знімка. Воно вказує том-джерело знімка.
Для попередньо наданих знімків ви (як адміністратор кластера) відповідаєте за створення обʼєкта VolumeSnapshotContent, як показано нижче.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
snapshotHandle — це унікальний ідентифікатор знімка тому, створеного в бекенді сховища. Це поле є обовʼязковим для попередньо наданих знімків. Воно вказує ідентифікатор знімка CSI в системі зберігання, який представляє цей VolumeSnapshotContent.
sourceVolumeMode — це режим тому, з якого зроблено знімок. Значенням поля sourceVolumeMode може бути Filesystem або Block. Якщо режим вихідного тому не вказано, Kubernetes вважає, що режим вихідного тому невідомий.
volumeSnapshotRef — це посилання на відповідний VolumeSnapshot. Зверніть увагу, що коли VolumeSnapshotContent створюється як попередньо наданий знімок, VolumeSnapshot, на який посилається volumeSnapshotRef, може ще не існувати.
Зміна режиму тому знімка
Якщо API VolumeSnapshots, встановлений у вашому кластері, підтримує поле sourceVolumeMode, то API може не давати неавторизованим користувачам змінювати режим тому.
Щоб перевірити, чи підтримує ваш кластер цю можливість, виконайте таку команду:
$ kubectl get crd volumesnapshotcontent -o yaml
Якщо ви хочете дозволити користувачам створювати PersistentVolumeClaim з наявного VolumeSnapshot, але з іншим режимом тому, ніж у джерела, слід додати анотацію snapshot.storage.kubernetes.io/allow-volume-mode-change: "true" до VolumeSnapshotContent, який відповідає VolumeSnapshot.
Для попередньо наданих знімків spec.sourceVolumeMode має заповнити адміністратор кластера.
Приклад ресурсу VolumeSnapshotContent із увімкненою цією можливістю виглядатиме так:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
annotations:
- snapshot.storage.kubernetes.io/allow-volume-mode-change: "true"
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
Топологія знімків томів
У деяких кластерах знімок можна використовувати лише з частини кластера. Наприклад, у багатозоновому кластері, де сховище не є спільним між зонами, знімок тому в одній зоні можна використовувати лише з цієї зони: томи, відновлені зі знімка, можна створювати лише там, де розташовані дані знімка.
Коли ввімкнено можливість VolumeSnapshotTopology, ця топологія записується та враховується:
- Адміністратор кластера може встановити
allowedTopologiesу VolumeSnapshotClass, щоб вказати, звідки мають бути доступні динамічно створені знімки. - Драйвер CSI повідомляє, звідки можна використовувати знімок, а sidecar-контейнер csi-snapshotter записує це в
VolumeSnapshotContent.spec.nodeAffinity. - Коли ви надаєте том зі знімка, ця топологія використовується для розміщення відновленого тому там, де доступні дані знімка.
Це альфа-можливість sidecar-контейнерів CSI, яка вмикається функціональною можливістю VolumeSnapshotTopology у csi-snapshotter та external-provisioner. Докладніше дивіться у зовнішній документації CSI.
Надання томів зі знімків
Ви можете надати новий том, попередньо заповнений даними зі знімка, за допомогою поля dataSource в обʼєкті PersistentVolumeClaim.
Докладніше дивіться в Знімок тому та відновлення тому зі знімка.
9 - Класи знімків томів
У цьому документі описано концепцію VolumeSnapshotClass у Kubernetes. Рекомендується ознайомитися зі знімками томів та класами сховищ.
Вступ
Так само як StorageClass надає адміністраторам можливість описувати «класи» сховища, які вони пропонують під час надання тому, VolumeSnapshotClass надає можливість описувати «класи» сховища під час надання знімка тому.
Ресурс VolumeSnapshotClass
Кожен VolumeSnapshotClass містить поля driver, deletionPolicy та parameters, які використовуються, коли VolumeSnapshot, що належить до цього класу, потрібно надати динамічно.
Назва обʼєкта VolumeSnapshotClass є важливою: саме за нею користувачі можуть запитати певний клас. Адміністратори встановлюють назву та інші параметри класу під час першого створення обʼєктів VolumeSnapshotClass, і ці обʼєкти не можна оновлювати після створення.
Примітка:
За встановлення CRD відповідає дистрибутив Kubernetes. Якщо потрібних CRD немає, створення VolumeSnapshotClass завершиться невдачею.apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
Адміністратори можуть вказати стандартний VolumeSnapshotClass для VolumeSnapshots, які не запитують привʼязки до певного класу, додавши анотацію snapshot.storage.kubernetes.io/is-default-class: "true":
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true"
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
Якщо існує кілька драйверів CSI, для кожного з них можна вказати стандартний VolumeSnapshotClass.
Залежності VolumeSnapshotClass
Коли ви створюєте VolumeSnapshot без зазначення VolumeSnapshotClass, Kubernetes автоматично вибирає стандартний VolumeSnapshotClass, драйвер CSI якого збігається з драйвером CSI StorageClass цього PVC.
Така поведінка дозволяє кільком стандартним обʼєктам VolumeSnapshotClass співіснувати в кластері, якщо кожен із них повʼязаний з унікальним драйвером CSI.
Завжди переконуйтеся, що для кожного драйвера CSI існує лише один стандартний VolumeSnapshotClass. Якщо з одним драйвером CSI створено кілька стандартних обʼєктів VolumeSnapshotClass, створення VolumeSnapshot завершиться невдачею, оскільки Kubernetes не зможе визначити, який із них використати.
Driver
Класи знімків томів мають драйвер, який визначає, який втулок томів CSI використовується для надання VolumeSnapshots. Це поле є обовʼязковим.
DeletionPolicy
Класи знімків томів мають deletionPolicy. Вона дозволяє налаштувати, що станеться з VolumeSnapshotContent, коли обʼєкт VolumeSnapshot, до якого він привʼязаний, буде видалено. Значення deletionPolicy класу знімків томів може бути Retain або Delete. Це поле є обовʼязковим.
Якщо deletionPolicy має значення Delete, базовий знімок сховища буде видалено разом з обʼєктом VolumeSnapshotContent. Якщо deletionPolicy має значення Retain, то і базовий знімок, і VolumeSnapshotContent залишаються.
Параметри
Класи знімків томів мають параметри, які описують знімки томів, що належать до цього класу. Залежно від driver можуть прийматися різні параметри.
10 - Клонування томів CSI
У цьому документі описано концепцію клонування наявних томів CSI у Kubernetes. Рекомендується ознайомитися з томами.
Вступ
Можливість клонування томів CSI додає підтримку вказання наявних PVC у полі dataSource, щоб позначити, що користувач хоче клонувати том.
Клон — це дублікат наявного тому Kubernetes, який можна використовувати так само, як будь-який стандартний том. Єдина відмінність полягає в тому, що під час надання, замість створення «нового» порожнього тому, бекенд-пристрій створює точний дублікат вказаного тому.
З погляду API Kubernetes реалізація клонування додає можливість вказати наявний PVC як dataSource під час створення нового PVC. Вихідний PVC має бути привʼязаним і доступним (не використовуватися).
Під час використання цієї можливості користувачі повинні знати таке:
- Підтримка клонування (
VolumePVCDataSource) доступна лише для драйверів CSI. - Підтримка клонування доступна лише для динамічних provisioners.
- Драйвери CSI можуть реалізовувати функціональність клонування томів, а можуть і не реалізовувати.
- Ви можете клонувати PVC лише тоді, коли він існує в тому самому просторі імен, що й цільовий PVC (джерело та призначення мають бути в одному просторі імен).
- Клонування підтримується з іншим Storage Class.
- Цільовий том може мати той самий або інший клас сховища, ніж джерело.
- Можна використовувати стандартний клас сховища, пропустивши storageClassName у специфікації.
- Клонування можна виконати лише між двома томами, які використовують однакове значення VolumeMode (якщо ви запитуєте том у блоковому режимі, джерело ТАКОЖ ПОВИННО бути в блоковому режимі)
Надання
Клони надаються так само, як і будь-який інший PVC, за винятком додавання dataSource, який посилається на наявний PVC у тому самому просторі імен.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clone-of-pvc-1
namespace: myns
spec:
accessModes:
- ReadWriteOnce
storageClassName: cloning
resources:
requests:
storage: 5Gi
dataSource:
kind: PersistentVolumeClaim
name: pvc-1
Примітка:
Ви повинні вказати значення місткості дляspec.resources.requests.storage, і воно має бути таким самим або більшим за місткість вихідного тому.Результатом є новий PVC із назвою clone-of-pvc-1, який має точно такий самий вміст, як і вказане джерело pvc-1.
Використання
Коли новий PVC стає доступним, клонований PVC використовується так само, як і інші PVC. На цьому етапі також очікується, що новостворений PVC є незалежним обʼєктом. Його можна використовувати, клонувати, створювати його знімки чи видаляти незалежно й без огляду на вихідний PVC з dataSource. Це також означає, що джерело ніяк не повʼязане з новоствореним клоном і його також можна змінити чи видалити, не впливаючи на новостворений клон.
11 - Наповнювачі томів та джерела даних
У цьому документі описано наповнювачі томів (volume populators) та джерела даних (data sources) у Kubernetes. Рекомендується ознайомитися з постійними томами.
Коли ви створюєте PersistentVolumeClaim, том, який Kubernetes надає для нього, зазвичай спочатку порожній. Джерело даних дозволяє натомість запитати, щоб новий том було попередньо заповнено наявними даними. Наповнювачі томів — це контролери, які виконують це заповнення на основі джерела даних, на яке посилається PersistentVolumeClaim.
Kubernetes має вбудовану підтримку джерел даних, які клонують наявний том або відновлюють знімок тому. Власні наповнювачі томів розширюють цей механізм. Джерело даних — це власний ресурс, тобто обʼєкт, тип якого визначено за допомогою CustomResourceDefinition. Контролер-наповнювач стежить за PersistentVolumeClaims, які посилаються на такий ресурс, і заповнює з нього новий том.
Наповнювачі томів та джерела даних
Kubernetes підтримує власні наповнювачі томів. Щоб використовувати власні наповнювачі томів, ви повинні ввімкнути функціональну можливість AnyVolumeDataSource для kube-apiserver та kube-controller-manager.
Наповнювачі томів використовують поле специфікації PVC з назвою dataSourceRef. На відміну від поля dataSource, яке може містити лише посилання на інший PersistentVolumeClaim або на VolumeSnapshot, поле dataSourceRef може містити посилання на будь-який обʼєкт у тому самому просторі імен, за винятком основних обʼєктів, відмінних від PVC. Для кластерів, у яких увімкнено цю функціональну можливість, слід надавати перевагу dataSourceRef, а не dataSource.
Посилання на джерела даних
Поле dataSourceRef поводиться майже так само, як поле dataSource. Якщо вказано одне з них, а інше ні, API-сервер надасть обом полям однакове значення. Жодне з полів не можна змінити після створення, а спроба вказати різні значення для цих двох полів призведе до помилки валідації. Тому обидва поля завжди матимуть однаковий вміст.
Існують дві відмінності між полями dataSourceRef та dataSource, про які користувачі повинні знати:
- Поле
dataSourceігнорує недійсні значення (ніби поле було порожнім), тоді якdataSourceRefніколи не ігнорує значення і спричинить помилку, якщо використано недійсне значення. Недійсними значеннями є будь-які основні обʼєкти (обʼєкти без apiGroup), крім PVC. - Поле
dataSourceRefможе містити різні типи обʼєктів, тоді як полеdataSourceдозволяє лише PVC та VolumeSnapshots.
Коли ввімкнено можливість CrossNamespaceVolumeDataSource, зʼявляються додаткові відмінності:
- Поле
dataSourceдозволяє лише локальні обʼєкти, тоді як полеdataSourceRefдозволяє обʼєкти в будь-яких просторах імен. - Коли вказано простір імен,
dataSourceтаdataSourceRefне синхронізуються.
Користувачі завжди повинні використовувати dataSourceRef у кластерах, де ввімкнено цю функціональну можливість, і повертатися до dataSource у кластерах, де її не ввімкнено. За жодних обставин не потрібно переглядати обидва поля. Дубльовані значення з дещо різною семантикою існують лише для зворотної сумісності. Зокрема, суміш старіших і новіших контролерів може взаємодіяти, оскільки поля однакові.
Використання наповнювачів томів
Наповнювачі томів — це контролери, які можуть створювати непорожні томи, вміст яких визначається власним ресурсом. Користувачі створюють заповнений том, посилаючись на власний ресурс за допомогою поля dataSourceRef:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: populated-pvc
spec:
dataSourceRef:
name: example-name
kind: ExampleDataSource
apiGroup: example.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Оскільки наповнювачі томів є зовнішніми компонентами, спроби створити PVC, який використовує один із них, можуть завершитися невдачею, якщо встановлено не всі потрібні компоненти. Зовнішні контролери повинні генерувати Events на PVC, щоб надавати зворотний звʼязок про статус створення, зокрема попередження, якщо PVC неможливо створити через відсутність певного компонента.
Ви можете встановити у свій кластер alpha-контролер volume data source validator. Цей контролер генерує попереджувальні Events на PVC, якщо жоден наповнювач не зареєстровано для обробки такого виду джерела даних. Коли для PVC встановлено відповідний наповнювач, саме цей контролер-наповнювач відповідає за створення Events, повʼязаних зі створенням тому та проблемами під час цього процесу.
Джерела даних між просторами імен
Kubernetes підтримує джерела даних томів між просторами імен. Щоб використовувати їх, ви повинні ввімкнути функціональні можливості AnyVolumeDataSource та CrossNamespaceVolumeDataSource для kube-apiserver та kube-controller-manager. Крім того, ви повинні ввімкнути функціональну можливість CrossNamespaceVolumeDataSource для csi-provisioner.
Увімкнення функціональної можливості CrossNamespaceVolumeDataSource дозволяє вказати простір імен у полі dataSourceRef.
Примітка:
Коли ви вказуєте простір імен для джерела даних тому, Kubernetes перевіряє наявність ReferenceGrant в іншому просторі імен, перш ніж прийняти посилання. ReferenceGrant є частиною API розширенняgateway.networking.k8s.io. Докладніше дивіться в розділі ReferenceGrant документації Gateway API. Це означає, що перед використанням цього механізму ви повинні розширити свій кластер Kubernetes принаймні ресурсом ReferenceGrant із Gateway API.Використання джерела даних тому між просторами імен
Створіть ReferenceGrant, щоб дозволити власнику простору імен прийняти посилання. Ви визначаєте заповнений том, вказуючи джерело даних тому між просторами імен за допомогою поля dataSourceRef. У вихідному просторі імен уже повинен існувати дійсний ReferenceGrant:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-ns1-pvc
namespace: default
spec:
from:
- group: ""
kind: PersistentVolumeClaim
namespace: ns1
to:
- group: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: new-snapshot-demo
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: ns1
spec:
storageClassName: example
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
dataSourceRef:
apiGroup: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: new-snapshot-demo
namespace: default
volumeMode: Filesystem
Що далі
- Дізнайтеся про постійні томи.
- Дізнайтеся про клонування томів CSI.
- Дізнайтеся про знімки томів.
- Прочитайте про функціональні можливості, згадані на цій сторінці.
12 - Місткість сховища
Місткість сховища обмежена і може відрізнятися залежно від вузла, на якому працює Pod: мережеве сховище може бути доступним не всім вузлам, а сховище може бути локальним для вузла від самого початку.
На цій сторінці описано, як Kubernetes відстежує місткість сховища та як планувальник використовує цю інформацію, щоб планувати Podʼи на вузли, які мають доступ до достатньої місткості сховища для томів, яких ще бракує. Без відстеження місткості сховища планувальник може вибрати вузол, який не має достатньо місткості для надання тому, і знадобиться кілька повторних спроб планування.
Перш ніж ви розпочнете
Kubernetes v1.37 містить підтримку API на рівні кластера для відстеження місткості сховища. Щоб скористатися нею, ви також повинні використовувати драйвер CSI, який підтримує відстеження місткості. Зверніться до документації драйверів CSI, які ви використовуєте, щоб дізнатися, чи доступна ця підтримка і, якщо так, як її використовувати. Якщо ви не використовуєте Kubernetes v1.37, перегляньте документацію для своєї версії Kubernetes.
API
Для цієї можливості існує два розширення API:
- Обʼєкти CSIStorageCapacity: їх створює драйвер CSI у просторі імен, де його встановлено. Кожен обʼєкт містить інформацію про місткість для одного класу сховища і визначає, які вузли мають доступ до цього сховища.
- Поле
CSIDriverSpec.StorageCapacity: якщо встановлено значенняtrue, планувальник Kubernetes враховуватиме місткість сховища для томів, які використовують драйвер CSI.
Планування
Планувальник Kubernetes використовує інформацію про місткість сховища, якщо:
- Pod використовує том, який ще не створено,
- цей том використовує StorageClass, який посилається на драйвер CSI та використовує режим привʼязки тому
WaitForFirstConsumer, і - обʼєкт
CSIDriverдля цього драйвера маєStorageCapacityзі значенням true.
У цьому випадку планувальник розглядає для Podʼа лише ті вузли, яким доступно достатньо сховища. Ця перевірка дуже спрощена і лише порівнює розмір тому з місткістю, вказаною в обʼєктах CSIStorageCapacity з топологією, що включає цей вузол.
Для томів із режимом привʼязки Immediate драйвер сховища вирішує, де створити том, незалежно від Podʼів, які використовуватимуть цей том. Потім планувальник планує Podʼи на вузли, де том доступний після його створення.
Для ефемерних томів CSI планування завжди відбувається без урахування місткості сховища. Це ґрунтується на припущенні, що цей тип тому використовують лише спеціальні драйвери CSI, які є локальними для вузла й не потребують там значних ресурсів.
Перепланування
Коли вузол вибрано для Podʼа з томами WaitForFirstConsumer, це рішення все ще є попереднім. Наступним кроком драйверу сховища CSI надсилається запит створити том із підказкою, що том має бути доступний на вибраному вузлі.
Оскільки Kubernetes міг вибрати вузол на підставі застарілої інформації про місткість, може статися, що том не вдасться створити. Тоді вибір вузла скидається, і планувальник Kubernetes знову намагається знайти вузол для Podʼа.
Обмеження
Відстеження місткості сховища збільшує ймовірність того, що планування спрацює з першої спроби, але не може цього гарантувати, оскільки планувальник має приймати рішення на підставі потенційно застарілої інформації. Зазвичай збої планування обробляє той самий механізм повторних спроб, що й для планування без інформації про місткість сховища.
Одна із ситуацій, коли планування може остаточно зазнати невдачі, — коли Pod використовує кілька томів: один том уже може бути створений у сегменті топології, де потім бракує місткості для іншого тому. Щоб це виправити, потрібне ручне втручання, наприклад, збільшення місткості або видалення вже створеного тому.
Що далі
- Докладніше про архітектуру читайте в Storage Capacity Constraints for Pod Scheduling KEP.
13 - Обмеження томів на вузлі
На цій сторінці описано максимальну кількість томів, які можна підʼєднати до вузла, для різних хмарних провайдерів.
Хмарні провайдери, такі як Google, Amazon і Microsoft, зазвичай обмежують кількість томів, які можна підʼєднати до вузла. Важливо, щоб Kubernetes дотримувався цих обмежень. Інакше Podʼи, заплановані на вузол, можуть застрягти в очікуванні підʼєднання томів.
Стандартні обмеження Kubernetes
Планувальник Kubernetes має стандартні обмеження на кількість томів, які можна підʼєднати до вузла:
| Хмарний сервіс | Максимальна кількість томів на вузол |
|---|---|
| Amazon Elastic Block Store (EBS) | 39 |
| Google Persistent Disk | 16 |
| Microsoft Azure Disk Storage | 16 |
Обмеження динамічних томів
Обмеження динамічних томів підтримуються для таких типів томів.
- Amazon EBS
- Google Persistent Disk
- Azure Disk
- CSI
Для томів, керованих вбудованими втулками томів, Kubernetes автоматично визначає тип вузла і застосовує відповідну максимальну кількість томів для вузла. Наприклад:
У Google Compute Engine до вузла можна підʼєднати до 127 томів, залежно від типу вузла.
Для дисків Amazon EBS на типах екземплярів M5,C5,R5,T3 та Z1D Kubernetes дозволяє підʼєднувати до вузла лише 25 томів. Для інших типів екземплярів в Amazon Elastic Compute Cloud (EC2) Kubernetes дозволяє підʼєднувати до вузла 39 томів.
В Azure до вузла можна підʼєднати до 64 дисків, залежно від типу вузла. Докладніше дивіться Sizes for virtual machines in Azure.
Якщо драйвер сховища CSI оголошує максимальну кількість томів для вузла (за допомогою
NodeGetInfo), kube-scheduler дотримується цього обмеження. Докладніше дивіться в специфікаціях CSI.Для томів, керованих вбудованими втулками, які було перенесено на драйвер CSI, максимальною кількістю томів буде та, про яку повідомляє драйвер CSI.
Mutable CSI Node Allocatable Count
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.36. It was first available in the v1.33 release.
Драйвери CSI можуть динамічно змінювати максимальну кількість томів, які можна підʼєднати до вузла, під час роботи. Це підвищує точність планування та зменшує кількість збоїв планування Podʼів через зміни в доступності ресурсів.
Щоб скористатися цією можливістю, ви повинні ввімкнути функціональну можливість MutableCSINodeAllocatableCount у таких компонентах:
kube-apiserverkubelet
Періодичні оновлення
Якщо цю можливість увімкнено, драйвери CSI можуть запитувати періодичні оновлення своїх обмежень томів, встановивши поле nodeAllocatableUpdatePeriodSeconds у специфікації CSIDriver. Наприклад:
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: hostpath.csi.k8s.io
spec:
nodeAllocatableUpdatePeriodSeconds: 60
kubelet періодично викликатиме точку доступу NodeGetInfo відповідного драйвера CSI, щоб оновити максимальну кількість томів, які можна підʼєднати, використовуючи інтервал, вказаний у полі nodeAllocatableUpdatePeriodSeconds. Мінімально допустиме значення цього поля — 10 секунд.
Якщо операція підʼєднання тому завершується помилкою ResourceExhausted (код gRPC 8), Kubernetes негайно оновлює кількість доступних для розподілу томів цього вузла. Крім того, kubelet позначає уражені Podʼи як Failed, що дозволяє їхнім контролерам обробити повторне створення. Це запобігає безстроковому застряганню Podʼів у стані ContainerCreating.
Запобігання розміщенню Podʼа без драйвера CSI
Функціональна можливість VolumeLimitScaling стандартно ввімкнена в Kubernetes v1.37.
Однак запобігання розміщенню Podʼів на вузлах без драйвера CSI вимагає явної згоди через поле spec.preventPodSchedulingIfMissing обʼєкта CSIDriver.
Поле preventPodSchedulingIfMissing стандартно має значення false, і його потрібно встановити в true, якщо ви не хочете, щоб Podʼи планувалися на вузлах без драйвера CSI. Стандартне значення false вибрано з міркувань зворотної сумісності та сумісності з Cluster AutoScaler, який може не враховувати обмеження томів CSI під час автомасштабування (дивіться розділ нижче).
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: hostpath.csi.k8s.io
spec:
preventPodSchedulingIfMissing: true
Обмеження підʼєднання томів CSI та cluster autoscaler
Cluster autoscaler може враховувати обмеження томів CSI, коли встановлено --enable-csi-node-aware-scheduling=true. Цей параметр не залежить від функціональної можливості VolumeLimitScaling.
Якщо ви використовуєте cluster autoscaler, встановлюйте spec.preventPodSchedulingIfMissing у true лише тоді, коли cluster autoscaler налаштовано з --enable-csi-node-aware-scheduling=true. Інакше його симуляції планування не включатимуть потрібну інформацію CSINode для нових вузлів, і cluster autoscaler може не масштабуватися вгору для Podʼів в очікуванні, які використовують томи CSI.
14 - Локальне тимчасове сховище
Вузли мають локальне тимчасове сховище, яке підтримується локально підключеними пристроями з можливістю запису або, інколи, оперативною памʼяттю. «Тимчасове» означає, що немає довгострокової гарантії щодо довговічності.
Podʼи використовують тимчасове локальне сховище як робочий простір, для кешування та для логів. kubelet може надавати Podʼам робочий простір, використовуючи локальне тимчасове сховище для монтування томів emptyDir у контейнери.
kubelet також використовує цей тип сховища для зберігання логів контейнерів на рівні вузла, образів контейнерів і шарів запущених контейнерів, доступних для запису.
Увага:
Якщо вузол виходить з ладу, дані в його тимчасовому сховищі можуть бути втрачені. Ваші застосунки не можуть очікувати жодних SLA щодо продуктивності (наприклад, дискових IOPS) від локального тимчасового сховища.Примітка:
Щоб квота ресурсів працювала для ephemeral-storage, потрібно виконати дві дії:
- Адміністратор встановлює квоту ресурсів для ephemeral-storage в просторі імен.
- Користувач повинен вказати обмеження для ресурсу ephemeral-storage у специфікації Podʼа.
Якщо користувач не вказав обмеження ресурсу ephemeral-storage у специфікації Podʼа, квота ресурсів не застосовується до ephemeral-storage.
Kubernetes дозволяє відстежувати, резервувати та обмежувати обсяг тимчасового локального сховища, яке може використовувати Pod.
Конфігурації для локального тимчасового сховища
Kubernetes підтримує такі способи налаштування локального тимчасового сховища на вузлі:
У цій конфігурації ви розміщуєте всі різні типи тимчасових локальних даних (томи emptyDir, шари, доступні для запису, образи контейнерів, логи) в одній файловій системі.
kubelet також записує логи контейнерів на рівні вузла і обробляє їх аналогічно тимчасовому локальному сховищу.
kubelet записує логи у файли всередині налаштованої теки логів (стандартно /var/log) і має базову теку для інших локально збережених даних (стандартно /var/lib/kubelet).
Зазвичай і /var/lib/kubelet, і /var/log розташовані в кореневій файловій системі, і kubelet розроблено з урахуванням такого розташування.
Ваш вузол може мати скільки завгодно інших файлових систем, які не використовуються для Kubernetes.
Ви використовуєте на вузлі одну файлову систему для тимчасових даних запущених Podʼів, таких як логи та томи emptyDir. Цю файлову систему також можна використовувати для інших даних, наприклад, для системних логів, не повʼязаних із Kubernetes; вона може бути навіть кореневою файловою системою.
kubelet також записує логи контейнерів на рівні вузла у першу файлову систему і обробляє їх аналогічно тимчасовому локальному сховищу.
Ви також використовуєте окрему файлову систему на іншому логічному пристрої зберігання. У цій конфігурації середовище виконання контейнерів зберігає і шари образів контейнерів, і шари, доступні для запису, у цій другій файловій системі. Налаштуйте це місце зберігання в середовищі виконання контейнерів, а не в kubelet.
Перша файлова система не містить жодних шарів образів або шарів, доступних для запису.
Ваш вузол може мати скільки завгодно інших файлових систем, які не використовуються для Kubernetes.
У цій конфігурації шари образів контейнерів розташовані в окремій файловій системі, а шари контейнерів, доступні для запису, — у тій самій файловій системі, що й тимчасові дані kubelet, такі як логи та томи emptyDir.
Ця конфігурація вимагає підтримки сигналів виселення containerfs. Докладніше про функціональну можливість і середовища виконання контейнерів, які підтримують цю конфігурацію, дивіться у виселенні внаслідок тиску на вузол.
На сторінці Виселення внаслідок тиску на вузол ці файлові системи, за якими ведеться спостереження, позначаються як nodefs, imagefs та containerfs. Ці назви не завжди означають окремі точки монтування.
kubelet може вимірювати використання локального сховища, якщо ви налаштовуєте вузол за однією з підтримуваних конфігурацій локального тимчасового сховища.
Якщо у вас інша конфігурація, kubelet не застосовує обмеження ресурсів для тимчасового локального сховища.
Примітка:
kubelet відстежує томиemptyDir типу tmpfs як використання памʼяті контейнера, а не як локальне тимчасове сховище.Примітка:
kubelet може відстежувати тимчасове сховище лише у файлових системах, які він спостерігає через підтримувані схеми розташування. Якщо ви монтуєте додаткові файлові системи за такими шляхами, як/var/lib/kubelet, /var/log або тека сховища середовища виконання контейнерів, поза цими схемами, kubelet може неправильно повідомляти про тимчасове сховище.Встановлення запитів та обмежень для локального тимчасового сховища
Ви можете вказати ephemeral-storage для керування локальним тимчасовим сховищем. Кожен контейнер Podʼа може вказати одне або обидва з такого:
spec.containers[].resources.limits.ephemeral-storagespec.containers[].resources.requests.ephemeral-storage
Обмеження та запити для ephemeral-storage вимірюються в байтах. Ви можете виразити обсяг сховища як просте ціле число або як число з фіксованою комою, використовуючи один із таких суфіксів: E, P, T, G, M, k. Ви також можете використовувати еквіваленти степеня двійки: Ei, Pi, Ti, Gi, Mi, Ki. Наприклад, усі наведені нижче величини мають приблизно однакове значення:
128974848129e6129M123Mi
Зверніть увагу на регістр суфіксів. Якщо ви запитуєте 400m тимчасового сховища, це запит на 0,4 байта. Той, хто це ввів, мабуть, мав на увазі 400 мебібайтів (400Mi) або 400 мегабайтів (400M).
У наведеному нижче прикладі Pod має два контейнери. Кожен контейнер має запит на 2GiB локального тимчасового сховища. Кожен контейнер має обмеження в 4GiB локального тимчасового сховища. Отже, Pod має запит на 4GiB локального тимчасового сховища та обмеження у 8GiB локального тимчасового сховища. 500Mi цього обмеження може використати том emptyDir.
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
volumeMounts:
- name: ephemeral
mountPath: "/tmp"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
volumeMounts:
- name: ephemeral
mountPath: "/tmp"
volumes:
- name: ephemeral
emptyDir:
sizeLimit: 500Mi
Як плануються Podʼи із запитами ephemeral-storage
Коли ви створюєте Pod, планувальник Kubernetes вибирає вузол, на якому працюватиме Pod. Кожен вузол має максимальний обсяг локального тимчасового сховища, який він може надати для Podʼів. Докладнішу інформацію дивіться в розділі Node Allocatable.
Планувальник гарантує, що сума запитів на ресурси запланованих контейнерів буде меншою за місткість вузла.
Керування споживанням тимчасового сховища
Якщо kubelet керує локальним тимчасовим сховищем як ресурсом, то kubelet вимірює використання сховища в:
- томах
emptyDir, за винятком томів tmpfsemptyDir - теках, що містять логи на рівні вузла
- шарах контейнерів, доступних для запису
Якщо Pod використовує більше тимчасового сховища, ніж ви дозволяєте, kubelet встановлює сигнал виселення, який запускає виселення Podʼа.
Для ізоляції на рівні контейнера, якщо використання шару контейнера, доступного для запису, та логів перевищує його обмеження сховища, kubelet позначає Pod для виселення.
Для ізоляції на рівні Podʼа kubelet обчислює загальне обмеження сховища Podʼа, підсумовуючи обмеження контейнерів цього Podʼа. У цьому випадку, якщо сума використання локального тимчасового сховища всіма контейнерами, а також томами emptyDir Podʼа перевищує загальне обмеження сховища Podʼа, kubelet також позначає Pod для виселення.
Увага:
Якщо kubelet не вимірює локальне тимчасове сховище, то Pod, який перевищує своє обмеження локального сховища, не буде виселений за порушення обмежень ресурсів локального сховища.
Однак, якщо місця у файловій системі для шарів контейнерів, доступних для запису, логів на рівні вузла або томів emptyDir стає мало, вузол позначає себе taint про нестачу локального сховища, і цей taint запускає виселення всіх Podʼів, які спеціально не толерують цей taint.
Дивіться підтримувані конфігурації для тимчасового локального сховища.
kubelet підтримує різні способи вимірювання використання сховища Podʼа:
kubelet виконує регулярні заплановані перевірки, які сканують кожен том emptyDir, теку логів контейнера та шар контейнера, доступний для запису.
Сканування вимірює, скільки місця використовується.
Примітка:
У цьому режимі kubelet не відстежує відкриті дескриптори видалених файлів.
Якщо ви (або контейнер) створюєте файл у томі emptyDir, щось потім відкриває цей файл, а ви видаляєте файл, поки він ще відкритий, то inode видаленого файлу залишається, доки ви не закриєте цей файл, але kubelet не вважає це місце використаним.
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the LocalStorageCapacityIsolationFSQuotaMonitoring feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Квоти проєктів — це можливість на рівні операційної системи для керування використанням сховища у файлових системах. У Kubernetes ви можете ввімкнути квоти проєктів для моніторингу використання сховища. Переконайтеся, що файлова система, на якій розміщено томи emptyDir на вузлі, підтримує квоти проєктів. Наприклад, XFS та ext4fs пропонують квоти проєктів.
Примітка:
Квоти проєктів дозволяють моніторити використання сховища; вони не застосовують обмеження.Kubernetes використовує ідентифікатори проєктів, починаючи з 1048576. Використовувані ідентифікатори зареєстровані в /etc/projects та /etc/projid. Якщо ідентифікатори проєктів у цьому діапазоні використовуються в системі для інших цілей, їх необхідно зареєструвати в /etc/projects та /etc/projid, щоб Kubernetes не використовував їх.
Квоти є швидшими та точнішими, ніж сканування тек. Коли тека призначається проєкту, всі файли, створені в цій теці, створюються в цьому проєкті, і ядро має лише відстежувати, скільки блоків використовується файлами в цьому проєкті. Якщо файл створено та видалено, але він має відкритий дескриптор файлу, він продовжує споживати простір. Відстеження квот точно фіксує цей простір, тоді як сканування тек пропускає простір, який використовують видалені файли.
Щоб використовувати квоти для відстеження використання ресурсів Podʼом, Pod повинен бути в просторі імен користувача. У просторах імен користувачів ядро обмежує зміни projectID у файловій системі, забезпечуючи надійність метрик сховища, обчислених за допомогою квот.
Якщо ви хочете використовувати квоти проєктів, вам слід:
Увімкнути функціональну можливість
LocalStorageCapacityIsolationFSQuotaMonitoring=trueза допомогою поляfeatureGatesу конфігурації kubelet.Переконатися, що функціональну можливість
UserNamespacesSupportувімкнено, а ядро, реалізація CRI та середовище виконання OCI підтримують простори імен користувачів.Переконатися, що в кореневій файловій системі (або необовʼязковій файловій системі середовища виконання) увімкнено квоти проєктів. Усі файлові системи XFS підтримують квоти проєктів. Для файлових систем ext4 потрібно ввімкнути можливість відстеження квот проєктів, поки файлова система не змонтована.
# For ext4, with /dev/block-device not mounted sudo tune2fs -O project -Q prjquota /dev/block-deviceПереконатися, що коренева файлова система (або необовʼязкова файлова система середовища виконання) змонтована з увімкненими квотами проєктів. Для XFS і ext4fs параметр монтування називається
prjquota.
Якщо ви не хочете використовувати квоти проєктів, вам слід:
- Вимкнути функціональну можливість
LocalStorageCapacityIsolationFSQuotaMonitoringза допомогою поляfeatureGatesу конфігурації kubelet.
Що далі
- Прочитайте про квоти проєктів у XFS.
15 - Моніторинг справності томів
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the CSIVolumeHealth feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Моніторинг справності томів CSI дозволяє драйверу CSI повідомляти Kubernetes про проблеми зі справністю тому або бекенду його сховища безпосередньо. Драйвер звітує через RPC CSI, а Kubernetes показує ці звіти у трьох полях статусу: PersistentVolumeClaim .status.healthStatus, Pod .status.volumeHealth та CSINode .status.storageHealth. Автоматизація може стежити за цими стійкими полями статусу, а не відтворювати справність томів з ефемерних Events чи зі специфічних для постачальника dashboards.
Примітка:
Функціональна можливістьCSIVolumeHealth існує з Kubernetes v1.21, але механізм, описаний на цій сторінці, є переробкою, яка замінює початкову альфа-реалізацію. Що змінилося, дивіться в розділі Обмеження.Як це працює
Специфікація CSI визначає чотири RPC для звітування про справність:
- На втулку контролера CSI:
ControllerListVolumeHealthтаControllerGetVolumeHealth, для справності кожного тому, яку спостерігає контролер. - На втулку вузла CSI:
NodeGetVolumeHealth, для справності кожного тому, яку спостерігає вузол, таNodeGetStorageHealth, для справності бекенду сховища, як її видно з цього вузла.
Драйверу потрібно реалізувати лише ті RPC, які він хоче підтримувати, і оголосити їхню підтримку через можливості втулка CSI. Драйвер, який не реалізує жодного з цих RPC, ніколи не опитується, і звітування для нього залишається неактивним. Драйвер, який оголошує можливість контролера LIST_VOLUME_HEALTH, також повинен оголосити GET_VOLUME_HEALTH; цю вимогу забезпечує sidecar-контейнер csi-external-health-monitor-controller.
Кожен звіт про справність містить status із невеликого набору значень, придатних для машинного аналізу, разом із визначеним драйвером reason та необовʼязковим зрозумілим людині message:
- Значення статусу на рівні тому (використовуються для
PersistentVolumeClaim.status.healthStatusтаPod.status.volumeHealth):Inaccessible,DataLoss,Degraded. - Значення статусу бекенду сховища (використовуються для
CSINode.status.storageHealth):StorageUnreachable,StorageDegraded.
Звіти зі сторони вузла та зі сторони контролера незалежні: том може бути Inaccessible з одного вузла, який втратив шлях до даних бекенду, тоді як втулок контролера все ще повідомляє, що том справний, і навпаки.
Справність, про яку повідомляється в Podʼах
Для томів, які використовують драйвер CSI з підтримкою RPC NodeGetVolumeHealth зі сторони вузла, kubelet періодично викликає цей RPC для кожного тому CSI, який він змонтував для Podʼа, і записує результат у pod.status.volumeHealth, використовуючи як ключ назву тому з pod.spec.volumes. Інтервал опитування — це налаштування kubelet volumeStatsAggPeriod (прапорець командного рядка --volume-stats-agg-period).
apiVersion: v1
kind: Pod
# ...
status:
volumeHealth:
- name: my-volume
healthConditions:
- status: Inaccessible
reason: VolumeNotFound
message: "volume not found on the storage backend"
lastTransitionTime: "2026-07-20T12:00:00Z"
kubelet записує лише pods/status, субресурс, який він уже має право оновлювати для Podʼів, привʼязаних до його власного вузла, тому для цього поля не потрібна нова авторизація.
Справність, про яку повідомляється в CSINode
Для кожного зареєстрованого на вузлі драйвера CSI, який підтримує NodeGetStorageHealth, kubelet періодично викликає цей RPC і записує результат у csinode.status.storageHealth, використовуючи як ключ назву драйвера.
apiVersion: storage.k8s.io/v1
kind: CSINode
# ...
status:
storageHealth:
- name: csi.example.com
healthConditions:
- status: StorageUnreachable
reason: NetworkPartition
message: "data path to the storage backend is unreachable from this node"
Запис StorageHealthCondition може за потреби обмежувати свою дію конкретним accessMode або volumeMode для бекендів, які деградують асиметрично (наприклад, мережева проблема, яка впливає на доступ ReadWriteMany, але не на ReadWriteOnce).
Запис у csinodes/status — це нова можливість, додана цією функціональністю: режим авторизації Node та втулок допуску NodeRestriction дозволяють kubelet змінювати лише обʼєкт CSINode, який відповідає його власному вузлу, і лише поки ввімкнено функціональну можливість CSIVolumeHealth.
Справність, про яку повідомляється в PersistentVolumeClaims
Справність томів, яку спостерігає контролер, записує в persistentvolumeclaim.status.healthStatus sidecar-контейнер csi-external-health-monitor-controller, що працює поряд із втулком контролера драйвера CSI. Sidecar-контейнер викликає ControllerListVolumeHealth (або переходить на ControllerGetVolumeHealth для кожного тому) і записує результат:
apiVersion: v1
kind: PersistentVolumeClaim
# ...
status:
healthStatus:
healthConditions:
- status: Inaccessible
reason: VolumeNotFound
message: "volume not found on the storage backend"
lastTransitionTime: "2026-07-20T12:00:00Z"
Жоден вузол ніколи не записує це поле; це робить лише sidecar-контейнер, що працює в панелі управління. Це не дає скомпрометованому або несправному вузлу впливати на те, що інші користувачі кластера бачать у PVC.
Чи доступний цей шлях для конкретного драйвера, залежить від того, чи цей драйвер і його розгортання sidecar-контейнера csi-external-health-monitor-controller перейшли на нові RPC контролера.
Увімкнення моніторингу справності томів
Моніторингом справності томів керує одна функціональна можливість CSIVolumeHealth на kube-apiserver та kubelet:
- На
kube-apiserverувімкнення функціональної можливості дозволяє записувати та читати нові поля статусу; вимкнення вилучає ці поля під час наступного запису в обʼєкт, але зберігає вже збережені значення. - На kubelet увімкнення функціональної можливості запускає періодичне опитування зі сторони вузла, описане вище.
Моніторинг зі сторони контролера, який заповнює persistentvolumeclaim.status.healthStatus, не має власної функціональної можливості. Розгортання sidecar-контейнера csi-external-health-monitor-controller поряд із втулком контролера вашого драйвера CSI саме по собі є ввімкненням цього моніторингу.
Увімкнення функціональної можливості саме по собі не призводить до появи інформації про справність: драйвер CSI також повинен оголосити та реалізувати відповідні RPC. Перегляньте документацію свого драйвера CSI, щоб дізнатися, які з чотирьох RPC він підтримує, якщо підтримує.
Моніторинг
kubelet надає метрику типу gauge csi_node_storage_health_status з мітками driver_name, status та reason і значенням 1 для кожного стану бекенду сховища, про який наразі повідомляється для драйвера на цьому вузлі.
Обмеження
- Kubernetes лише показує ці звіти про справність, але не діє на їх основі. Ніщо в Kubernetes не переплановує Podʼи, не перемикає томи на резерв і не реагує якось інакше на повідомлений стан самостійно. Створення контролера виправлення на основі цих полів статусу залишається за операторами кластерів і постачальниками.
- Старіша альфа-реалізація тієї самої функціональної можливості
CSIVolumeHealth(доступна з Kubernetes v1.21) повідомляла про ненормальні стани томів за допомогою Events Kubernetes та метрикиkubelet_volume_stats_health_status_abnormal. Цей механізм замінено полями статусу та RPC, описаними на цій сторінці, і його більше не існує.
Що далі
- Прочитайте KEP-1432, щоб ознайомитися з повним дизайном.
- Дивіться документацію драйверів CSI, щоб дізнатися, які драйвери CSI реалізують моніторинг справності томів.
16 - Сховище у Windows
На цій сторінці наведено огляд сховища, специфічного для операційної системи Windows.
Постійне сховище
У Windows є багатошаровий драйвер файлової системи для монтування шарів контейнера та створення копії файлової системи на основі NTFS. Усі шляхи файлів у контейнері розвʼязуються лише в контексті цього контейнера.
- У Docker монтування томів може бути спрямоване лише на теку в контейнері, а не на окремий файл. Це обмеження не стосується containerd.
- Монтування томів не може проєктувати файли або теки назад на файлову систему хоста.
- Файлові системи лише для читання не підтримуються, оскільки завжди потрібен доступ для запису до реєстру Windows та бази даних SAM. Однак томи лише для читання підтримуються.
- Маски користувача та дозволи для томів недоступні. Оскільки SAM не є спільним для хоста й контейнера, між ними немає зіставлення. Усі дозволи розвʼязуються в контексті контейнера.
Як наслідок, на вузлах Windows не підтримуються такі можливості сховища:
- Монтування підшляхів тому: у контейнері Windows можна змонтувати лише весь том
- Монтування підшляхів тому для Secrets
- Проєкція монтування хоста
- Коренева файлова система лише для читання (зіставлені томи все ще підтримують
readOnly) - Зіставлення блокових пристроїв
- Памʼять як носій сховища (наприклад,
emptyDir.mediumзі значеннямMemory) - Можливості файлової системи, такі як uid/gid; дозволи файлової системи Linux для кожного користувача
- Встановлення дозволів Secret за допомогою DefaultMode (через залежність від UID/GID)
- Підтримка сховища/томів на основі NFS
- Розширення змонтованого тому (resizefs)
Томи Kubernetes дозволяють розгортати в Kubernetes складні застосунки, яким потрібне збереження даних і спільне використання томів Podʼами. Керування постійними томами, повʼязаними з конкретним бекендом сховища або протоколом, включає такі дії, як надання, скасування надання та зміна розміру томів, підʼєднання тому до вузла Kubernetes і відʼєднання від нього, а також монтування тому в окремих контейнерах Podʼа, якому потрібно зберігати дані, і його розмонтування.
Компоненти керування томами постачаються як втулки томів Kubernetes. У Windows підтримуються такі широкі класи втулків томів Kubernetes:
- Втулки FlexVolume
- Зверніть увагу, що FlexVolumes застаріли з версії 1.23
- Втулки CSI
Вбудовані втулки томів
Наведені нижче вбудовані втулки підтримують постійне сховище на вузлах Windows: