Efemeryczne woluminy z monitorowaniem pojemności przechowywania: EmptyDir na sterydach

Efemeryczne woluminy z monitorowaniem pojemności przechowywania: EmptyDir na sterydach

Niektóre aplikacje również potrzebują przechowywać dane, ale są na to wystarczająco spokojne, że dane nie będą zachowane po ponownym uruchomieniu.

Na przykład usługi do buforowania są ograniczone pamięcią operacyjną, ale mogą również przenosić dane, które rzadko są używane, do pamięci masowej działającej wolniej niż pamięć operacyjna, co ma niewielki wpływ na ogólną wydajność. Inne aplikacje muszą wiedzieć, że w plikach mogą być niektóre dane tylko do odczytu, na przykład ustawienia lub tajne klucze.

W Kubernetes istnieje już kilka typów ephemericznych woluminów, ale ich funkcjonalność jest ograniczona do tego, co jest zaimplementowane w K8s.

Ephemericzne woluminy CSI umożliwiły rozszerzenie Kubernetes za pomocą sterowników CSI w celu zapewnienia wsparcia dla lekkich lokalnych woluminów. W ten sposób można stosować dowolne struktury: ustawienia, sekrety, dane identyfikacyjne, zmienne i tak dalej. Sterowniki CSI muszą być rozwinięte, aby wspierać tę funkcję Kubernetes, ponieważ zakłada się, że standardowe znormalizowane sterowniki nie będą działać — lecz przewiduje się, że takie woluminy można będzie używać na każdym węźle wybranym dla poda.

Może to stanowić problem dla woluminów znacząco obciążających zasoby węzła lub dla pamięci masowej dostępnej tylko na niektórych węzłach. Dlatego w Kubernetes 1.19 wprowadzono dwie nowe funkcje woluminów do testów alfa, konceptualnie podobne do woluminów EmptyDir:

  • ephemericzne woluminy ogólnego przeznaczenia;

  • śledzenie pojemności pamięci masowej CSI.

Zalety nowego podejścia:

  • pamięć masowa może być lokalna lub podłączona w sieci;

  • woluminy mogą mieć określony rozmiar, którego aplikacja nie może przekroczyć;

  • działa z dowolnymi sterownikami CSI obsługującymi zapewnienie trwałych woluminów i (w celu wsparcia śledzenia pojemności) implementującymi wywołanie GetCapacity;

  • woluminy mogą mieć pewne dane początkowe, zależne od sterownika i parametrów;

  • wszystkie operacje typowe dla woluminu (tworzenie migawki, zmiana rozmiaru itp.) są wspierane;

  • woluminy można używać z dowolnym kontrolerem aplikacji, który akceptuje specyfikację modułu lub woluminu;

  • Planista Kubernetes sam wybiera odpowiednie węzły, więc nie trzeba już zapewniać ani konfigurować rozszerzeń planisty czy modyfikować webhooków.

Zastosowania

Tak więc efemeryczne wolumeny ogólnego przeznaczenia nadają się do następujących zastosowań:

Pamięć trwała jako zamiennik pamięci operacyjnej dla memcached

Ostatnie wydania memcached dodały wsparcie użycia pamięci trwałej (Intel Optane itp., przyp. tłumacza) zamiast zwykłej pamięci operacyjnej. Podczas wdrażania memcached za pośrednictwem kontrolera aplikacji można za pomocą efemerycznych wolumenów ogólnego przeznaczenia wysłać zapytanie o przydzielenie wolumenu o określonym rozmiarze z PMEM przy użyciu sterownika CSI, na przykład PMEM-CSI.

Lokalne przechowywanie LVM jako przestrzeń robocza

Aplikacje pracujące z danymi, których rozmiar przekracza pamięć operacyjną, mogą żądać lokalnego przechowywania o rozmiarze lub metrykach wydajności, których nie mogą zapewnić zwykłe wolumeny EmptyDir z Kubernetes. Na przykład, dla tego celu stworzono TopoLVM.

Dostęp tylko do odczytu dla wolumenów z danymi

Przydzielenie wolumenu może prowadzić do utworzenia zapełnionego wolumenu przy:

Te wolumeny mogą być montowane w trybie tylko do odczytu.

Jak to działa

Efemeryczne wolumeny ogólnego przeznaczenia

Kluczową cechą efemerycznych wolumenów ogólnego przeznaczenia jest nowe źródło wolumenu, EphemeralVolumeSource, zawierające wszystkie pola potrzebne do utworzenia zapytania o wolumen (historycznie nazywane żądaniem trwałego wolumenu, PVC). Nowy kontroler w kube-controller-manager przegląda pod'y, tworzące takie źródło wolumenu, a następnie tworzy PVC dla tych podów. Dla sterownika CSI to zapytanie wygląda tak samo jak pozostałe, dlatego nie potrzebna jest tutaj specjalna pomoc.

Dopóki takie PVC istnieją — mogą być używane jak wszelkie inne zapytania o wolumen. W szczególności mogą być używane jako źródło danych przy kopiowaniu wolumenu lub tworzeniu migawki z wolumenu. Obiekt PVC zawiera również aktualny stan wolumenu.

Nazwy automatycznie tworzonych PVC są określone z góry: jest to kombinacja nazwy podu i nazwy wolumenu, oddzielona dywizem. Ustalenie nazw ułatwia interakcję z PVC, ponieważ nie trzeba ich szukać, jeśli znana jest nazwa podu i wolumenu. Wadą tego rozwiązania jest to, że nazwa może już być używana, co zostaje wykryte przez Kubernetes, a w efekcie uruchomienie podu jest blokowane.

Aby mieć pewność, że wolumen jest usuwany razem z podem, kontroler przypisuje pod jako właściciela żądania dotyczącego wolumenu. Kiedy pod jest usuwany, aktywowany jest standardowy mechanizm utylizacji, który usuwa zarówno żądanie, jak i wolumen.

Żądaniom przypisuje się sterownik magazynu za pośrednictwem standardowego mechanizmu klasy magazynu. Chociaż klasy z natychmiastowym i opóźnionym wiązaniem (które także) WaitForFirstConsumer) są obsługiwane, dla efemerycznych wolumenów sensowne jest używanie WaitForFirstConsumer, wówczas planista może uwzględnić zarówno wykorzystanie węzła, jak i dostępność magazynu przy wyborze węzła. Pojawia się tu również nowa funkcja.

Śledzenie pojemności magazynu

Zwykle planista nie ma informacji na temat tego, gdzie sterownik CSI utworzy wolumen. Również planista nie ma możliwości bezpośredniego skontaktowania się ze sterownikiem, aby zażądać tych informacji. Dlatego planista pyta węzły, aż znajdzie taki, w którym wolumeny mogą być dostępne (opóźnione wiązanie) lub całkowicie pozostawia wybór miejsca na wolumenie sterownikowi (natychmiastowe wiązanie).

Nowy API CSIStorageCapacity, znajdujący się w fazie alpha, pozwala na przechowywanie potrzebnych danych w etcd, dzięki czemu są one dostępne dla planisty. W przeciwieństwie do wsparcia dla efemerycznych wolumenów ogólnego przeznaczenia, przy wdrażaniu sterownika należy włączyć śledzenie pojemności magazynu: external-provisioner musi opublikować informacje o pojemności uzyskiwane od sterownika za pośrednictwem standardowego GetCapacity.

Jeśli planista musi wybrać węzeł dla podu z nieprzypisanym wolumenem korzystającym z opóźnionego wiązania, a sterownik podczas wdrażania aktywował tę funkcję ustawiając flagę CSIDriver.storageCapacity, to automatycznie zostaną odrzucone węzły, które nie mają wystarczającej pojemności magazynu. Działa to zarówno dla efemerycznych wolumenów ogólnego przeznaczenia, jak i dla stałych wolumenów, ale nie dla efemerycznych wolumenów CSI, ponieważ ich parametry nie mogą być odczytane przez Kubernetes.

Zwykle woluminy z bezpośrednim powiązaniem są tworzone przed planowaniem podów, a ich lokalizacja jest wybierana przez sterownik magazynu, dlatego podczas konfiguracji external-provisioner domyślnie pomijane są klasy magazynowe z bezpośrednim powiązaniem, ponieważ te dane i tak nie będą używane.

Ponieważ scheduler Kubernetes musi pracować z potencjalnie przestarzałymi informacjami, nie ma gwarancji, że pojemność będzie dostępna w każdym przypadku, gdy wolumin zostanie stworzony, jednakże szanse na to, że zostanie stworzony bez ponownych prób, wzrastają.

N.B. Bardziej szczegółowe informacje można uzyskać, a także bezpiecznie „poćwiczyć na kotach” na warsztatach, a w przypadku całkowicie niejasnej sytuacji otrzymać pomoc techniczną podczas intensywów — Kubernetes Podstawy odbędą się 28-30 września, a dla bardziej zaawansowanych specjalistów Kubernetes Mega 14-16 października.

Bezpieczeństwo

CSIStorageCapacity

Obiekty CSIStorageCapacity znajdują się w przestrzeniach nazw, zaleca się ograniczenie uprawnień RBAC dla CSIStorageCapacity w tej przestrzeni przy wdrażaniu każdego sterownika CSI, ponieważ jest oczywiste, skąd pochodzą dane. W każdym razie Kubernetes tego nie sprawdza, a zazwyczaj sterowniki są instalowane w jednej przestrzeni nazw, więc ostatecznie oczekuje się, że sterowniki będą działać i nie publikować błędnych danych (i w tym przypadku mnie zaskoczyło, przyp. tłumacza na podstawie znanego dowcipu)

Efemeryczne wolumeny ogólnego przeznaczenia

Jeżeli użytkownicy mają uprawnienia do tworzenia poda (bezpośrednio lub pośrednio) — będą również mogli stworzyć efemeryczne woluminy ogólnego przeznaczenia, nawet jeśli nie mają uprawnień do tworzenia żądania woluminu. To dlatego, że kontrole uprawnień RBAC są stosowane do kontrolera, który tworzy PVC, a nie do użytkownika. To jest główna zmiana, którą trzeba dodać do konta, przed włączeniem tej funkcji w klastrach, jeśli niepewni użytkownicy nie powinni mieć uprawnień do tworzenia woluminów.

Przykład

Osobna gałąź w PMEM-CSI zawiera wszystkie potrzebne zmiany do uruchomienia klastra Kubernetes 1.19 w środowiskach wirtualnych QEMU ze wszystkimi funkcjami znajdującymi się na etapie alpha. Kod sterownika nie był zmieniany, zmieniło się tylko wdrożenie.

Na odpowiedniej maszynie (Linux, zwykły użytkownik może użyć Docker, patrz tutaj szczegóły) te polecenia uruchomią klaster i zainstalują sterownik 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

Po uruchomieniu wszystko będzie zawierać instrukcje użycia:

Klaster testowy jest gotowy. Zaloguj się z [...] /pmem-csi/_work/pmem-govm/ssh.0, uruchom
kubectl po zalogowaniu. Alternatywnie, użyj kubectl bezpośrednio z
następującą zmienną środowiskową:
   KUBECONFIG=[...] /pmem-csi/_work/pmem-govm/kube.config

secret/pmem-csi-registry-secrets utworzono
secret/pmem-csi-node-secrets utworzono
serviceaccount/pmem-csi-controller utworzono
...
Aby przetestować sterownik pmem-csi z efemerycznymi wolumenami:
   cat deploy/kubernetes-1.19/pmem-app-ephemeral.yaml |
   [...] /pmem-csi/_work/pmem-govm/ssh.0 kubectl create -f -

Obiekty CSIStorageCapacity nie są przeznaczone do odczytu przez ludzi, więc wymagana jest pewna obróbka. Za pomocą filtrów szablonów w Golang zostaną pokazane klasy przechowywania, w tym przykładzie wyświetlone zostaną nazwa, topologia i pojemność:

$ 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

Oddzielny obiekt ma następującą zawartość:

$ kubectl describe csistoragecapacities/csisc-6cw8j
Nazwa:         csisc-sqdnt
Namespace:    default
Etykiety:       
Adnotacje:  
Wersja API:  storage.k8s.io/v1alpha1
Pojemność:     30716Mi
Rodzaj:         CSIStorageCapacity
Metadane:
  Znacznik czasu utworzenia:  2020-08-11T15:41:03Z
  Generowana nazwa:       csisc-
  Zarządzane pola:
    ...
  Odniesienia właściciela:
    Wersja API:     apps/v1
    Kontroler:      prawda
    Rodzaj:            StatefulSet
    Nazwa:            pmem-csi-controller
    UID:             590237f9-1eb4-4208-b37b-5f7eab4597d1
  Wersja zasobu:  2994
  Link samodzielny:         /apis/storage.k8s.io/v1alpha1/namespaces/default/csistoragecapacities/csisc-sqdnt
  UID:               da36215b-3b9d-404a-a4c7-3f1c3502ab13
Topologia węzła:
  Dopasuj etykiety:
    pmem-csi.intel.com/node:  pmem-csi-pmem-govm-worker1
Nazwa klasy przechowywania:           pmem-csi-sc-late-binding
Wydarzenia:

Spróbujmy stworzyć aplikację demonstracyjną z jednym efemerycznym wolumenem ogólnego przeznaczenia. Zawartość pliku 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

Po utworzeniu, jak pokazano w instrukcji powyżej, mamy dodatkowy pod oraz PVC:

$ kubectl get pods/my-csi-app-inline-volume -o wide
NAZWA                       GOTOWY   STATUS    RESTARTY   WIEK     IP          WĘZEŁ                         NOMINOWANY WĘZEŁ   BRAMKI GOTOWOŚCI
my-csi-app-inline-volume   1/1     Działa   0          6m58s   10.36.0.2   pmem-csi-pmem-govm-worker1              
$ kubectl get pvc/my-csi-app-inline-volume-my-csi-volume
NAZWA                                     STATUS   WOLumen                                     POJEMNOŚĆ   TRYBY DOSTĘPU   KLASA PRZECHOWYWANIA               WIEK
my-csi-app-inline-volume-my-csi-volume   Związano    pvc-c11eb7ab-a4fa-46fe-b515-b366be908823   4Gi        RWO            pmem-csi-sc-late-binding   9m21s

Właścicielem PVC jest pod:

$ 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
...

Informacje zostały zaktualizowane zgodnie z oczekiwaniami dla 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

Jeśli inne aplikacje będą potrzebować więcej niż 26620Mi, harmonogram nie weźmie tego pod uwagę pmem-csi-pmem-govm-worker1 w żadnym wypadku.

Co dalej?

Obie funkcje są nadal w opracowaniu. Otworzono kilka zgłoszeń podczas testów alfa. Przez linki z propozycjami poprawy dokumentowane są prace, które należy wykonać, aby przejść do etapu beta, a także jakie alternatywy zostały już rozważone i odrzucone:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster