Ефемерні томи із відстеженням ємності сховища: EmptyDir на стероїдах

Ефемерні томи із відстеженням ємності сховища: EmptyDir на стероїдах

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

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

У Kubernetes вже є кілька типів ефемерних томівАле їх функціональність обмежена тим, що реалізовано в K8s.

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

Це може стати проблемою для томів із значним споживанням ресурсів вузла або сховища, доступного лише на деяких вузлах. Тому в Kubernetes 1.19 представлені дві нові функції томів для альфа-тестування, які концептуально схожі на томи EmptyDir:

  • ефемерні томи загального призначення;

  • відстеження ємності сховища CSI.

Переваги нового підходу:

  • сховище може бути локальним або підключається по мережі;

  • томи можуть мати заданий розмір, який може бути перевищений додатком;

  • працює з будь-якими драйверами CSI, які підтримують надання постійних томів і (для підтримки відстеження ємності) реалізують виклик GetCapacity;

  • томи можуть мати деякі початкові дані, що залежать від драйвера та параметрів;

  • всі типові операції з томом (створення знімка стану, зміна розміру тощо) підтримуються;

  • томи можна використовувати з будь-яким контролером додатків, які приймають специфікацію модуля чи тома;

  • Планувальник Kubernetes сам вибирає відповідні вузли, тому більше не потрібно забезпечувати та налаштовувати розширення планувальника та змінювати webhooks.

варіанти застосування

Таким чином, ефемерні томи загального призначення підходять для наступних варіантів застосування:

Постійна пам'ять як заміна оперативної пам'яті для memcached

Останні випуски memcached додали підтримку використання постійної пам'яті (Intel Optane тощо, прим. перекладача) замість звичайної оперативної пам'яті. При розгортанні memcached через контролер додатків можна за допомогою ефемерних томів загального призначення зробити запит на виділення тома заданого розміру з PMEM за допомогою драйвера CSI, наприклад PMEM-CSI.

Локальне сховище LVM як робочий простір

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

Доступ лише для читання для томів з даними

Виділення тома може призвести до створення заповненого тома за умови:

Ці томи можуть бути змонтовані лише для читання.

Як це працює

Ефемерні томи загального призначення

Ключовою особливістю ефемерних томів загального призначення є нове джерело тому, EphemeralVolumeSourceмістить всі поля для створення запиту до того (історично це називається запит на постійний том, PVC). Новий контролер у kube-controller-manager переглядає поди, що створюють таке джерело тому, а потім створює PVC для цих подів. Для драйвера CSI цей запит виглядає так само, як і інші, тому тут не потрібно особливої ​​підтримки.

Поки що такі PVC існують — можуть використовуватися, як і будь-які інші запити на те. Зокрема, вони можуть бути посиланням як джерело даних під час копіювання тома або створення знімка з тома. PVC-об'єкт також містить поточний стан тома.

Імена автоматично створюваних PVC зумовлені: це комбінація імені пода та імені тома, розділених між собою дефісом. Обумовленість імен спрощує взаємодію з PVC, оскільки його не треба шукати, якщо відомо ім'я пода та ім'я тома. Недоліком є ​​те, що ім'я може бути використано, що виявляється Kubernetes і в результаті запуск пода блокується.

Щоб бути впевненим у тому, що том видаляється разом із подом, контролер робить під власником запиту у тому. Коли під видаляється - відпрацьовує штатний механізм прибирання сміття, який видаляє як запит, так і тому.

Запитам ставиться у відповідність драйвер сховища через звичайний механізм класу сховища. Хоча класи з негайним і пізнім зв'язуванням (вони ж WaitForFirstConsumer) підтримуються, для ефемерних томів має сенс використовувати WaitForFirstConsumerтоді планувальник може врахувати як використання вузла, так і доступність сховища при виборі вузла. Тут з'являється нова функція.

Відстеження ємності сховища

