
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 , ale ich funkcjonalność jest ograniczona do tego, co jest zaimplementowane w K8s.
Ephemericzne 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ć : 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 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 .
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 .
Dostęp tylko do odczytu dla wolumenów z danymi
Przydzielenie wolumenu może prowadzić do utworzenia zapełnionego wolumenu przy:
przywracaniu ;
tworzeniu ;
pracy .
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 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 — odbędą się 28-30 września, a dla bardziej zaawansowanych specjalistów 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ć , przed włączeniem tej funkcji w klastrach, jeśli niepewni użytkownicy nie powinni mieć uprawnień do tworzenia woluminów.
Przykład
Osobna 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ć , patrz 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
