Ένα πρακτικό παράδειγμα σύνδεσης αποθήκευσης που βασίζεται σε Ceph σε ένα σύμπλεγμα Kubernetes

Το Container Storage Interface (CSI) είναι μια ενοποιημένη διεπαφή μεταξύ Kubernetes και συστημάτων αποθήκευσης. Έχουμε ήδη μιλήσει για αυτό εν συντομία είπα, και σήμερα θα ρίξουμε μια πιο προσεκτική ματιά στον συνδυασμό CSI και Ceph: θα δείξουμε πώς συνδέστε την αποθήκευση Ceph στο σύμπλεγμα Kubernetes.
Το άρθρο παρέχει πραγματικά, αν και ελαφρώς απλοποιημένα παραδείγματα για ευκολία αντίληψης. Δεν εξετάζουμε το ενδεχόμενο εγκατάστασης και διαμόρφωσης συμπλεγμάτων Ceph και Kubernetes.

Αναρωτιέστε πώς λειτουργεί;

Ένα πρακτικό παράδειγμα σύνδεσης αποθήκευσης που βασίζεται σε Ceph σε ένα σύμπλεγμα Kubernetes

Έτσι, έχετε ένα σύμπλεγμα Kubernetes στα χέρια σας, που έχει αναπτυχθεί, για παράδειγμα, kubespray. Υπάρχει ένα σύμπλεγμα Ceph που λειτουργεί κοντά - μπορείτε επίσης να το εγκαταστήσετε, για παράδειγμα, με αυτό ένα σετ βιβλίων. Ελπίζω να μην χρειάζεται να αναφέρω ότι για παραγωγή μεταξύ τους πρέπει να υπάρχει δίκτυο με εύρος ζώνης τουλάχιστον 10 Gbit/s.

Αν τα έχεις όλα αυτά, πάμε!

Αρχικά, ας πάμε σε έναν από τους κόμβους του συμπλέγματος Ceph και ας ελέγξουμε ότι όλα είναι εντάξει:

ceph health
ceph -s

Στη συνέχεια, θα δημιουργήσουμε αμέσως μια πισίνα για δίσκους RBD:

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

Ας περάσουμε στο σύμπλεγμα Kubernetes. Εκεί, πρώτα απ 'όλα, θα εγκαταστήσουμε το πρόγραμμα οδήγησης Ceph CSI για το RBD. Θα εγκαταστήσουμε, όπως αναμένεται, μέσω του Helm.
Προσθέτουμε ένα αποθετήριο με ένα γράφημα, παίρνουμε ένα σύνολο μεταβλητών για το γράφημα ceph-csi-rbd:

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

Τώρα πρέπει να συμπληρώσετε το αρχείο cephrbd.yml. Για να το κάνετε αυτό, μάθετε το αναγνωριστικό συμπλέγματος και τις διευθύνσεις IP των οθονών στο Ceph:

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

Εισάγουμε τις λαμβανόμενες τιμές στο αρχείο cephrbd.yml. Ταυτόχρονα, ενεργοποιούμε τη δημιουργία πολιτικών PSP (Pod Security Policies). Επιλογές σε ενότητες nodeplugin и προμηθευτής ήδη στο αρχείο, μπορούν να διορθωθούν όπως φαίνεται παρακάτω:

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

Στη συνέχεια, το μόνο που μας μένει είναι να εγκαταστήσουμε το γράφημα στο σύμπλεγμα Kubernetes.

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

Υπέροχα, ο οδηγός RBD λειτουργεί!
Ας δημιουργήσουμε ένα νέο StorageClass στο Kubernetes. Αυτό απαιτεί και πάλι λίγη τσαχπινιά με τον Ceph.

Δημιουργούμε έναν νέο χρήστη στο Ceph και του δίνουμε δικαιώματα να γράφει στο pool κύβος:

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

Τώρα ας δούμε ότι το κλειδί πρόσβασης είναι ακόμα εκεί:

ceph auth get-key client.rbdkube

Η εντολή θα δώσει κάτι σαν αυτό:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Ας προσθέσουμε αυτήν την τιμή στο Secret στο σύμπλεγμα Kubernetes - όπου τη χρειαζόμαστε κλειδί του χρήστη:

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

Και δημιουργούμε το μυστικό μας:

kubectl apply -f secret.yaml

Στη συνέχεια, χρειαζόμαστε μια δήλωση StorageClass κάπως έτσι:

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

Πρέπει να συμπληρωθεί clusterID, που έχουμε ήδη μάθει από την ομάδα ceph fsid, και εφαρμόστε αυτό το μανιφέστο στο σύμπλεγμα Kubernetes:

kubectl apply -f storageclass.yaml

