Thursday, November 21, 2024

Sử dụng Rados Block Device với Kubernetes

-

1. Tổng quan về Block Device và Kubernetes.

Trong Kubernetes, Ceph Block Devices có thể được sử dụng từ phiên bản 1.13 trở đi thông qua một công cụ gọi là ceph-csi. Công cụ này giúp cung cấp tự động các RBD images (Rados Block Device) để làm phần lưu trữ trong Kubernetes và ánh xạ các RBD images này như các block device trên các máy chủ chạy các container ví dụ như pods trong Kubernetes. Điều này cho phép các ứng dụng trong Kubernetes sử dụng các ổ đĩa RBD để lưu trữ dữ liệu của họ.

Hình dung Ceph chia nhỏ các block device images thành các đối tượng và phân phối chúng trên toàn cụm máy chủ Ceph. Điều này có nghĩa là các Ceph Block Device image lớn hơn có hiệu suất tốt hơn so với việc sử dụng một máy chủ đơn lẻ làm lưu trữ.

Để sử dụng Ceph Block Device với Kubernetes phiên bản 1.13 trở lên, bạn cần cài đặt và cấu hình ceph-csi trong môi trường Kubernetes của bạn. Hình dưới đây mô tả cấu trúc công nghệ của Kubernetes và Ceph khi hoạt động cùng nhau.

Quan trọng
Ceph-csi mặc định sử dụng các module kernel RBD, có thể không hỗ trợ tất cả các cấu hình CRUSH hay tính năng RBD images của Ceph.

2. Tạo một Pool.

Mặc định, các Ceph block device sử dụng pool rbd. Để tạo một pool để lưu trữ dữ liệu cho ổ đĩa của Kubernetes, bạn cần đảm bảo rằng cụm Ceph của bạn đang hoạt động, sau đó thực hiện các bước sau:

  • Tạo pool bằng lệnh sau:
$ ceph osd pool create kubernetes
pool 'kubernetes' created
Lưu ý: bạn có thể cần xác định số lượng pg_num đặt cho pool của bạn. Hãy xem Create a Pool để biết chi tiết về cách chỉ định số lượng pg_num đặt cho pool và Placement Groups của bạn.
  • Sau khi tạo pool, bạn cần khởi tạo pool này trước khi sử dụng. Sử dụng công cụ rbd để khởi tạo pool như sau:
rbd pool init kubernetes

Lệnh này sẽ thực hiện quá trình khởi tạo cho pool kubernetes của bạn, cho phép bạn sử dụng nó để lưu trữ dữ liệu cho các ổ đĩa trong Kubernetes.

Lưu ý: Lệnh này nếu chạy thành công thì bạn sẽ không nhìn thấy output nhé.

3. Cấu hình Ceph-CSI.

3.1. Thiết lập xác thực Ceph Client.

Để cấu hình xác thực client Ceph cho Kubernetes và ceph-csi, bạn cần tạo một người dùng mới và ghi lại key được tạo bằng cách tạo một người dùng mới với tên “client.kubernetes” và cấu hình quyền truy cập cho nó sử dụng lệnh dưới, kết quả của lệnh trên sẽ hiển thị thông tin về người dùng “client.kubernetes”, bao gồm cả key.

$ ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
[client.kubernetes]
        key = AQD2sydlqy1rLhAAIan+HqmcldxyZTPr7n3rFg==

Lệnh này sẽ tạo một người dùng với quyền truy cập đến pool “kubernetes” trong Ceph. Hãy ghi nhớ key được tạo,vì bạn sẽ cần nó cho các bước tiếp theo.

3.2. Tạo Ceph-CSI Configmap.

Ceph-CSI yêu cầu một ConfigMap được lưu trữ trong Kubernetes để xác định các địa chỉ Ceph monitor của cụm Ceph. Bạn cần thu thập thông tin về fsid và địa chỉ IP Ceph monitor của cụm Ceph. Bạn có thể làm như sau:

  • Sử dụng lệnh sau để lấy thông tin về fsid và các địa chỉ IP của Ceph monitor:
$ ceph mon dump
epoch 11
fsid 1d447334-e065-4745-b494-99bc76c7dff8
last_changed 2023-07-12T21:55:43.494947+0700
created 2023-05-23T21:40:20.987182+0700
min_mon_release 16 (pacific)
election_strategy: 1
0: [v2:192.168.13.226:3300/0,v1:192.168.13.226:6789/0] mon.pve-node2
1: [v2:192.168.13.227:3300/0,v1:192.168.13.227:6789/0] mon.pve-node3
2: [v2:192.168.13.225:3300/0,v1:192.168.13.225:6789/0] mon.pve-node1
dumped monmap epoch 11

Lưu ý fsid là1d447334-e065-4745-b494-99bc76c7dff8 và các địa chỉ Ceph monitor là "192.168.13.225:6789", "192.168.13.226:6789", "192.168.13.227:6789".

  • Tiếp theo, tạo một file YAML, ví dụ csi-config-map.yaml để định nghĩa ConfigMap cho ceph-csi. Bạn có thể sử dụng lệnh sau:
cat <<EOF > csi-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    [
      {
        "clusterID": "1d447334-e065-4745-b494-99bc76c7dff8",
        "monitors": [
          "192.168.13.225:6789",
          "192.168.13.226:6789",
          "192.168.13.227:6789"
        ]
      }
    ]
metadata:
  name: ceph-csi-config
EOF

Sau khi tạo file YAML, bạn có thể áp dụng ConfigMap này trong Kubernetes bằng lệnh dưới:

$ kubectl apply -f csi-config-map.yaml
configmap/ceph-csi-config created

Lưu ý, phiên bản gần đây của ceph-csi cũng yêu cầu một ConfigMap bổ sung để xác định thông tin về Key Management Service (KMS) provider.

Nếu bạn không sử dụng KMS, bạn có thể tạo một ConfigMap trống hoặc tham khảo ví dụ tại đây: https://github.com/ceph/ceph-csi/tree/master/examples/kms.

Do mình không sử dụng KMS nên mình sẽ tạo file ceph-config-map.yaml trống như sau:

cat <<EOF > ceph-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    {}    
metadata:
  name: ceph-csi-encryption-kms-config
  namespace: default
EOF

Cuối cùng để lưu ConfigMap mới trong Kubernetes, bạn có thể sử dụng lệnh dưới:

kubectl apply -f ceph-config-map.yaml

Phiên bản gần đây của ceph-csi cũng yêu cầu một ConfigMap bổ sung để xác định cấu hình Ceph để thêm vào file ceph.conf bên trong các container CSI. Bạn có thể tạo một file YAML, ví dụ ceph-config-map.yaml để định nghĩa ConfigMap này và sau đó áp dụng nó vào Kubernetes:

cat <<EOF > ceph-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  ceph.conf: |
    [global]
    auth_cluster_required = cephx
    auth_service_required = cephx
    auth_client_required = cephx
  keyring: |
metadata:
  name: ceph-config
EOF

Triển khai ConfigMap mới này trong Kubernetes:

$ kubectl apply -f ceph-config-map.yaml
configmap/ceph-config created

Bây giờ bạn đã cấu hình các ConfigMap cần thiết cho ceph-csi để làm việc với Ceph cluster trong Kubernetes.

4. Tạo Ceph-CSI, Cephx Secret.

Ceph-csi yêu cầu thông tin xác thực cephx để giao tiếp với cụm Ceph. Bạn cần tạo một file YAML, ví dụ csi-rbd-secret.yaml để định nghĩa Secret cho ceph-csi, sử dụng thông tin về người dùng và key cephx đã tạo trước đó.

Bạn có thể sử dụng lệnh sau:

cat <<EOF > csi-rbd-secret.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: default
stringData:
  userID: kubernetes
  userKey: AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==
EOF

Lưu ý rằng trong file YAML này:

  • userID là tên người dùng Ceph đã được tạo (trong ví dụ này, là “kubernetes”).
  • userKey là key cephx tương ứng với người dùng (đã được cung cấp trong bước tạo người dùng trước đó).

Sau khi tạo file YAML này, bạn có thể triển khai Secret mới trong Kubernetes bằng lệnh sau:

$ kubectl apply -f csi-rbd-secret.yaml
secret/csi-rbd-secret created

Bây giờ bạn đã tạo và lưu trữ thông tin xác thực cephx trong một Secret để sử dụng cho ceph-csi khi giao tiếp với cụm Ceph trong Kubernetes.

5. Cấu hình Ceph-CSI Plugins.

Để cấu hình các plugin của ceph-csi, bạn cần tạo các đối tượng Kubernetes như ServiceAccount, RBAC ClusterRole và ClusterRoleBinding. Đối tượng này không cần phải được tùy chỉnh đặc biệt cho môi trường Kubernetes của bạn và có thể được sử dụng các file YAML có sẵn của ceph-csi. Dưới đây là các bước cụ thể:

Triển khai file csi-provisioner-rbac.yaml để tạo các đối tượng ServiceAccount và RBAC ClusterRole/ClusterRoleBindingi.

$ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
serviceaccount/rbd-csi-provisioner created
clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role created
role.rbac.authorization.k8s.io/rbd-external-provisioner-cfg created
rolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role-cfg created

Triển khai file csi-nodeplugin-rbac.yaml.

$ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml
serviceaccount/rbd-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin created

Cuối cùng, tạo các plugin ceph-csi provisioner và node plugin. Trừ khi bạn có nhu cầu đặc biệt, các đối tượng này không cần phải được tùy chỉnh cho môi trường Kubernetes của bạn và có thể sử dụng các file YAML có sẵn của ceph-csi như ở trên.

Tải về file YAML cho ceph-csi provisioner.

wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml

Và triển khai nó.

kubectl apply -f csi-rbdplugin-provisioner.yaml

Tải về file YAML cho ceph-csi node plugin.

wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin.yaml

Và tiếp tục triển khai nó.

$ kubectl apply -f csi-rbdplugin.yaml
daemonset.apps/csi-rbdplugin created
service/csi-metrics-rbdplugin created
Lưu ý quan trọng:
Mặc định, các file YAML cho provisioner và node plugin sẽ sử dụng phiên bản container development (development release) của ceph-csi (quay.io/cephcsi/cephcsi:canary). Tuy nhiên, trong môi trường production, bạn nên cập nhật file YAML để sử dụng phiên bản container ổn định (release version) của ceph-csi thay vì phiên bản development.

6. Sử dụng Ceph Block Device tạo một Storageclass.

Trong Kubernetes, StorageClass là định nghĩa cho một lớp lưu trữ. Có thể tạo nhiều đối tượng StorageClass để ánh xạ tới các dịch vụ lưu trữ khác nhau (ví dụ: lưu trữ dựa trên NVMe so với lưu trữ dựa trên HDD) và tính năng khác nhau.

6.1. Nếu bạn chưa biết về reclaimPolicy thì đọc thêm phần 6.1 này, nếu đã biết rồi thì bỏ qua nó và xem tiếp phần 6.2.

reclaimPolicy trong Kubernetes StorageClass quy định cách các tài nguyên PersistentVolumes (PVs) nên được xử lý sau khi PersistentVolumeClaims (PVCs) không còn được sử dụng. Có hai giá trị chính cho reclaimPolicy: “Retain” và “Delete,” và chúng khác nhau như sau:

  • Retain:
    • Khi reclaimPolicy được đặt thành “Retain,” PVs sẽ không bị xoá sau khi PVCs không còn được sử dụng hoặc bị xoá. Thay vào đó, PVs sẽ tiếp tục tồn tại và chờ sẵn sàng để bạn có thể thực hiện xử lý thủ công sau này.
    • Điều này có ích khi bạn muốn giữ lại dữ liệu trên PVs cho mục đích sao lưu hoặc kiểm tra sau khi PVCs không còn được sử dụng.
  • Delete:
    • Khi reclaimPolicy được đặt thành “Delete,” PVs sẽ bị xoá khi PVCs không còn được sử dụng hoặc bị xoá. Hệ thống Kubernetes sẽ tự động xóa các PVs không còn được sử dụng theo cài đặt này.
    • Điều này có thể hữu ích khi bạn không còn quan tâm đến dữ liệu trên PVs và muốn tiết kiệm tài nguyên lưu trữ bằng cách xoá các PVs không còn sử dụng.

6.2. Cách tạo Storage Class.

  • Tạo StorageClass với reclaimPolicy là Retain.

Ví dụ, để tạo một StorageClass sử dụng ceph-csi và ánh xạ tới pool “kubernetes” mà bạn đã tạo trước đó, bạn có thể sử dụng file YAML sau, đảm bảo rằng thuộc tính “clusterID” khớp với fsid của cụm Ceph của bạn:

cat <<EOF > csi-rbd-sc-delete.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc-delete
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: 1d447334-e065-4745-b494-99bc76c7dff8
   pool: kubernetes
   imageFeatures: layering
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: default
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: default
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
   - discard
EOF

Sau khi tạo file YAML này, bạn có thể áp dụng StorageClass mới này trong Kubernetes bằng lệnh sau:

$ kubectl apply -f csi-rbd-sc-delete.yaml
storageclass.storage.k8s.io/csi-rbd-sc-delete created

Kết quả.

$ kubectl get storageclass
NAME                PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-rbd-sc-delete   rbd.csi.ceph.com   Delete          Immediate           true                   119s                2m46s
  • Tạo storageclass với reclaimPolicy là Retain.

Lưu ý, một khi bạn đã cấu hình reclaimPolicy cho StorageClass, bạn không thể thay đổi nó. Và như vậy khi bạn tạo một StorageClass với một reclaimPolicy, điều này sẽ áp dụng cho tất cả PersistentVolumeClaims (PVCs) được tạo bằng StorageClass đó. Tuy nhiên, sau khi PVC đã được tạo, bạn không thể thay đổi reclaimPolicy cho PVC đó hoặc cho StorageClass mà PVC đó đang sử dụng.

Nếu bạn muốn sử dụng reclaimPolicy khác, bạn sẽ phải tạo một StorageClass mới với giá trị reclaimPolicy mà bạn muốn. Sau đó, bạn có thể sử dụng StorageClass mới này khi tạo PVCs để đảm bảo rằng chúng sử dụng reclaimPolicy mới.

cat <<EOF > csi-rbd-sc-retain.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc-retain
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: 1d447334-e065-4745-b494-99bc76c7dff8
   pool: kubernetes
   imageFeatures: layering
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: default
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: default
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Retain  # Đây là ví dụ của một reclaimPolicy khác.
allowVolumeExpansion: true
mountOptions:
   - discard
EOF

Áp dụng mainifest.

$ kubectl apply -f csi-rbd-sc-retain.yaml
storageclass.storage.k8s.io/csi-rbd-sc-retain created

Sau đó, bạn có thể sử dụng StorageClass “csi-rbd-sc-retain” khi bạn tạo PVCs và chúng sẽ tuân theo reclaimPolicy mới.

Sau khi bạn tạo thêm StorageClass với reclaimPolicy là Retain, bạn sẽ có kết quả với 2 StorageClass như sau:

$ kubectl get storageclass
NAME                PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-rbd-sc-delete   rbd.csi.ceph.com   Delete          Immediate           true                   119s
csi-rbd-sc-retain   rbd.csi.ceph.com   Retain          Immediate           true                   2m46s

