Ceph tabanlı depolamayı Kubernetes kümesine bağlamanın pratik bir örneği

Konteyner Depolama Arayüzü (CSI), Kubernetes ile depolama sistemleri arasında birleşik bir arayüzdür. Zaten kısaca bahsetmiştik söyledive bugün CSI ve Ceph kombinasyonuna daha yakından bakacağız: nasıl olduğunu göstereceğiz Ceph depolama birimini bağlayın Kubernetes kümesine.
Makale, algılama kolaylığı için biraz basitleştirilmiş de olsa gerçek örnekler sunmaktadır. Ceph ve Kubernetes kümelerini kurmayı ve yapılandırmayı düşünmüyoruz.

Nasıl çalıştığını merak mı ediyorsunuz?

Ceph tabanlı depolamayı Kubernetes kümesine bağlamanın pratik bir örneği

Yani parmaklarınızın ucunda konuşlandırılmış bir Kubernetes kümesi var; kubespray. Yakınlarda çalışan bir Ceph kümesi var - bunu örneğin bununla da kurabilirsiniz bir dizi oyun kitabı. Umarım aralarında üretim için en az 10 Gbit/s bant genişliğine sahip bir ağ olması gerektiğini belirtmeye gerek yoktur.

Bunların hepsine sahipseniz gidelim!

Öncelikle Ceph küme düğümlerinden birine gidelim ve her şeyin yolunda olup olmadığını kontrol edelim:

ceph health
ceph -s

Daha sonra hemen RBD diskleri için bir havuz oluşturacağız:

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

Kubernetes kümesine geçelim. Orada öncelikle RBD için Ceph CSI sürücüsünü kuracağız. Beklendiği gibi Helm aracılığıyla kurulum yapacağız.
Bir grafik içeren bir depo ekliyoruz, seph-csi-rbd grafiği için bir dizi değişken elde ediyoruz:

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

Şimdi cephrbd.yml dosyasını doldurmanız gerekiyor. Bunu yapmak için Ceph'teki monitörlerin küme kimliğini ve IP adreslerini bulun:

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

Elde edilen değerleri cephrbd.yml dosyasına giriyoruz. Aynı zamanda PSP politikalarının (Pod Güvenlik Politikaları) oluşturulmasına da olanak sağlıyoruz. Bölümlerdeki seçenekler düğüm eklentisi и sağlayıcı dosyada zaten mevcutsa aşağıda gösterildiği gibi düzeltilebilir:

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

Daha sonra bize kalan tek şey grafiği Kubernetes kümesine kurmak.

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

Harika, RBD sürücüsü çalışıyor!
Kubernetes'te yeni bir StorageClass oluşturalım. Bu yine Ceph ile biraz uğraşmayı gerektiriyor.

Ceph'te yeni bir kullanıcı oluşturup ona havuza yazma hakkı veriyoruz Kube:

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

Şimdi erişim anahtarının hâlâ orada olduğunu görelim:

ceph auth get-key client.rbdkube

Komut şunun gibi bir çıktı verecektir:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Bu değeri Kubernetes kümesindeki Secret'a (ihtiyacımız olan yere) ekleyelim Kullanıcı anahtarı:

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

Ve sırrımızı yaratıyoruz:

kubectl apply -f secret.yaml

Daha sonra, şunun gibi bir StorageClass bildirimine ihtiyacımız var:

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

Doldurulması gerekiyor küme kimliğiekip tarafından zaten öğrendiğimiz cep fsidve bu bildirimi Kubernetes kümesine uygulayın:

kubectl apply -f storageclass.yaml

Kümelerin birlikte nasıl çalıştığını kontrol etmek için aşağıdaki PVC'yi (Kalıcı Hacim Talebi) oluşturalım:

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

Kubernetes'in Ceph'te istenen birimi nasıl oluşturduğunu hemen görelim:

kubectl get pvc
kubectl get pv

Her şey harika görünüyor! Bu Ceph tarafında nasıl görünüyor?
Havuzdaki birimlerin bir listesini alıyoruz ve birimimizle ilgili bilgileri görüntülüyoruz:

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

Şimdi bir RBD birimini yeniden boyutlandırmanın nasıl çalıştığını görelim.
Pvc.yaml bildirimindeki birim boyutunu 2Gi olarak değiştirin ve uygulayın:

kubectl apply -f pvc.yaml

Değişikliklerin geçerli olmasını bekleyip birim boyutuna tekrar bakalım.

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

kubectl get pv
kubectl get pvc

PVC'nin boyutunun değişmediğini görüyoruz. Nedenini öğrenmek için Kubernetes'te PVC'nin YAML açıklamasını sorgulayabilirsiniz:

kubectl get pvc rbd-pvc -o yaml

Sorun şu:

ileti: Düğümdeki birimin dosya sistemi yeniden boyutlandırılmasını tamamlamak için kullanıcının bir bölmeyi (yeniden) başlatması bekleniyor. tür: FileSystemResizePending

Yani disk büyümüştür ancak üzerindeki dosya sistemi büyümemiştir.
Dosya sistemini büyütmek için birimi bağlamanız gerekir. Ülkemizde üretilen PVC/PV şu anda hiçbir şekilde kullanılmamaktadır.

Örneğin şöyle bir test Pod oluşturabiliriz:

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

Şimdi PVC'ye bakalım:

