基於 Ceph 的存儲連接到 Kubernetes 集群的實際示例

容器儲存介面(CSI)是 Kubernetes 和儲存系統之間的統一介面。 我們已經簡單地討論過了 告訴,今天我們將仔細研究 CSI 和 Ceph 的組合:我們將展示如何 連接 Ceph 存儲 到 Kubernetes 叢集。
為了便於理解,本文提供了真實但稍微簡化的範例。 我們不考慮安裝和設定Ceph和Kubernetes叢集。

您想知道它是如何工作的嗎?

基於 Ceph 的存儲連接到 Kubernetes 集群的實際示例

因此,您已經擁有一個觸手可及的 Kubernetes 集群,例如已部署: 庫貝噴霧。 附近有一個 Ceph 叢集正在運行 - 您也可以安裝它,例如,使用以下命令 一套劇本。 我希望無需提及,為了進行生產,它們之間必須有一個頻寬至少為 10 Gbit/s 的網路。

如果你擁有這一切,我們就出發吧!

首先,讓我們轉到一個 Ceph 叢集節點並檢查一切是否正常:

ceph health
ceph -s

接下來,我們將立即為 RBD 磁碟建立一個池:

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

讓我們繼續討論 Kubernetes 叢集。 首先,我們將為 RBD 安裝 Ceph CSI 驅動程式。 我們將按照預期透過 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 檔案。 為此,請找出 Ceph 中監視器的群集 ID 和 IP 位址:

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

我們將獲得的值輸入到cephrbd.yml檔案中。 在此過程中,我們支援建立 PSP 策略(Pod 安全策略)。 部分選項 節點插件 и 供應商 已在文件中,可以按如下所示更正它們:

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 驅動程式工作了!
讓我們在 Kubernetes 中建立一個新的 StorageClass。 這又需要對 Ceph 進行一些修改。

我們在 Ceph 中建立一個新使用者並授予他寫入池的權限 庫貝:

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

現在讓我們看看存取金鑰仍然存在:

ceph auth get-key client.rbdkube

該命令將輸出如下內容:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

讓我們將此值新增至 Kubernetes 叢集中的 Secret - 我們需要它的地方 使用者金鑰:

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

需要填寫 簇ID,我們團隊已經了解了 頭孢夫西德,並將此清單套用到 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

一切似乎都很棒! 這在 Ceph 方面看起來是什麼樣的?
我們取得池中卷的清單並查看有關磁碟區的資訊:

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 以取得 PVC 的 YAML 描述:

kubectl get pvc rbd-pvc -o yaml

問題是這樣的:

訊息:等待使用者(重新)啟動 Pod 以完成節點上捲的檔案系統大小調整。 類型:FileSystemResizePending

也就是說,磁碟成長了,但其上的檔案系統卻沒有成長。
要擴展檔案系統,您需要安裝磁碟區。 在我國,目前還沒有以任何方式使用所創造的 PVC/PV。

我們可以建立一個測試 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 區塊裝置),但如果不同的微服務需要同時使用該磁碟,則無法完成此操作。 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

請注意,監視器位址以位址:連接埠的簡單形式指定。 為了在節點上掛載 cephfs,這些位址會傳送到核心模組,而核心模組還不知道如何使用 v2 監控協定。
我們更改 httpMetrics 的連接埠(Prometheus 將去那裡監視指標),以便它不會與 Kubespray 安裝的 nginx-proxy 衝突。 你可能不需要這個。

在 Kubernetes 叢集中安裝 Helm Chart:

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

我們在這裡填寫一下 簇ID 並適用於 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

當然,像這樣在Ceph節點上安裝FS只適合訓練目的,這就是我們在我們的程式上所做的 泥漿課程。 我認為沒有人會在生產中這樣做;意外刪除重要文件的風險很高。

最後,讓我們檢查一下在 CephFS 的情況下如何調整磁碟區大小。 讓我們回到 Kubernetes 並編輯 PVC 的清單 - 增加那裡的大小,例如,增加到 7Gi。

讓我們套用編輯後的文件:

kubectl apply -f pvc.yaml

我們查看掛載的目錄,看看配額發生了怎樣的變化:

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

要使此命令起作用,您可能需要在系統上安裝該軟體包 屬性.

眼睛害怕,但手卻害怕

所有這些咒語和冗長的 YAML 清單表面上看起來很複雜,但實際上,Slurm 的學生很快就掌握了它們的竅門。
在本文中,我們沒有深入叢林 - 有相關的官方文件。 如果您對使用 Kubernetes 叢集設定 Ceph 儲存的詳細資訊感興趣,這些連結將會有所幫助:

Kubernetes 使用卷的一般原則
RBD 文檔
從Ceph角度整合RBD和Kubernetes
從CSI角度整合RBD和Kubernetes
一般 CephFS 文檔
從CSI角度整合CephFS和Kubernetes

在 Slurm 課程上 Kubernetes 基地 您可以更進一步,在 Kubernetes 中部署一個真實的應用程序,該應用程式將使用 CephFS 作為檔案儲存。 透過 GET/POST 請求,您將能夠向 Ceph 傳輸檔案並從 Ceph 接收檔案。

如果您對資料儲存更感興趣,請註冊 Ceph 的新課程。 當 Beta 測試正在進行時,您可以以折扣價獲得該課程,並且您可以影響其內容。

文章作者:Alexander Shvalov,執業工程師 南橋,經過認證的 Kubernetes 管理員、Slurm 課程的作者和開發者。

來源: www.habr.com