Skip to main content
  • »
  • KUBERNETES »
  • Wolumenowa i efemeryczna pamięć masowa dla klastrów Kubernetes w NSIS OpenStack Magnum

Wolumenowa i efemeryczna pamięć masowa dla klastrów Kubernetes w NSIS OpenStack Magnum

Kontenery w Kubernetes przechowują pliki na dysku i jeśli kontener ulegnie awarii, dane zostaną utracone. Nowy kontener może zastąpić stary, ale dane nie przetrwają. Inny problem pojawia się, gdy kontenery uruchomione w kapsule muszą współdzielić pliki.

Dlatego też Kubernetes posiada inny rodzaj przechowywania plików, zwany volumes. Mogą one być trwałe lub efemeryczne, w zależności od czasu życia kapsuły:

  • Woluminy efemeryczne są usuwane, gdy pod jest usuwany, podczas gdy

  • Woluminy trwałe nadal istnieją, nawet jeśli podstacja, do której są podłączone, już nie istnieje.

Koncepcja woluminów została po raz pierwszy spopularyzowana przez Docker, gdzie był to katalog na dysku lub w kontenerze. W hostingu NSIS OpenStack domyślny magazyn docker jest skonfigurowany do korzystania z efemerycznego dysku instancji. Można to zmienić, określając rozmiar woluminu dockera podczas tworzenia klastra, symbolicznie w ten sposób (poniżej znajduje się pełne polecenie generowania nowego klastra przy użyciu –docker-volume-size):

openstack coe cluster create --docker-volume-size 50

Oznacza to, że zostanie utworzony i dołączony do poda trwały wolumen o rozmiarze 50 GB. Użycie –docker-volume-size to sposób zarówno na zarezerwowanie miejsca, jak i zadeklarowanie, że pamięć masowa będzie trwała.

Co będziemy omawiać

  • Jak utworzyć klaster, gdy używany jest –docker-volume-size?

  • Jak utworzyć manifest pod z emptyDir jako wolumenem?

  • Jak utworzyć kapsułę z tym manifestem

  • Jak wykonywać polecenia bash w kontenerze

  • Jak zapisać plik w pamięci trwałej

  • Jak wykazać, że dołączony wolumin jest trwały?

Wymagania wstępne

1 Hosting

Potrzebne jest konto hostingowe NSIS z interfejsem Horizon https://horizon.cloudferro.com.

2 Tworzenie klastrów za pomocą CLI

Artykuł /kubernetes/How-To-Use-Command-Line-Interface-for-Kubernetes-Clusters-On-NSIS-c-OpenStack-Magnum wprowadzi cię w tworzenie klastrów za pomocą interfejsu wiersza poleceń.

3 Podłącz klienta openstack do chmury

Przygotuj klientów openstack i magnum, wykonując Krok 2 Podłącz klientów OpenStack i Magnum do chmury Horizon z artykułu Jak zainstalować klientów OpenStack i Magnum dla interfejsu wiersza poleceń w NSIS Horizon?.

4 Sprawdź dostępne limity

Przed utworzeniem dodatkowego klastra sprawdź stan zasobów za pomocą poleceń Horizon Computer => Overview.

5 Klucze prywatne i publiczne

Para kluczy SSH utworzona w pulpicie nawigacyjnym OpenStack. Aby ją utworzyć, postępuj zgodnie z tym artykułem Jak utworzyć parę kluczy w OpenStack Dashboard na NSIS Cloud. Zostanie utworzona para kluczy o nazwie „sshkey” i będzie można jej używać również w tym samouczku.

6 Rodzaje woluminów

Typy wolumenów są opisane w oficjalnej dokumentacji Kubernetes.

Krok 1 - Utworzenie klastra przy użyciu –docker-volume-size

Zamierzasz utworzyć nowy klaster o nazwie dockerspace, który będzie używał parametru –docker-volume-size przy użyciu następującego polecenia:

openstack coe cluster create dockerspace
  --cluster-template k8s-1.23.16-cilium-v1.0.3
  --keypair sshkey
  --master-count 1
  --node-count 2
  --docker-volume-size 50
  --master-flavor eo1.large
  --flavor eo2.large

Po kilku minutach zostanie utworzony nowy klaster dockerspace.

Kliknij Container Infra => Clusters, aby wyświetlić trzy klastry w systemie: authenabled, k8s-cluster i dockerspace.

../_images/dockerspace_created1.png

Oto ich instancje (po kliknięciu na Compute => Instances):

../_images/instances1.png

Każdy z nich będzie miał co najmniej dwie instancje, jedną dla węzła głównego i jedną dla węzła roboczego. dockerspace ma trzy instancje, ponieważ ma dwa węzły robocze, utworzone ze smakiem eo2.large.

