Et praktisk eksempel på å koble Ceph-basert lagring til en Kubernetes-klynge

Container Storage Interface (CSI) er et enhetlig grensesnitt mellom Kubernetes og lagringssystemer. Vi har allerede snakket kort om det fortalte, og i dag skal vi se nærmere på kombinasjonen av CSI og Ceph: vi viser hvordan koble til Ceph-lagring til Kubernetes-klyngen.
Artikkelen gir ekte, om enn litt forenklede eksempler for å lette oppfatningen. Vi vurderer ikke å installere og konfigurere Ceph- og Kubernetes-klynger.

Lurer du på hvordan det fungerer?

Et praktisk eksempel på å koble Ceph-basert lagring til en Kubernetes-klynge

Så du har en Kubernetes-klynge for hånden, distribuert, for eksempel, kubespray. Det er en Ceph-klynge som jobber i nærheten - du kan også installere den for eksempel med denne et sett med lekebøker. Jeg håper det ikke er nødvendig å nevne at for produksjon mellom dem må det være et nettverk med en båndbredde på minst 10 Gbit/s.

Hvis du har alt dette, la oss gå!

Først, la oss gå til en av Ceph-klyngenodene og sjekke at alt er i orden:

ceph health
ceph -s

Deretter oppretter vi umiddelbart et basseng for RBD-disker:

ceph osd pool create kube 32
ceph osd pool application enable kube rbd

La oss gå videre til Kubernetes-klyngen. Der vil vi først og fremst installere Ceph CSI-driveren for RBD. Vi vil installere, som forventet, gjennom Helm.
Vi legger til et depot med et diagram, vi får et sett med variabler for ceph-csi-rbd-diagrammet:

helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml

Nå må du fylle ut filen cephrbd.yml. For å gjøre dette, finn ut klynge-IDen og IP-adressene til monitorer i Ceph:

ceph fsid  # так мы узнаем clusterID
ceph mon dump  # а так увидим IP-адреса мониторов

Vi legger inn de oppnådde verdiene i cephrbd.yml-filen. Samtidig muliggjør vi opprettelsen av PSP-policyer (Pod Security Policies). Alternativer i seksjoner nodeplugin и provianter allerede i filen, kan de rettes som vist nedenfor:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"
      - "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"
      - "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"

nodeplugin:
  podSecurityPolicy:
    enabled: true

provisioner:
  podSecurityPolicy:
    enabled: true

Deretter gjenstår alt for oss å installere diagrammet i Kubernetes-klyngen.

helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace

Flott, RBD-driveren fungerer!
La oss lage en ny StorageClass i Kubernetes. Dette krever igjen litt fikling med Ceph.

Vi oppretter en ny bruker i Ceph og gir ham rettigheter til å skrive til bassenget kube:

ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'

La oss nå se at tilgangsnøkkelen fortsatt er der:

ceph auth get-key client.rbdkube

Kommandoen vil gi ut noe slikt:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

La oss legge denne verdien til Secret i Kubernetes-klyngen – der vi trenger den brukernøkkel:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi-rbd
stringData:
  # Значения ключей соответствуют имени пользователя и его ключу, как указано в
  # кластере Ceph. ID юзера должен иметь доступ к пулу,
  # указанному в storage class
  userID: rbdkube
  userKey: <user-key>

Og vi skaper vår hemmelighet:

kubectl apply -f secret.yaml

Deretter trenger vi et StorageClass-manifest noe som dette:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: <cluster-id>
   pool: kube

   imageFeatures: layering

   # Эти секреты должны содержать данные для авторизации
   # в ваш пул.
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd

   csi.storage.k8s.io/fstype: ext4

reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - discard

Må fylles ut clusterID, som vi allerede har lært av teamet ceph fsid, og bruk dette manifestet på Kubernetes-klyngen:

kubectl apply -f storageclass.yaml

For å sjekke hvordan klyngene fungerer sammen, la oss lage følgende PVC (Persistent Volume Claim):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc

La oss umiddelbart se hvordan Kubernetes opprettet det forespurte volumet i Ceph:

