Một ví dụ thực tế về kết nối bộ lưu trữ dựa trên Ceph với cụm Kubernetes

Giao diện lưu trữ container (CSI) là giao diện hợp nhất giữa Kubernetes và hệ thống lưu trữ. Chúng ta đã nói chuyện ngắn gọn về nó rồi nói, а сегодня подробнее рассмотрим связку CSI и Ceph: покажем, как kết nối bộ lưu trữ Ceph đến cụm Kubernetes.
Bài viết đưa ra những ví dụ thực tế tuy hơi đơn giản để bạn dễ hình dung. Chúng tôi không xem xét việc cài đặt và định cấu hình cụm Ceph và Kubernetes.

Bạn đang tự hỏi nó hoạt động như thế nào?

Một ví dụ thực tế về kết nối bộ lưu trữ dựa trên Ceph với cụm Kubernetes

Vì vậy, bạn có một cụm Kubernetes trong tầm tay, được triển khai, chẳng hạn như kubespray. Có một cụm Ceph đang hoạt động gần đó - ví dụ: bạn cũng có thể cài đặt nó bằng cái này một bộ vở kịch. Tôi hy vọng không cần phải đề cập rằng để sản xuất giữa chúng phải có mạng có băng thông ít nhất là 10 Gbit/s.

Nếu bạn có tất cả những điều này, hãy đi!

Trước tiên, hãy đi đến một trong các nút cụm Ceph và kiểm tra xem mọi thứ có theo thứ tự không:

ceph health
ceph -s

Tiếp theo, chúng tôi sẽ tạo ngay một nhóm cho các đĩa RBD:

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

Hãy chuyển sang cụm Kubernetes. Ở đó, trước hết chúng ta sẽ cài đặt trình điều khiển Ceph CSI cho RBD. Chúng tôi sẽ cài đặt như mong đợi thông qua Helm.
Chúng tôi thêm một kho lưu trữ có biểu đồ, chúng tôi nhận được một tập hợp các biến cho biểu đồ ceph-csi-rbd:

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

Bây giờ bạn cần điền vào tệp cephrbd.yml. Để thực hiện việc này, hãy tìm ra cluster ID và địa chỉ IP của màn hình trong Ceph:

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

Chúng ta nhập các giá trị thu được vào file cephrbd.yml. Đồng thời, chúng tôi cho phép tạo chính sách PSP (Chính sách bảo mật Pod). Tùy chọn trong phần nút nút и người cung cấp đã có trong tệp, chúng có thể được sửa như dưới đây:

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

Tiếp theo, tất cả những gì còn lại của chúng ta là cài đặt biểu đồ trong cụm Kubernetes.

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

Tuyệt vời, trình điều khiển RBD hoạt động!
Hãy tạo một StorageClass mới trong Kubernetes. Điều này một lần nữa đòi hỏi phải mày mò một chút với Ceph.

Chúng tôi tạo một người dùng mới trong Ceph và cấp cho anh ta quyền ghi vào nhóm khối lập phương:

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

Bây giờ hãy xem khóa truy cập vẫn còn ở đó:

ceph auth get-key client.rbdkube

Lệnh sẽ xuất ra một cái gì đó như thế này:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Hãy thêm giá trị này vào Secret trong cụm Kubernetes - nơi chúng ta cần userKey:

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

Và chúng tôi tạo ra bí mật của mình:

kubectl apply -f secret.yaml

Tiếp theo, chúng ta cần một bảng kê khai StorageClass như thế này:

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

Cần phải điền ID cụm, điều mà nhóm chúng tôi đã học được cephfsidvà áp dụng bảng kê khai này cho cụm Kubernetes:

kubectl apply -f storageclass.yaml

Để kiểm tra cách các cụm hoạt động cùng nhau, hãy tạo PVC (Yêu cầu khối lượng liên tục) sau đây:

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

Hãy cùng xem ngay cách Kubernetes tạo khối lượng được yêu cầu trong Ceph:

kubectl get pvc
kubectl get pv

Mọi thứ dường như đều tuyệt vời! Điều này trông như thế nào về phía Ceph?
Chúng tôi nhận được danh sách các tập trong nhóm và xem thông tin về khối lượng của chúng tôi:

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

Bây giờ hãy xem cách thay đổi kích thước ổ đĩa RBD hoạt động như thế nào.
Thay đổi kích thước âm lượng trong tệp kê khai PVC.yaml thành 2Gi và áp dụng nó:

kubectl apply -f pvc.yaml

Chúng ta hãy đợi những thay đổi có hiệu lực và xem lại kích thước âm lượng.

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

kubectl get pv
kubectl get pvc

Chúng tôi thấy kích thước của PVC không thay đổi. Để tìm hiểu lý do, bạn có thể truy vấn Kubernetes để biết mô tả YAML của PVC:

kubectl get pvc rbd-pvc -o yaml

Đây là vấn đề:

thông báo: Đang chờ người dùng (khởi động lại) một nhóm để hoàn tất việc thay đổi kích thước ổ đĩa hệ thống tệp trên nút. loại: FileSystemResizePending

Nghĩa là, đĩa đã phát triển nhưng hệ thống tệp trên đó thì không.
Để phát triển hệ thống tập tin, bạn cần gắn âm lượng. Ở nước ta, PVC/PV được tạo ra hiện không được sử dụng dưới bất kỳ hình thức nào.

Chúng ta có thể tạo một Test Pod, ví dụ như thế này:

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

Và bây giờ hãy nhìn vào PVC:

kubectl get pvc

Kích thước đã thay đổi, mọi thứ đều ổn.