Jak na razie wszystko w porządku, nic nadzwyczajnego. Kliknij Volumes => Volumes, aby wyświetlić listę woluminów:

../_images/volumes1.png

Jeśli –docker-volume-size nie jest włączony, pojawią się tutaj tylko instancje z etcd-volume w nazwie, tak jak w przypadku klastrów authenabled i k8s-cluster. Jeśli jest włączony, pojawią się dodatkowe woluminy, po jednym dla każdego węzła. dockerspace będzie zatem miał jedną instancję dla węzła głównego i dwie instancje dla węzłów roboczych.

Zwróć uwagę na kolumnę Attached. Wszystkie węzły dla dockerspace używają /dev/vdb do przechowywania danych, co jest faktem, który będzie ważny później.

Jak określono podczas tworzenia, docker-volumes mają rozmiar 50 GB każdy.

W tym kroku utworzyłeś nowy klaster z włączonym docker storage, a następnie zweryfikowałeś, że główna różnica polega na tworzeniu wolumenów dla klastra.

Krok 2 - Utwórz manifest pod

Aby utworzyć pod, należy użyć pliku w formacie yaml, który definiuje parametry pod. Użyj polecenia

nano redis.yaml

aby utworzyć plik o nazwie redis.yaml i skopiować do niego następujące wiersze:

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage
    emptyDir: {}

Tak to będzie wyglądać w terminalu:

../_images/nano_redis_yaml1.png

Tworzony jest Pod, jego nazwa to redis i będzie on zajmował jeden kontener o nazwie redis. Zawartością tego kontenera będzie obraz o nazwie redis.

Redis jest dobrze znaną bazą danych, a jej obraz jest przygotowany z wyprzedzeniem, więc można go pobrać bezpośrednio z repozytorium. Jeśli wdrażasz własną aplikację, najlepszym sposobem byłoby wydanie jej za pośrednictwem Dockera i pobranie z jego repozytorium.

Nowy wolumin zostanie nazwany redis-storage, a jego katalog będzie miał nazwę /data/redis. Nazwa woluminu ponownie będzie redis-storage i będzie typu emptyDir.

Wolumin emptyDir jest początkowo pusty i jest tworzony po raz pierwszy, gdy Pod jest przypisany do węzła. Będzie istniał tak długo, jak ten Pod będzie tam działał, a jeśli Pod zostanie usunięty, powiązane dane w emptyDir zostaną trwale usunięte. Dane w woluminie emptyDir są jednak bezpieczne w przypadku awarii kontenera.

Oprócz emptyDir, można było użyć około tuzina innych typów woluminów: awsElasticBlockStore, azureDisk, cinder itd.

W tym kroku przygotowałeś manifest pod, za pomocą którego utworzysz pod w następnym kroku.

Krok 3 - Utwórz Pod na węźle 0 dockerspace

W tym kroku utworzony zostanie nowy pod na węźle 0 klastra dockerspace.

Najpierw sprawdź, jakie kapsuły są dostępne w klastrze:

kubectl get pods

Może to spowodować wyświetlenie wiersza błędu, takiego jak ten:

The connection to the server localhost:8080 was refused - did you specify the right host or port?

Stanie się tak, jeśli nie skonfigurowałeś parametrów kubectl zgodnie z wymaganiami wstępnymi nr 3. Teraz należy skonfigurować dostęp do dockerstate:

mkdir dockerspacedir

openstack coe cluster config
--dir dockerspacedir
--force
--output-certs
dockerspace

Najpierw utwórz nowy katalog, dockerspacedir, w którym będzie znajdował się plik konfiguracyjny dostępu do klastra, a następnie wykonaj polecenie cluster config. Wyjściem będzie następujący wiersz:

export KUBECONFIG=/Users/duskosavic/CloudferroDocs/dockerspacedir/config

Skopiuj go i wprowadź ponownie jako polecenie w terminalu. To da aplikacji kubectl dostęp do klastra. Utwórz pod za pomocą tego polecenia:

kubectl apply -f redis.yaml

Odczyta on parametry z pliku redis.yaml i wyśle je do klastra.

Oto polecenie umożliwiające dostęp do wszystkich kapsuł, jeśli takie istnieją:

kubectl get pods

NAME    READY   STATUS              RESTARTS   AGE
redis   0/1     ContainerCreating   0          7s

Powtórz polecenie po kilku sekundach i zobacz różnicę:

kubectl get pods

NAME    READY   STATUS    RESTARTS   AGE
redis   1/1     Running   0          81s

W tym kroku utworzono nowy pod na klastrze dockerspace i jest on uruchomiony.

W następnym kroku wejdziesz do kontenera i zaczniesz wydawać polecenia, tak jak w każdym innym środowisku Linux.

Krok 4 - Wykonywanie poleceń bash w kontenerze

W tym kroku uruchomiona zostanie powłoka bash w kontenerze, co w systemie Linux jest równoznaczne z uruchomieniem systemu operacyjnego:

kubectl exec -it redis -- /bin/bash

Poniższa lista jest odpowiedzią:

root@redis:/data# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          50G  1.4G   49G   3% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/vdb         50G  1.4G   49G   3% /data
/dev/vda4        32G  4.6G   27G  15% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           3.9G   16K  3.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           3.9G     0  3.9G   0% /proc/acpi
tmpfs           3.9G     0  3.9G   0% /proc/scsi
tmpfs           3.9G     0  3.9G   0% /sys/firmware

Tak to będzie wyglądać w terminalu:

../_images/redis-data1.png

Zauważ, że monit zmienił się na

root@redis:/data#

co oznacza, że teraz wydajesz polecenia wewnątrz samego kontenera. Pod działa jako Fedora 33 i można użyć df, aby zobaczyć woluminy i ich rozmiary. Polecenie

df -h

wyświetla rozmiary plików i katalogów w ludzki sposób (zwykłe znaczenie parametru -h to Help, podczas gdy tutaj jest to skrót od Human).

W tym kroku aktywowano system operacyjny kontenera.

Krok 5 - Zapisywanie pliku w pamięci trwałej

W tym kroku zamierzasz przetestować trwałość plików w pamięci trwałej. Najpierw

  • zapisać plik w katalogu /data/redis, a następnie

  • kill the Redis process, which in turn will

  • zabić pojemnik; w końcu będziesz

  • ponownie wejść do kapsuły,

gdzie znajdziesz nienaruszony plik.

Zauważ, że dev/vdb ma rozmiar 50 GB w powyższym zestawieniu i połącz go z kolumną Attached To w zestawieniu Volumes => Volumes:

../_images/devvdb1.png

Z kolei jest on powiązany z instancją:

../_images/instance1.png

Ta instancja jest wstrzykiwana do kontenera i - będąc niezależną instancją - działa jako trwały magazyn dla poda.

Utwórz plik w kontenerze redis:

cd /data/redis/
echo Hello > test-file

Zainstaluj oprogramowanie, aby zobaczyć numer PID procesu Redis w kontenerze

apt-get update
apt-get install procps
ps aux

Są to uruchomione procesy:

../_images/redis_kill1.png

Weź numer PID dla procesu Redis (tutaj jest to 1) i wyeliminuj go za pomocą polecenia

kill 1

Spowoduje to najpierw zabicie kontenera, a następnie zamknięcie jego wiersza poleceń.

W tym kroku utworzono plik i zabito kontener zawierający plik. Stanowi to podstawę do przetestowania, czy pliki przetrwają awarię kontenera.

Krok 6 - Sprawdź plik zapisany w poprzednim kroku

W tym kroku dowiesz się, czy plik plik testowy nadal istnieje.

Wejdź ponownie do kapsuły, aktywuj jej powłokę bash i sprawdź, czy plik przetrwał:

kubectl exec -it redis -- /bin/bash
cd redis
ls

test-file

Tak, plik plik testowy wciąż tam jest. Trwały magazyn dla pod zawiera go w ścieżce /data/redis:

../_images/final_result1.png

W tym kroku ponownie wszedłeś do poda i okazało się, że plik przetrwał nienaruszony. Było to oczekiwane, ponieważ woluminy typu emptyDir przetrwają awarie kontenera tak długo, jak długo istnieje pod.

Co robić dalej

  • emptyDir przetrwa awarie kontenera, ale zniknie, gdy pod zniknie. Inne typy woluminów mogą lepiej przetrwać utratę podów. Na przykład:

  • awsElasticBlockStore spowoduje odmontowanie woluminu, gdy pod zniknie; będąc odmontowanym i nie zniszczonym, zachowa dane, które zawiera. Ten typ woluminu może mieć wstępnie wypełnione dane i może współdzielić dane między podami.

  • cephfs can also have pre-populated data and share them among the pods, but can additionally also be mounted by multiple writers at the same time.

Mogą również obowiązywać inne ograniczenia. Niektóre z tych typów wolumenów będą wymagały najpierw aktywacji własnych serwerów lub wszystkie węzły, na których działają pody, muszą być tego samego typu itd. Warunek wstępny nr 6 zawiera listę wszystkich typów wolumenów dla klastrów Kubernetes, więc warto go przestudiować i zastosować do własnych aplikacji Kubernetes.