Зазвичай планувальник не має даних про те, де драйвер CSI створить том. Також планувальник не має можливості зв'язатися з драйвером безпосередньо для запиту цієї інформації. Тому планувальник опитує вузли доти, доки знайде той, у якому томи може бути доступними (пізнє зв'язування), або повністю залишить вибір місця за драйвером (негайне зв'язування).

Новий API CSIStorageCapacity, що знаходиться в стадії alpha, дозволяє зберігати потрібні дані в etcd, так що вони доступні планувальнику. На відміну від підтримки ефемерних томів загального призначення під час розгортання драйвера потрібно включити відстеження ємності сховища: external-provisioner повинен опублікувати інформацію про ємність, що отримується від драйвера через звичайний GetCapacity.

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

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

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

NB Більш детальну інформацію ви зможете отримати, а також безпечно «потренуватися на кішках стенді», а у разі зовсім незрозумілої ситуації отримати кваліфіковану допомогу техпідтримки на інтенсивних умовах. Kubernetes База пройде 28-30 вересня, а для більш розвинених фахівців Kubernetes Мега 14–16 жовтня.

Безпека

CSIStorageCapacity

Об'єкти CSIStorageCapacity знаходяться у просторах імен, при розкочуванні кожного драйвера CSI у своєму просторі імен рекомендується обмежити права RBAC для CSIStorageCapacity у цьому просторі, оскільки очевидно, звідки надходять дані. У будь-якому випадку Kubernetes не перевіряє це, а зазвичай драйвери ставляться в одному просторі імен, так що зрештою очікується, що драйвера будуть працювати і не будуть публікувати невірні дані (і тут мені картка поперла, прим. перекладача за мотивами бородатого анекдоту)

Ефемерні томи загального призначення

Якщо користувачі мають права на створення пода (прямо чи опосередковано) — вони також зможуть створити ефемерні томи загального призначення навіть якщо вони не мають прав на створення запиту на тому. А все тому, що перевірки прав RBAC застосовуються до контролера, який створює PVC, а не користувача. Це основна зміна, яку потрібно додати до облікового запису, перед включенням цієї функції до кластерів, якщо ненадійні користувачі не повинні мати права на створення томів.

Приклад

Окрема гілка в PMEM-CSI містить всі необхідні зміни для запуску кластера Kubernetes 1.19 всередині віртуальних машин QEMU з усіма функціями, що знаходяться на стадії alpha. Код драйвера не змінювався, змінилося лише розгортання.

На підходящій машині (Linux, звичайний користувач може використовувати Docker, дивіться тут деталі) ці команди піднімуть кластер і встановлять драйвер PMEM-CSI:

git clone --branch=kubernetes-1-19-blog-post https://github.com/intel/pmem-csi.git
cd pmem-csi
export TEST_KUBERNETES_VERSION=1.19 TEST_FEATURE_GATES=CSIStorageCapacity=true,GenericEphemeralVolume=true TEST_PMEM_REGISTRY=intel
make start && echo && test/setup-deployment.sh

Після того, як все відпрацює, висновок міститиме інструкції для використання:

The test cluster is ready. Log in with [...]/pmem-csi/_work/pmem-govm/ssh.0, run
kubectl once logged in.  Alternatively, use kubectl directly with the
following env variable:
   KUBECONFIG=[...]/pmem-csi/_work/pmem-govm/kube.config

secret/pmem-csi-registry-secrets created
secret/pmem-csi-node-secrets created
serviceaccount/pmem-csi-controller created
...
To try out the pmem-csi driver ephemeral volumes:
   cat deploy/kubernetes-1.19/pmem-app-ephemeral.yaml |
   [...]/pmem-csi/_work/pmem-govm/ssh.0 kubectl create -f -

Об'єкти CSIStorageCapacity не мають на увазі читання людьми, так що треба деяка обробка. За допомогою фільтрів шаблону на Golang будуть показані класи сховищ, у цьому прикладі будуть відображені ім'я, топологія та ємність:

$ kubectl get 
        -o go-template='{{range .items}}{{if eq .storageClassName "pmem-csi-sc-late-binding"}}{{.metadata.name}} {{.nodeTopology.matchLabels}} {{.capacity}}
{{end}}{{end}}' 
        csistoragecapacities
csisc-2js6n map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker2] 30716Mi
csisc-sqdnt map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker1] 30716Mi
csisc-ws4bv map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker3] 30716Mi