Trong phần đầu tiên, chúng ta đã làm việc với thiết bị khối RBD (viết tắt của Rados Block Device), nhưng điều này không thể thực hiện được nếu các vi dịch vụ khác nhau cần hoạt động đồng thời với đĩa này. CephFS phù hợp hơn nhiều để làm việc với các tệp thay vì hình ảnh đĩa.
Sử dụng ví dụ về cụm Ceph và Kubernetes, chúng tôi sẽ định cấu hình CSI và các thực thể cần thiết khác để hoạt động với CephFS.

Hãy lấy các giá trị từ biểu đồ Helm mới mà chúng ta cần:

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

Một lần nữa bạn cần điền vào tệp cephfs.yml. Như trước đây, các lệnh Ceph sẽ giúp:

ceph fsid
ceph mon dump

Điền vào tệp với các giá trị như thế này:

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

Xin lưu ý rằng địa chỉ màn hình được chỉ định ở dạng đơn giản address:port. Để gắn cephfs trên một nút, các địa chỉ này được chuyển đến mô-đun hạt nhân, mô-đun này chưa biết cách hoạt động với giao thức giám sát v2.
Chúng tôi thay đổi cổng cho httpMetrics (Prometheus sẽ đến đó để theo dõi số liệu) để cổng này không xung đột với nginx-proxy do Kubespray cài đặt. Bạn có thể không cần điều này.

Cài đặt biểu đồ Helm trong cụm Kubernetes:

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

Chúng ta hãy đến kho dữ liệu Ceph để tạo một người dùng riêng ở đó. Tài liệu nêu rõ rằng nhà cung cấp CephFS yêu cầu quyền truy cập của quản trị viên cụm. Nhưng chúng tôi sẽ tạo một người dùng riêng fs với quyền hạn chế:

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'

Và hãy xem ngay khóa truy cập của anh ấy, chúng ta sẽ cần nó sau:

ceph auth get-key client.fs

Hãy tạo Secret và StorageClass riêng biệt.
Không có gì mới, chúng ta đã thấy điều này trong ví dụ về RBD:

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

Áp dụng bảng kê khai:

kubectl apply -f secret.yaml

Và bây giờ - một StorageClass riêng biệt:

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

Hãy điền vào đây ID cụm và áp dụng trong Kubernetes:

kubectl apply -f storageclass.yaml

Проверка

Để kiểm tra, như trong ví dụ trước, hãy tạo PVC:

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

Và kiểm tra sự hiện diện của PVC/PV:

kubectl get pvc
kubectl get pv

Nếu bạn muốn xem các tập tin và thư mục trong CephFS, bạn có thể gắn hệ thống tập tin này vào đâu đó. Ví dụ như hình dưới đây.

Hãy đi đến một trong các nút cụm Ceph và thực hiện các hành động sau:

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

Tất nhiên, việc gắn FS trên nút Ceph như thế này chỉ phù hợp cho mục đích đào tạo, đó là những gì chúng tôi làm trên nút Ceph của mình. Các khóa học ở khu ổ chuột. Tôi không nghĩ có ai sẽ làm điều này trong quá trình sản xuất; có nguy cơ cao vô tình xóa các tập tin quan trọng.

Và cuối cùng, hãy kiểm tra xem mọi thứ hoạt động như thế nào với việc thay đổi kích thước khối lượng trong trường hợp CephFS. Hãy quay lại Kubernetes và chỉnh sửa tệp kê khai của chúng tôi cho PVC - ví dụ: tăng kích thước ở đó lên 7Gi.

Hãy áp dụng tập tin đã chỉnh sửa:

kubectl apply -f pvc.yaml

Hãy nhìn vào thư mục được gắn để xem hạn ngạch đã thay đổi như thế nào:

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

Để lệnh này hoạt động, bạn có thể cần cài đặt gói trên hệ thống của mình attr.

Đôi mắt sợ hãi, nhưng đôi tay đang làm

Tất cả các phép thuật và biểu hiện YAML dài này bề ngoài có vẻ phức tạp, nhưng trên thực tế, học sinh Slurm sẽ hiểu rõ chúng khá nhanh.
Trong bài viết này, chúng tôi không đi sâu vào rừng - có tài liệu chính thức về điều đó. Nếu bạn quan tâm đến chi tiết thiết lập bộ lưu trữ Ceph với cụm Kubernetes, các liên kết này sẽ giúp:

Nguyên tắc chung của Kubernetes làm việc với khối lượng
Tài liệu RBD
Tích hợp RBD và Kubernetes từ góc độ Ceph
Tích hợp RBD và Kubernetes từ góc độ CSI
Tài liệu chung về CephFS
Tích hợp CephFS và Kubernetes từ góc độ CSI

Trong khóa học Slurm Cơ sở Kubernetes bạn có thể tiến xa hơn một chút và triển khai một ứng dụng thực trong Kubernetes sẽ sử dụng CephFS làm nơi lưu trữ tệp. Thông qua các yêu cầu GET/POST, bạn sẽ có thể chuyển tệp đến và nhận chúng từ Ceph.

Và nếu bạn quan tâm hơn đến việc lưu trữ dữ liệu thì hãy đăng ký khóa học mới về Ceph. Trong khi quá trình thử nghiệm beta đang diễn ra, khóa học có thể được giảm giá và bạn có thể tác động đến nội dung của nó.

Tác giả bài viết: Alexander Shvalov, kỹ sư thực hành Cầu nam, Quản trị viên Kubernetes được chứng nhận, tác giả và nhà phát triển các khóa học Slurm.

Nguồn: www.habr.com