Et praktisk eksempel på at forbinde Ceph-baseret lager til en Kubernetes-klynge

Container Storage Interface (CSI) er en samlet grænseflade mellem Kubernetes og lagersystemer. Vi har allerede talt om det kort fortalt, og i dag vil vi se nærmere på kombinationen af ​​CSI og Ceph: vi viser hvordan tilslut Ceph-lager til Kubernetes-klyngen.
Artiklen giver rigtige, omend lidt forenklede eksempler for at lette opfattelsen. Vi overvejer ikke at installere og konfigurere Ceph- og Kubernetes-klynger.

Undrer du dig over, hvordan det virker?

Et praktisk eksempel på at forbinde Ceph-baseret lager til en Kubernetes-klynge

Så du har en Kubernetes-klynge lige ved hånden, implementeret f.eks. kubespray. Der er en Ceph klynge, der arbejder i nærheden - du kan også installere den for eksempel med denne et sæt spillebøger. Jeg håber, der ikke er behov for at nævne, at for produktion mellem dem skal der være et netværk med en båndbredde på mindst 10 Gbit/s.

Hvis du har alt dette, så lad os gå!

Lad os først gå til en af ​​Ceph-klyndeknuderne og kontrollere, at alt er i orden:

ceph health
ceph -s

Dernæst opretter vi straks en pulje til RBD-diske:

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

Lad os gå videre til Kubernetes-klyngen. Der vil vi først og fremmest installere Ceph CSI-driveren til RBD. Vi installerer, som forventet, gennem Helm.
Vi tilføjer et depot med et diagram, vi får et sæt variabler til 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

Nu skal du udfylde filen cephrbd.yml. For at gøre dette skal du finde ud af klynge-id'et og IP-adresserne på skærme i Ceph:

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

Vi indtaster de opnåede værdier i filen cephrbd.yml. Samtidig muliggør vi oprettelsen af ​​PSP-politikker (Pod Security Policies). Valgmuligheder i sektioner nodeplugin и proviant 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

Dernæst er det eneste, der er tilbage for os, at 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

Fantastisk, RBD-driveren virker!
Lad os oprette en ny StorageClass i Kubernetes. Dette kræver igen lidt pusle med Ceph.

Vi opretter en ny bruger i Ceph og giver ham rettigheder til at skrive til puljen Kube:

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

Lad os nu se, at adgangsnøglen stadig er der:

ceph auth get-key client.rbdkube

Kommandoen udsender noget som dette:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Lad os tilføje denne værdi til Secret i Kubernetes-klyngen - hvor vi har brug for det brugernøgle:

---
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 skaber vores hemmelighed:

kubectl apply -f secret.yaml

Dernæst har vi brug for et StorageClass-manifest noget 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

Skal udfyldes klynge-ID, som vi allerede har lært af holdet ceph fsid, og anvende dette manifest på Kubernetes-klyngen:

kubectl apply -f storageclass.yaml

For at kontrollere, hvordan klyngerne arbejder sammen, lad os oprette 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

Lad os straks se, hvordan Kubernetes oprettede det anmodede bind i Ceph:

kubectl get pvc
kubectl get pv

Alt ser ud til at være fantastisk! Hvordan ser det ud på Ceph-siden?
Vi får en liste over mængder i poolen og ser information om vores volumen:

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

Lad os nu se, hvordan størrelsen på en RBD-volumen fungerer.
Skift volumenstørrelsen i pvc.yaml-manifestet til 2Gi og anvend det:

kubectl apply -f pvc.yaml

Lad os vente på, at ændringerne træder i kraft og se på volumenstørrelsen igen.

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

kubectl get pv
kubectl get pvc

Vi ser, at størrelsen af ​​PVC ikke har ændret sig. For at finde ud af hvorfor, kan du forespørge Kubernetes om en YAML-beskrivelse af PVC:

kubectl get pvc rbd-pvc -o yaml

Her er problemet:

besked: Venter på, at brugeren (gen-)starter en pod for at afslutte filsystemets størrelse på volumen på noden. type: FileSystemResizePending

Det vil sige, at disken er vokset, men det er filsystemet på den ikke.
For at udvide filsystemet skal du montere volumen. I vores land bruges den skabte PVC/PV ikke i øjeblikket på nogen måde.

Vi kan oprette en test Pod, for eksempel sådan her:

---
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 lad os nu se på PVC:

kubectl get pvc

Størrelsen er ændret, alt er fint.

I den første del arbejdede vi med RBD-blokenheden (den står for Rados Block Device), men dette kan ikke lade sig gøre, hvis forskellige mikrotjenester skal arbejde med denne disk samtidigt. CephFS er meget bedre egnet til at arbejde med filer frem for diskbilleder.
Ved at bruge eksemplet med Ceph- og Kubernetes-klynger vil vi konfigurere CSI og andre nødvendige entiteter til at arbejde med CephFS.

Lad os få værdierne fra det nye Helm-diagram, vi har brug for:

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

Igen skal du udfylde filen cephfs.yml. Som før vil Ceph-kommandoer hjælpe:

ceph fsid
ceph mon dump

Udfyld filen med værdier som denne:

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

Bemærk venligst, at monitoradresser er angivet i den simple formular adresse:port. For at montere cephf'er på en node overføres disse adresser til kernemodulet, som endnu ikke ved, hvordan man arbejder med v2-monitorprotokollen.
Vi ændrer porten for httpMetrics (Prometheus vil gå dertil for at overvåge metrics), så den ikke kommer i konflikt med nginx-proxy, som er installeret af Kubespray. Du har muligvis ikke brug for 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

Lad os gå til Ceph-datalageret for at oprette en separat bruger der. Dokumentationen angiver, at CephFS-provideren kræver adgangsrettigheder til klyngeadministratorer. Men vi vil oprette en separat bruger fs med begrænsede rettigheder:

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 lad os straks se på hans adgangsnøgle, vi får brug for den senere:

ceph auth get-key client.fs

Lad os oprette separate Secret og StorageClass.
Intet nyt, vi har allerede set dette i eksemplet med RBD:

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

Anvendelse af manifestet:

kubectl apply -f secret.yaml

Og nu - en separat 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

Lad os udfylde det her klynge-ID og gældende i Kubernetes:

kubectl apply -f storageclass.yaml

inspektion

For at kontrollere, som i det foregående eksempel, lad os skabe 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 af ​​PVC/PV:

kubectl get pvc
kubectl get pv

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

Lad os gå til en af ​​Ceph-klyndeknuderne og udfø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 af FS på en Ceph node som denne kun egnet til træningsformål, hvilket er hvad vi gør på vores Slurm kurser. Jeg tror ikke, at nogen ville gøre dette i produktionen; der er en høj risiko for ved et uheld at slette vigtige filer.

Og endelig, lad os tjekke, hvordan tingene fungerer med at ændre størrelse på volumener i tilfælde af CephFS. Lad os vende tilbage til Kubernetes og redigere vores manifest for PVC - øge størrelsen der, for eksempel til 7Gi.

Lad os anvende den redigerede fil:

kubectl apply -f pvc.yaml

Lad os se på den monterede mappe for at se, hvordan kvoten har ændret sig:

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

For at denne kommando skal virke, skal du muligvis installere pakken på dit system attr.

Øjnene er bange, men det gør hænderne

Alle disse besværgelser og lange YAML-manifester virker komplicerede på overfladen, men i praksis får Slurm-eleverne ret hurtigt styr på dem.
I denne artikel gik vi ikke dybt ind i junglen – det er der officiel dokumentation for. Hvis du er interesseret i detaljerne om opsætning af Ceph-lagring med en Kubernetes-klynge, vil disse links hjælpe:

Generelle principper for Kubernetes arbejde med volumener
RBD dokumentation
Integration af RBD og Kubernetes fra et Ceph-perspektiv
Integration af RBD og Kubernetes fra et CSI-perspektiv
Generel CephFS-dokumentation
Integration af CephFS og Kubernetes fra et CSI-perspektiv

På Slurm-banen Kubernetes Base du kan gå lidt længere og implementere en rigtig applikation i Kubernetes, der vil bruge CephFS som fillagring. Gennem GET/POST-anmodninger vil du være i stand til at overføre filer til og modtage dem fra Ceph.

Og hvis du er mere interesseret i datalagring, så tilmeld dig nyt kursus om Ceph. Mens beta-testen er i gang, kan kurset opnås med rabat, og du kan påvirke dets indhold.

Forfatter til artiklen: Alexander Shvalov, praktiserende ingeniør Southbridge, Certificeret Kubernetes-administrator, forfatter og udvikler af Slurm-kurser.

Kilde: www.habr.com