Окремий об'єкт має такий вміст:

$ kubectl describe csistoragecapacities/csisc-6cw8j
Name:         csisc-sqdnt
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  storage.k8s.io/v1alpha1
Capacity:     30716Mi
Kind:         CSIStorageCapacity
Metadata:
  Creation Timestamp:  2020-08-11T15:41:03Z
  Generate Name:       csisc-
  Managed Fields:
    ...
  Owner References:
    API Version:     apps/v1
    Controller:      true
    Kind:            StatefulSet
    Name:            pmem-csi-controller
    UID:             590237f9-1eb4-4208-b37b-5f7eab4597d1
  Resource Version:  2994
  Self Link:         /apis/storage.k8s.io/v1alpha1/namespaces/default/csistoragecapacities/csisc-sqdnt
  UID:               da36215b-3b9d-404a-a4c7-3f1c3502ab13
Node Topology:
  Match Labels:
    pmem-csi.intel.com/node:  pmem-csi-pmem-govm-worker1
Storage Class Name:           pmem-csi-sc-late-binding
Events:                       <none>

Спробуємо створити демонстраційний додаток з одним ефемерним томом загального призначення. Вміст файлу pmem-app-ephemeral.yaml:

# This example Pod definition demonstrates
# how to use generic ephemeral inline volumes
# with a PMEM-CSI storage class.
kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline-volume
spec:
  containers:
    - name: my-frontend
      image: intel/pmem-csi-driver-test:v0.7.14
      command: [ "sleep", "100000" ]
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-volume
  volumes:
  - name: my-csi-volume
    ephemeral:
      volumeClaimTemplate:
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 4Gi
          storageClassName: pmem-csi-sc-late-binding

Після створення, як показано в інструкції вище, у нас з'явився додатковий під і PVC:

$ kubectl get pods/my-csi-app-inline-volume -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP          NODE                         NOMINATED NODE   READINESS GATES
my-csi-app-inline-volume   1/1     Running   0          6m58s   10.36.0.2   pmem-csi-pmem-govm-worker1   <none>           <none>
$ kubectl get pvc/my-csi-app-inline-volume-my-csi-volume
NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE
my-csi-app-inline-volume-my-csi-volume   Bound    pvc-c11eb7ab-a4fa-46fe-b515-b366be908823   4Gi        RWO            pmem-csi-sc-late-binding   9m21s

Власник PVC - під:

$ kubectl get -o yaml pvc/my-csi-app-inline-volume-my-csi-volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: pmem-csi.intel.com
    volume.kubernetes.io/selected-node: pmem-csi-pmem-govm-worker1
  creationTimestamp: "2020-08-11T15:44:57Z"
  finalizers:
  - kubernetes.io/pvc-protection
  managedFields:
    ...
  name: my-csi-app-inline-volume-my-csi-volume
  namespace: default
  ownerReferences:
  - apiVersion: v1
    blockOwnerDeletion: true
    controller: true
    kind: Pod
    name: my-csi-app-inline-volume
    uid: 75c925bf-ca8e-441a-ac67-f190b7a2265f
...

Очікувано оновилася інформація для pmem-csi-pmem-govm-worker1:

csisc-2js6n map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker2] 30716Mi
csisc-sqdnt map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker1] 26620Mi
csisc-ws4bv map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker3] 30716Mi

Якщо іншому додатку треба буде більше, ніж 26620Mi, планувальник не буде брати до уваги pmem-csi-pmem-govm-worker1 за будь-якого розкладу.

Що далі?

Обидві функції досі у розробці. Було відкрито кілька заявок під час alpha-тестування. За посиланнями з пропозиціями щодо покращення ведеться документування роботи, яку треба зробити, щоб перейти в стадію beta, а також які альтернативи були вже розглянуті та відхилені:

Джерело: habr.com

Додати коментар або відгук