Ceph RBD 与 StorageClass 绑定

相关文档解释

Block Devices and Kubernetes — Ceph Documentation

存储类 | Kubernetes

k8s通过rbd使用ceph,pvc在线扩容

# 配置文件解释
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.16.153.105:6789
  adminId: kube
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret-user
  userSecretNamespace: default
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"
allowVolumeExpansion: true
  • monitors:Ceph monitor,逗号分隔。该参数是必需的。

  • adminId:Ceph 客户端 ID,用于在池 ceph 池中创建 image 。默认是 "admin"。

  • adminSecretadminId 的 Secret 名称。该参数是必需的。 提供的 secret 必须有值为 "kubernetes.io/rbd" 的 type 参数。

  • adminSecretNamespaceadminSecret 的命名空间。默认是 "default"。

  • pool: Ceph RBD 池. 默认是 "rbd"。

  • userId:Ceph 客户端 ID,用于映射 RBD 镜像。默认与 adminId 相同。

  • userSecretName:用于映射 RBD 镜像的 userId 的 Ceph Secret 的名字。 它必须与 PVC 存在于相同的 namespace 中。该参数是必需的。 提供的 secret 必须具有值为 "kubernetes.io/rbd" 的 type 参数,例如以这样的方式创建:

    kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
      --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \
      --namespace=kube-system
    
  • userSecretNamespaceuserSecretName 的命名空间。

  • fsType:Kubernetes 支持的 fsType。默认:"ext4"

  • imageFormat:Ceph RBD 镜像格式,"1" 或者 "2"。默认值是 "1"。

  • imageFeatures:这个参数是可选的,只能在你将 imageFormat 设置为 "2" 才使用。 目前支持的功能只是 layering。默认是 "",没有功能打开

  • allowVolumeExpansion: 如果对PVC扩容,则其对应的"storage class"中allowVolumeExpansion字段需要设置成true

具体步骤

您可以使用 Ceph Block 设备 image 与 Kubernetes v1.13 和以后通过ceph-csi,它动态地提供 RBD image 以支持 Kubernetes 卷,并映射这些 RBD image 作为块设备(可选地安装 image 中包含的文件系统)在运行线程的运行窗格,以引用 RBD 支持的卷。 Ceph 设备 image 作为整个群集的对象进行块设备管理,这意味着大型 Ceph Block 设备 image 比独立服务器具有更好的性能!

若要将 Ceph Block 设备与 Kubernetes v1.13 及更高版本一起使用,必须在 Kubernetes 环境中安装和配置。下图描述了 Kubernetes/Ceph。ceph-csi

注意: ceph-csi默认使用 RBD 内核模块,它可能不支持所有 Ceph CRUSH 可调谐或 RBD image 功能

imageFormat: "2" imageFeatures: "layering"

创建 Pool

默认情况下,Ceph 块设备使用池。为 Kubernetes 卷存储创建池。确保 Ceph 群集正在运行,然后创建池。rbd

$ ceph osd pool create kubernetes

新创建的池在使用前必须先初始化。使用该工具初始化池:rbd

$ rbd pool init kubernetes

配置 CEPH-CSI

设置 CEPH 客户端身份验证

为 kubernetes 和 ceph-csi 创建一个新用户。执行以下操作并记录生成的密钥:

注意:

目前版本可能存在 Bug, kubernetes 用户在进行认证授权后,k8s 生成的 pod 申请PVC 的时候会显示认证失败,使用 admin 用户就没有此问题。所以建议直接采用 admin 用户

$ ceph auth list
client.admin
        key: AQBvGNtf5hzJERAAvnOqP+1AkODNYL43/dssGA==
        caps: [mds] allow *
        caps: [mgr] allow *
        caps: [mon] allow *
        caps: [osd] allow *
# OR
$ ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
[client.kubernetes]
    key = AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==

生成CEPH-CSI 配置映射

ceph-csi需要存储在 Kubernetes 中的ConfigMap对象来定义 Ceph 群集的 Ceph 监视器地址。收集 Ceph 群集唯一 fsid和监视器地址:

[root@node1 ~]# ceph mon dump

fsid 3f5560c6-3af3-4983-89ec-924e8eaa9e06

[root@node1 ~]# ceph -s
  cluster:
    id:     3f5560c6-3af3-4983-89ec-924e8eaa9e06
    health: HEALTH_OK

注意 ceph-csi目前仅支持传统的V1 协议

生成类似于以下示例的 csi-config-map.yaml文件,将fsid替换为"clusterID",将监视器地址替换为"监视器":

$ cat <<EOF > csi-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    [
      {
        "clusterID": "3f5560c6-3af3-4983-89ec-924e8eaa9e06",
        "monitors": [
          "192.168.6.160:6789",
          "192.168.6.161:6789",
          "192.168.6.162:6789"
        ]
      }
    ]
metadata:
  name: ceph-csi-config
EOF

生成后,将新的ConfigMap 对象存储在 kubernetes :

$ kubectl apply -f csi-config-map.yaml

生成CEPH -CSI CEPHX Secret

ceph-csi需要 cephx 凭据才能与 Ceph 群集通信。使用新创建的 Kubernetes 用户 ID 和 cephx 密钥生成类似于以下示例的csi-rbd-secret.yaml文件:

注意:

因为kubernetes用户会报错,我使用的 admin 用户

$ cat <<EOF > csi-rbd-secret.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: default
stringData:
  userID: admin # 用户名
  userKey: AQBvGNtf5hzJERAAvnOqP+1AkODNYL43/dssGA== # 用户key
EOF

生成后,将新的机密对象存储在 kubernetes :

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

配置CEPH-CSI插件

创建所需的ServiceAccount和 RBAC群集区域/群集区域绑定 kubernetes 对象。这些对象不一定需要针对您的 Kubernetes 环境进行自定义,因此可以从ceph-csi 部署 YAM使用:

$ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
$ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml

最后,创建ceph-csi预配和节点插件。除了ceph-csi 容器发布版本之外,这些对象不一定需要针对您的 Kubernetes 环境进行自定义,因此可以按样使用ceph-csi部署 YAML:

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

默认会缺少一个 kms-csi 的一个文件, 导致生成 pod 的时候会报错

kms-config GitHub地址

$ cat kms-config.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    {
      "vault-test": {
        "encryptionKMSType": "vault",
        "vaultAddress": "http://vault.default.svc.cluster.local:8200",
        "vaultAuthPath": "/v1/auth/kubernetes/login",
        "vaultRole": "csi-kubernetes",
        "vaultPassphraseRoot": "/v1/secret",
        "vaultPassphrasePath": "ceph-csi/",
        "vaultCAVerify": "false"
      },
      "vault-tokens-test": {
          "encryptionKMSType": "vaulttokens",
          "vaultAddress": "http://vault.default.svc.cluster.local:8200",
          "vaultBackendPath": "secret/",
          "vaultTLSServerName": "vault.default.svc.cluster.local",
          "vaultCAVerify": "false",
          "tenantConfigName": "ceph-csi-kms-config",
          "tenantTokenName": "ceph-csi-kms-token",
          "tenants": {
              "my-app": {
                  "vaultAddress": "https://vault.example.com",
                  "vaultCAVerify": "true"
              },
              "an-other-app": {
                  "tenantTokenName": "storage-encryption-token"
              }
          }
       }
    }
metadata:
  name: ceph-csi-encryption-kms-config

$ kubectl apply -f kms-config.yaml

重要说明 预配器和节点插件YAM将默认提取ceph-csi 容器(quay.io/cephcsi/cephcsi:canary)。应更新 YAML 以将发布版本容器用于生产工作负载。

使用 CEPH 块设备

创建存储类

Kubernetes存储类定义存储类。可以创建多个 StorageClass 对象以映射到不同的服务质量级别(即 NVMe 与基于 HDD 的池)和功能。

例如,若要创建映射到上面创建的kubernetes池的ceph-csi存储类,在确保"clusterID"属性与 Ceph 群集的fsid匹配后,可以使用以下 YAML 文件:

$ cat <<EOF > csi-rbd-sc.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: 3f5560c6-3af3-4983-89ec-924e8eaa9e06
   pool: kubernetes
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: default
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: default
   imageFormat: "2"
   imageFeatures: "layering"
reclaimPolicy: Delete
mountOptions:
   - discard
EOF
$ kubectl apply -f csi-rbd-sc.yaml

创建 PVC

PVC 是用户对抽象存储资源的请求。然后, PVC 将关联到Pod资源以预配持久卷,该资源将由 Ceph 块 image 支持。可以选择可选的 VolumeMode,用于在装载的文件系统(默认)或基于原始块设备的卷之间进行选择。

使用ceph-csi ,为卷模式指定文件系统可以同时支持读取写入一个和读取单一多访问模式声明,而指定卷模式的块可以支持读取写入一下,读取写入多,和读取单一多访问模式声明。

例如,要创建一个基于块的 PVC ,该声明利用上面创建的基于 ceph-csi的存储类,可以使用以下 YAML 从csi-rbd-sc 存储类请求原始块存储:

$ cat <<EOF > raw-block-pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: raw-block-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Block
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc
EOF
$ kubectl apply -f raw-block-pvc.yaml

演示 pod 绑定 RBD 模式 PVC

$ cat <<EOF > raw-block-pod.yaml
---
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
EOF
$ kubectl apply -f raw-block-pod.yaml

若要创建使用上面创建的基于ceph-csi 的基于 cephfs PVC ,可以使用以下 YAML 从csi-rbd-sc存储类请求装载的文件系统(由 RBD image 支持) :

$ cat <<EOF > pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc
EOF
$ kubectl apply -f pvc.yaml

演示 Pod 绑定 cephfs 的 PVC:

$ cat <<EOF > pod.yaml
---
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
EOF
$ kubectl apply -f pod.yaml