Για να ελέγξουμε πώς συνεργάζονται τα συμπλέγματα, ας δημιουργήσουμε το ακόλουθο PVC (Αξίωση μόνιμου όγκου):

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

Ας δούμε αμέσως πώς ο Kubernetes δημιούργησε τον ζητούμενο τόμο στο Ceph:

kubectl get pvc
kubectl get pv

Όλα δείχνουν να είναι υπέροχα! Πώς φαίνεται αυτό από την πλευρά του Κεφ;
Λαμβάνουμε μια λίστα με τους τόμους στην πισίνα και προβάλλουμε πληροφορίες σχετικά με τον τόμο μας:

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

Τώρα ας δούμε πώς λειτουργεί η αλλαγή μεγέθους ενός τόμου RBD.
Αλλάξτε το μέγεθος του όγκου στο μανιφέστο pvc.yaml σε 2Gi και εφαρμόστε το:

kubectl apply -f pvc.yaml

Ας περιμένουμε να ισχύσουν οι αλλαγές και ας δούμε ξανά το μέγεθος της έντασης.

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

kubectl get pv
kubectl get pvc

Βλέπουμε ότι το μέγεθος του PVC δεν έχει αλλάξει. Για να μάθετε γιατί, μπορείτε να ρωτήσετε την Kubernetes για μια περιγραφή YAML του PVC:

kubectl get pvc rbd-pvc -o yaml

Εδώ είναι το πρόβλημα:

μήνυμα: Αναμονή για να (επαν)εκκινήσει ο χρήστης μια ομάδα αρχείων για να ολοκληρωθεί η αλλαγή μεγέθους του τόμου του συστήματος αρχείων στον κόμβο. τύπος: FileSystemResizePending

Δηλαδή, ο δίσκος έχει μεγαλώσει, αλλά το σύστημα αρχείων σε αυτόν όχι.
Για να αναπτύξετε το σύστημα αρχείων, πρέπει να προσαρτήσετε τον τόμο. Στη χώρα μας το δημιουργημένο PVC/PV δεν χρησιμοποιείται επί του παρόντος με κανέναν τρόπο.

Μπορούμε να δημιουργήσουμε ένα test Pod, για παράδειγμα ως εξής:

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

Και τώρα ας δούμε το PVC:

kubectl get pvc

Το μέγεθος έχει αλλάξει, όλα είναι καλά.

Στο πρώτο μέρος, δουλέψαμε με τη συσκευή μπλοκ RBD (αντιπροσωπεύει Rados Block Device), αλλά αυτό δεν μπορεί να γίνει εάν διαφορετικές μικροϋπηρεσίες πρέπει να εργαστούν με αυτόν τον δίσκο ταυτόχρονα. Το CephFS είναι πολύ πιο κατάλληλο για εργασία με αρχεία παρά με εικόνες δίσκου.
Χρησιμοποιώντας το παράδειγμα των συμπλεγμάτων Ceph και Kubernetes, θα διαμορφώσουμε το CSI και άλλες απαραίτητες οντότητες για να συνεργαστούν με το CephFS.

Ας πάρουμε τις τιμές από το νέο διάγραμμα Helm που χρειαζόμαστε:

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

Και πάλι πρέπει να συμπληρώσετε το αρχείο cephfs.yml. Όπως και πριν, οι εντολές Ceph θα βοηθήσουν:

ceph fsid
ceph mon dump

Συμπληρώστε το αρχείο με τιμές όπως αυτή:

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

Λάβετε υπόψη ότι οι διευθύνσεις οθόνης καθορίζονται στην απλή φόρμα διεύθυνση:port. Για την προσάρτηση των cephfs σε έναν κόμβο, αυτές οι διευθύνσεις μεταφέρονται στη μονάδα πυρήνα, η οποία δεν γνωρίζει ακόμη πώς να λειτουργεί με το πρωτόκολλο παρακολούθησης v2.
Αλλάζουμε τη θύρα για το httpMetrics (ο Prometheus θα πάει εκεί για μετρήσεις παρακολούθησης) ώστε να μην έρχεται σε διένεξη με το nginx-proxy, το οποίο εγκαθίσταται η Kubespray. Μπορεί να μην το χρειάζεστε αυτό.

Εγκαταστήστε το διάγραμμα Helm στο σύμπλεγμα Kubernetes:

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

Ας πάμε στο χώρο αποθήκευσης δεδομένων Ceph για να δημιουργήσουμε έναν ξεχωριστό χρήστη εκεί. Η τεκμηρίωση αναφέρει ότι ο πάροχος CephFS απαιτεί δικαιώματα πρόσβασης διαχειριστή συμπλέγματος. Αλλά θα δημιουργήσουμε έναν ξεχωριστό χρήστη fs με περιορισμένα δικαιώματα:

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'

Και ας δούμε αμέσως το κλειδί πρόσβασής του, θα το χρειαστούμε αργότερα:

ceph auth get-key client.fs

Ας δημιουργήσουμε ξεχωριστά Secret και StorageClass.
Τίποτα νέο, το έχουμε ήδη δει στο παράδειγμα του RBD:

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

Εφαρμογή της δήλωσης:

kubectl apply -f secret.yaml

Και τώρα - μια ξεχωριστή 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

Ας το συμπληρώσουμε εδώ clusterID και ισχύει στο Kubernetes:

kubectl apply -f storageclass.yaml

Проверка

Για να ελέγξουμε, όπως στο προηγούμενο παράδειγμα, ας δημιουργήσουμε ένα PVC:

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

Και ελέγξτε την παρουσία PVC/PV:

kubectl get pvc
kubectl get pv

Εάν θέλετε να δείτε αρχεία και καταλόγους στο CephFS, μπορείτε να προσαρτήσετε αυτό το σύστημα αρχείων κάπου. Για παράδειγμα όπως φαίνεται παρακάτω.

Ας πάμε σε έναν από τους κόμβους του συμπλέγματος Ceph και ας εκτελέσουμε τις ακόλουθες ενέργειες:

# Точка монтирования
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

Φυσικά, η τοποθέτηση FS σε έναν κόμβο Ceph είναι κατάλληλη μόνο για εκπαιδευτικούς σκοπούς, κάτι που κάνουμε στο δικό μας Μαθήματα Slurm. Δεν νομίζω ότι κάποιος θα το έκανε αυτό στην παραγωγή· υπάρχει μεγάλος κίνδυνος κατά λάθος διαγραφής σημαντικών αρχείων.

Και τέλος, ας ελέγξουμε πώς λειτουργούν τα πράγματα με την αλλαγή μεγέθους τόμων στην περίπτωση του CephFS. Ας επιστρέψουμε στο Kubernetes και ας επεξεργαστούμε το μανιφέστο μας για PVC - αυξήστε το μέγεθος εκεί, για παράδειγμα, σε 7Gi.

Ας εφαρμόσουμε το επεξεργασμένο αρχείο:

kubectl apply -f pvc.yaml

Ας δούμε τον προσαρτημένο κατάλογο για να δούμε πώς έχει αλλάξει το όριο:

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

Για να λειτουργήσει αυτή η εντολή, ίσως χρειαστεί να εγκαταστήσετε το πακέτο στο σύστημά σας attr.

Τα μάτια φοβούνται, αλλά τα χέρια το κάνουν

Όλα αυτά τα ξόρκια και οι μεγάλες εκδηλώσεις YAML φαίνονται περίπλοκα στην επιφάνεια, αλλά στην πράξη, οι μαθητές Slurm τα καταφέρνουν πολύ γρήγορα.
Σε αυτό το άρθρο δεν μπήκαμε βαθιά στη ζούγκλα - υπάρχει επίσημη τεκμηρίωση για αυτό. Εάν ενδιαφέρεστε για τις λεπτομέρειες της ρύθμισης του χώρου αποθήκευσης Ceph με ένα σύμπλεγμα Kubernetes, αυτοί οι σύνδεσμοι θα σας βοηθήσουν:

Γενικές αρχές της εργασίας Kubernetes με τόμους
Τεκμηρίωση RBD
Ενσωμάτωση RBD και Kubernetes από την οπτική γωνία του Ceph
Ενσωμάτωση RBD και Kubernetes από την οπτική γωνία του CSI
Γενική τεκμηρίωση CephFS
Ενσωμάτωση CephFS και Kubernetes από την οπτική γωνία του CSI

Στο μάθημα Slurm Βάση Kubernetes μπορείτε να προχωρήσετε λίγο πιο πέρα ​​και να αναπτύξετε μια πραγματική εφαρμογή στο Kubernetes που θα χρησιμοποιεί το CephFS ως αποθήκευση αρχείων. Μέσω αιτημάτων GET/POST θα μπορείτε να μεταφέρετε αρχεία και να τα λαμβάνετε από τον Ceph.

Και αν σας ενδιαφέρει περισσότερο η αποθήκευση δεδομένων, εγγραφείτε νέο μάθημα για τον Κεφ. Ενώ η δοκιμή beta βρίσκεται σε εξέλιξη, το μάθημα μπορεί να αποκτηθεί με έκπτωση και μπορείτε να επηρεάσετε το περιεχόμενό του.

Συντάκτης του άρθρου: Alexander Shvalov, ασκούμενος μηχανικός Southbridge, Πιστοποιημένος Διαχειριστής Kubernetes, συγγραφέας και προγραμματιστής μαθημάτων Slurm.

Πηγή: www.habr.com