kubectl get pvc
kubectl get pv

Alt ser ut til å være flott! Hvordan ser dette ut på Ceph-siden?
Vi får en liste over volumer i bassenget og viser informasjon om volumet vårt:

rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # тут, конечно же, будет другой ID тома, который выдала предыдущая команда

La oss nå se hvordan størrelsen på et RBD-volum fungerer.
Endre volumstørrelsen i pvc.yaml-manifestet til 2Gi og bruk den:

kubectl apply -f pvc.yaml

La oss vente til endringene trer i kraft og se på volumstørrelsen igjen.

rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653

kubectl get pv
kubectl get pvc

Vi ser at størrelsen på PVC ikke har endret seg. For å finne ut hvorfor, kan du spørre Kubernetes om en YAML-beskrivelse av PVC:

kubectl get pvc rbd-pvc -o yaml

Her er problemet:

melding: Venter på at brukeren skal (re-)starte en pod for å fullføre filsystemendring av volum på noden. type: FileSystemResizePending

Det vil si at disken har vokst, men filsystemet på den har ikke vokst.
For å utvide filsystemet, må du montere volumet. I vårt land brukes ikke den opprettede PVC/PV på noen måte.

Vi kan lage en testpod, for eksempel slik:

---
apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx:1.17.6
      volumeMounts:
        - name: mypvc
          mountPath: /data
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

Og la oss nå se på PVC:

kubectl get pvc

Størrelsen har endret seg, alt er i orden.

I den første delen jobbet vi med RBD-blokkenheten (den står for Rados Block Device), men dette kan ikke gjøres hvis forskjellige mikrotjenester trenger å jobbe med denne disken samtidig. CephFS er mye bedre egnet for arbeid med filer i stedet for diskbilder.
Ved å bruke eksemplet med Ceph- og Kubernetes-klynger, vil vi konfigurere CSI og andre nødvendige enheter for å jobbe med CephFS.

La oss hente verdiene fra det nye Helm-diagrammet vi trenger:

helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml

Igjen må du fylle ut filen cephfs.yml. Som før vil Ceph-kommandoer hjelpe:

ceph fsid
ceph mon dump

Fyll ut filen med verdier som dette:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "172.18.8.5:6789"
      - "172.18.8.6:6789"
      - "172.18.8.7:6789"

nodeplugin:
  httpMetrics:
    enabled: true
    containerPort: 8091
  podSecurityPolicy:
    enabled: true

provisioner:
  replicaCount: 1
  podSecurityPolicy:
    enabled: true

Vær oppmerksom på at monitoradresser er spesifisert i det enkle skjemaet adresse:port. For å montere cephfs på en node, overføres disse adressene til kjernemodulen, som ennå ikke vet hvordan den fungerer med v2-monitorprotokollen.
Vi endrer porten for httpMetrics (Prometheus vil gå dit for å overvåke beregninger) slik at den ikke kommer i konflikt med nginx-proxy, som er installert av Kubespray. Du trenger kanskje ikke dette.

Installer Helm-diagrammet i Kubernetes-klyngen:

helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace

La oss gå til Ceph-datalageret for å opprette en egen bruker der. Dokumentasjonen sier at CephFS-provisjonsprogrammet krever tilgangsrettigheter for klyngeadministratorer. Men vi vil opprette en egen bruker fs med begrensede rettigheter:

ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'

Og la oss umiddelbart se på tilgangsnøkkelen hans, vi trenger den senere:

ceph auth get-key client.fs

La oss lage separate Secret og StorageClass.
Ikke noe nytt, vi har allerede sett dette i eksemplet med RBD:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: ceph-csi-cephfs
stringData:
  # Необходимо для динамически создаваемых томов
  adminID: fs
  adminKey: <вывод предыдущей команды>

Bruk av manifestet:

kubectl apply -f secret.yaml

Og nå - en egen StorageClass:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: <cluster-id>

  # Имя файловой системы CephFS, в которой будет создан том
  fsName: cephfs

  # (необязательно) Пул Ceph, в котором будут храниться данные тома
  # pool: cephfs_data

  # (необязательно) Разделенные запятыми опции монтирования для Ceph-fuse
  # например:
  # fuseMountOptions: debug

  # (необязательно) Разделенные запятыми опции монтирования CephFS для ядра
  # См. man mount.ceph чтобы узнать список этих опций. Например:
  # kernelMountOptions: readdir_max_bytes=1048576,norbytes

  # Секреты должны содержать доступы для админа и/или юзера Ceph.
  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs

  # (необязательно) Драйвер может использовать либо ceph-fuse (fuse), 
  # либо ceph kernelclient (kernel).
  # Если не указано, будет использоваться монтирование томов по умолчанию,
  # это определяется поиском ceph-fuse и mount.ceph
  # mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - debug

La oss fylle det ut her clusterID og gjelder i Kubernetes:

kubectl apply -f storageclass.yaml

Проверка

For å sjekke, som i forrige eksempel, la oss lage en PVC:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-cephfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: csi-cephfs-sc

Og kontroller tilstedeværelsen av PVC/PV:

kubectl get pvc
kubectl get pv

Hvis du vil se på filer og kataloger i CephFS, kan du montere dette filsystemet et sted. For eksempel som vist nedenfor.

La oss gå til en av Ceph-klyngenodene og utføre følgende handlinger:

# Точка монтирования
mkdir -p /mnt/cephfs

# Создаём файл с ключом администратора
ceph auth get-key client.admin >/etc/ceph/secret.key

# Добавляем запись в /etc/fstab
# !! Изменяем ip адрес на адрес нашего узла
echo "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev    0       2" >> /etc/fstab

mount /mnt/cephfs

Selvfølgelig er montering av FS på en Ceph-node som dette kun egnet for treningsformål, og det er det vi gjør på vår Slurmkurs. Jeg tror ikke noen ville gjort dette i produksjonen; det er stor risiko for å slette viktige filer ved et uhell.

Og til slutt, la oss sjekke hvordan ting fungerer med å endre størrelse på volumer når det gjelder CephFS. La oss gå tilbake til Kubernetes og redigere manifestet vårt for PVC - øke størrelsen der, for eksempel til 7Gi.

La oss bruke den redigerte filen:

kubectl apply -f pvc.yaml

La oss se på den monterte katalogen for å se hvordan kvoten har endret seg:

getfattr -n ceph.quota.max_bytes <каталог-с-данными>

For at denne kommandoen skal fungere, må du kanskje installere pakken på systemet ditt attr.

Øynene er redde, men hendene gjør det

Alle disse trylleformularene og de lange YAML-manifestene virker kompliserte på overflaten, men i praksis får Slurm-elever taket på dem ganske raskt.
I denne artikkelen gikk vi ikke dypt inn i jungelen - det finnes offisiell dokumentasjon for det. Hvis du er interessert i detaljene for å sette opp Ceph-lagring med en Kubernetes-klynge, vil disse koblingene hjelpe:

Generelle prinsipper for Kubernetes som arbeider med volumer
RBD-dokumentasjon
Integrering av RBD og Kubernetes fra et Ceph-perspektiv
Integrering av RBD og Kubernetes fra et CSI-perspektiv
Generell CephFS-dokumentasjon
Integrering av CephFS og Kubernetes fra et CSI-perspektiv

På Slurm-banen Kubernetes Base du kan gå litt lenger og distribuere en ekte applikasjon i Kubernetes som vil bruke CephFS som fillagring. Gjennom GET/POST-forespørsler vil du kunne overføre filer til og motta dem fra Ceph.

Og hvis du er mer interessert i datalagring, så meld deg på nytt kurs på Ceph. Mens betatesten pågår, kan kurset fås med rabatt og du kan påvirke innholdet.

Forfatter av artikkelen: Alexander Shvalov, praktiserende ingeniør Southbridge, Sertifisert Kubernetes-administrator, forfatter og utvikler av Slurm-kurs.

Kilde: www.habr.com