No menu items!
No menu items!
More

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

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email