kubectl get pvc

Boyut değişti, her şey yolunda.

İlk bölümde RBD blok cihazı (Rados Block Device anlamına gelir) ile çalıştık ancak farklı mikro servislerin bu diskle aynı anda çalışması gerekiyorsa bu yapılamaz. CephFS, disk görüntüleri yerine dosyalarla çalışmak için çok daha uygundur.
Ceph ve Kubernetes kümeleri örneğini kullanarak CSI ve diğer gerekli varlıkları CephFS ile çalışacak şekilde yapılandıracağız.

İhtiyacımız olan yeni Helm grafiğinden değerleri alalım:

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

Yine cephfs.yml dosyasını doldurmanız gerekiyor. Daha önce olduğu gibi Ceph komutları yardımcı olacaktır:

ceph fsid
ceph mon dump

Dosyayı aşağıdaki gibi değerlerle doldurun:

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

Monitör adreslerinin basit adres:bağlantı noktası şeklinde belirtildiğini lütfen unutmayın. Cephfs'i bir düğüme monte etmek için bu adresler, v2 monitör protokolüyle nasıl çalışacağını henüz bilmeyen çekirdek modülüne aktarılır.
Kubespray tarafından yüklenen nginx-proxy ile çakışmaması için httpMetrics bağlantı noktasını değiştiriyoruz (Prometheus, ölçümleri izlemek için oraya gidecektir). Buna ihtiyacınız olmayabilir.

Helm grafiğini Kubernetes kümesine yükleyin:

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

Orada ayrı bir kullanıcı oluşturmak için Ceph veri deposuna gidelim. Belgeler, CephFS sağlayıcısının küme yöneticisi erişim haklarına ihtiyaç duyduğunu belirtir. Ancak ayrı bir kullanıcı oluşturacağız fs sınırlı haklarla:

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'

Ve hemen erişim anahtarına bakalım, ona daha sonra ihtiyacımız olacak:

ceph auth get-key client.fs

Ayrı Secret ve StorageClass oluşturalım.
Yeni bir şey yok, bunu zaten RBD örneğinde gördük:

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

Manifest'in uygulanması:

kubectl apply -f secret.yaml

Ve şimdi - ayrı bir 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

Burayı dolduralım küme kimliği ve Kubernetes'te uygulanabilir:

kubectl apply -f storageclass.yaml

Kontrol

Kontrol etmek için önceki örnekte olduğu gibi bir PVC oluşturalım:

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

Ve PVC/PV'nin varlığını kontrol edin:

kubectl get pvc
kubectl get pv

CephFS'deki dosya ve dizinlere bakmak istiyorsanız bu dosya sistemini bir yere monte edebilirsiniz. Örneğin aşağıda gösterildiği gibi.

Ceph küme düğümlerinden birine gidelim ve aşağıdaki eylemleri gerçekleştirelim:

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

Elbette FS'yi bu şekilde bir Ceph düğümüne monte etmek yalnızca eğitim amaçlıdır ve biz de bunu yapıyoruz. Slurm kursları. Üretimde kimsenin bunu yapacağını sanmıyorum; önemli dosyaların kazara silinmesi riski yüksek.

Son olarak CephFS örneğinde hacimlerin yeniden boyutlandırılmasında işlerin nasıl yürüdüğünü kontrol edelim. Kubernetes'e dönelim ve PVC için bildirimimizi düzenleyelim - oradaki boyutu örneğin 7Gi'ye artıralım.

Düzenlenen dosyayı uygulayalım:

kubectl apply -f pvc.yaml

Kotanın nasıl değiştiğini görmek için eklenen dizine bakalım:

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

Bu komutun çalışması için paketi sisteminize yüklemeniz gerekebilir. özellik.

Gözler korkuyor ve eller yapıyor

Tüm bu büyüler ve uzun YAML manifestoları ilk bakışta karmaşık görünse de pratikte Slurm öğrencileri bunları oldukça çabuk kavrarlar.
Bu yazıda ormanın derinliklerine inmedik - bunun için resmi belgeler var. Kubernetes kümesiyle Ceph depolama alanı kurmanın ayrıntılarıyla ilgileniyorsanız şu bağlantılar yardımcı olacaktır:

Kubernetes'in birimlerle çalışmasının genel ilkeleri
RBD Belgeleri
RBD ve Kubernetes'i Ceph perspektifinden entegre etme
RBD ve Kubernetes'i CSI perspektifinden entegre etme
Genel CephFS Belgeleri
CephFS ve Kubernetes'i CSI perspektifinden entegre etme

Slurm rotasında Kubernetes Üssü biraz daha ileri giderek Kubernetes'te CephFS'yi dosya depolama alanı olarak kullanacak gerçek bir uygulamayı dağıtabilirsiniz. GET/POST istekleri aracılığıyla dosyaları Ceph'e aktarabilecek ve Ceph'ten alabileceksiniz.

Veri depolamayla daha çok ilgileniyorsanız, o zaman kaydolun Ceph'te yeni kurs. Beta testi devam ederken kursu indirimli olarak alabilir ve içeriğine etki edebilirsiniz.

Makalenin yazarı: Alexander Shvalov, pratik mühendis Güney köprüsü, Sertifikalı Kubernetes Yöneticisi, Slurm kurslarının yazarı ve geliştiricisi.

Kaynak: habr.com