Lưu ý, trong Kubernetes phiên bản 1.14 và 1.15, tính năng mở rộng block device (volume expansion) đang ở trạng thái alpha và yêu cầu bật tính năng “ExpandCSIVolumes”.

7. Tạo Persistentvolumeclaim.

PersistentVolumeClaim (PVC) là một yêu cầu được người dùng gửi để yêu cầu cho phép sử dụng tài nguyên. PVC này sau đó sẽ được liên kết với một tài nguyên Pod để cung cấp một PersistentVolume. Bạn có thể tùy chọn volumeMode để xác định liệu PVC nên là Filesystem (mặc định) hay là raw block storage.

Sử dụng ceph-csi, việc xác định volumeMode là Filesystem có thể hỗ trợ cả ReadWriteOnce và ReadOnlyMany accessMode. Khi xác định volumeMode là Block, có thể hỗ trợ cả ReadWriteOnce, ReadWriteMany, và ReadOnlyMany accessMode.

Ví dụ 1, tạo PVC dựa trên Block-Based.

Để tạo một PVC dựa trên block-based và sử dụng StorageClass ceph-csi đã được tạo trước đó, bạn có thể sử dụng file YAML sau để yêu cầu lưu trữ raw block storage từ StorageClass csi-rbd-sc:

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

Sau khi tạo PVC này, bạn có thể liên kết nó với một Pod để sử dụng PVC như một RAW Device.

Ví dụ 2, tạo PVC với Filesystem (Filesystem-Based).

Để tạo một PVC dựa trên file-system-based và sử dụng StorageClass ceph-csi, bạn có thể sử dụng file YAML sau để yêu cầu một Filesystem được mount từ StorageClass csi-rbd-sc:

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

Sau khi tạo PVC này, bạn có thể mount nó với một Pod để sử dụng PVC như một Filesystem.

Ví dụ 3, llên kết PVC với Pod (Block-Based).

Dưới đây là ví dụ về cách liên kết PVC dựa trên Block Storage với một Pod để sử dụng nó như một raw block device

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-raw-block-volume
spec:
  containers:
    - name: fc-container
      image: fedora:26
      command: ["/bin/sh", "-c"]
      args: ["tail -f /dev/null"]
      volumeDevices:
        - name: data
          devicePath: /dev/xvda
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: raw-block-pvc

Ví dụ 4, liên kết PVC với Pod (Filesystem-Based).

Dưới đây là ví dụ về cách liên kết PVC dựa trên Filesystem với một Pod để sử dụng nó như một Filesystem.

apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
        - name: mypvc
          mountPath: /var/lib/www/html
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

Chú ý cuối cùng:

  • Bạn có thể tùy chỉnh các thông số trong các file YAML trên, ví dụ như kích thước lưu trữ (storage size), tên PVC (PVC name), và các tùy chọn khác để phù hợp với nhu cầu cụ thể của bạn.
  • Các PVC có thể được sử dụng để yêu cầu lưu trữ từ một StorageClass. Trong ví dụ này, chúng ta đã sử dụng StorageClass có tên là “csi-rbd-sc” mà bạn đã tạo trước đó.
  • Điều quan trọng là khi tạo PVC, bạn cần đảm bảo rằng StorageClass phù hợp với yêu cầu của PVC và cung cấp đủ các tùy chọn yêu cầu cho PVC như kích thước lưu trữ.
  • Các Pod sau đó có thể liên kết với các PVC để sử dụng lưu trữ này cho các ứng dụng và dịch vụ của bạn.

Hy vọng rằng các ví dụ trên đã giúp bạn hiểu cách tạo và sử dụng PersistentVolumeClaim trong Kubernetes để quản lý lưu trữ ứng dụng của bạn.

Tài liệu tham khảo https://docs.ceph.com/en/latest/rbd/rbd-kubernetes/.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories