k8s对接ceph存储(块存储)使用

前置条件:已有 一台外网服务器(用于镜像转存、yaml文件下载)、ceph 集群和 kubernetes 集群

参考文档:Block Devices and Kubernetes — Ceph Documentation

创建存储池

先在 ceph 集群创建 k8s 的存储池

#                     存储池名   存储池pg数
$ceph osd pool create kubernetes 256

$ ceph df
GLOBAL:
    SIZE        AVAIL       RAW USED     %RAW USED
    15.0GiB     12.0GiB      3.00GiB         20.04
POOLS:
    NAME           ID     USED     %USED     MAX AVAIL     OBJECTS
    kubernetes     1        0B         0       5.62GiB           0

初始化存储池

$ rbd pool init kubernetes

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

$ ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes'

[client.kubernetes]
key = AQD6LhVk7pHCNhAA9B0rqZSHSvSsIP2zMv2K4A==

生成 CEPH-CSI 配置映射

ceph-csi 需要在 Kubernetes 中的 ConfigMap 对象来定义 Ceph 集群的 Ceph 监视器地址。查看 Ceph 集群唯一的 FSID 和 mon 地址:

$ ceph mon dump
dumped monmap epoch 1
epoch 1
fsid 9532a730-ca55-43a2-b9c2-c1dc1d1d37bc
last_changed 2023-03-18 00:52:04.368882
created 2023-03-18 00:52:04.368882
0: 192.168.102.20:6789/0 mon.node1
1: 192.168.102.21:6789/0 mon.node2
2: 192.168.102.22:6789/0 mon.node3

k8s集群中创建并执行 csi-config-map.yaml 文件

替换自己的配置,clusterID 为 fsid 、 mon

$ cat <<EOF > csi-config-map.yaml
---
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    [
      {
        "clusterID": "9532a730-ca55-43a2-b9c2-c1dc1d1d37bc",
        "monitors": [
          "192.168.102.20:6789",
          "192.168.102.21:6789",
          "192.168.102.22:6789"
        ]
      }
    ]
metadata:
  name: ceph-csi-config
EOF
$ kubectl create -f csi-config-map.yaml
configmap/ceph-csi-config created
$ kubectl get configmap -A
NAMESPACE         NAME                                 DATA   AGE
default           ceph-csi-config                      1      47s
default           kube-root-ca.crt                     1      19m
kube-flannel      kube-flannel-cfg                     2      14m
kube-flannel      kube-root-ca.crt                     1      14m
kube-node-lease   kube-root-ca.crt                     1      19m
kube-public       cluster-info                         2      19m
kube-public       kube-root-ca.crt                     1      19m
kube-system       coredns                              1      19m
kube-system       extension-apiserver-authentication   6      19m
kube-system       kube-proxy                           2      19m
kube-system       kube-root-ca.crt                     1      19m
kube-system       kubeadm-config                       1      19m
kube-system       kubelet-config-1.23                  1      19m

最新版本的 ceph-csi 还需要一个额外的 ConfigMap 对象来 定义密钥管理服务 (KMS) 提供程序详细信息。如果未设置 KMS, CSI-KMS-config-map.yaml 文件按以下配置或参考示例 在 https://github.com/ceph/ceph-csi/tree/master/examples/kms

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

执行配置文件

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

最新版本的 ceph-csi 还需要另一个 ConfigMap 对象 定义要添加到 CSI 容器内的 ceph.conf 文件的 Ceph 配置:

$ 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 is a required key and its value should be empty
  keyring: |
metadata:
  name: ceph-config
EOF

执行配置文件

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

生成 CEPH-CSI CEPHX 秘密

Ceph-CSI 需要 Cephx 凭证才能与 Ceph 通信。生成一个类似于以下示例的 csi-rbd-secret.yaml 文件, 使用之前创建的 Kubernetes 用户 ID 和 cephx 密钥:

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

生成后,将新的 Secret 对象存储在 Kubernetes 中:

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

配置 CEPH-CSI 插件

创建所需的 ServiceAccount 和 RBAC ClusterRole/ClusterRoleBinding Kubernetes 对象。这些对象不一定需要自定义 您的 Kubernetes 环境,因此可以从 ceph-csi 部署 YAML 中按原样使用:

$ 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

这里由于网络问题需要手动拉取以下镜像

$ cat *.yaml | grep image:
          image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0
          image: registry.k8s.io/sig-storage/csi-snapshotter:v6.1.0
          image: registry.k8s.io/sig-storage/csi-attacher:v4.0.0
          image: registry.k8s.io/sig-storage/csi-resizer:v1.6.0
          image: quay.io/cephcsi/cephcsi:canary
          image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.6.2

可以使用以下脚本将镜像转存到自己的私有仓库,需替换为自己的仓库路径。

#需要有外网服务器!!!

#!/bin/bash
echo -e "\E[0;41m 私有仓库需要提前登录!! \E[0m \n"

checkEv() {
if [ $1 == 0 ];
then
  echo -e "\E[0;42m 成功 !!!! \E[0m \n"
else
  echo -e "\E[0;41m 失败 !!! \E[0m \n"
fi
}


imagePath=$1
#替换为自己的镜像仓库地址
aliImagePath="registry.cn-chengdu.aliyuncs.com/gcriosa"
imageVersion=`echo ${imagePath} | awk -F\/ '{print $NF}'`

echo -e "\E[0;42m 拉取镜像 !!!! \E[0m \n"
docker pull ${imagePath}
checkEv $?

echo -e "\E[0;42m 镜像路径转换 !!!! \E[0m \n"
docker tag ${imagePath} ${aliImagePath}/${imageVersion}
checkEv $?

echo -e "\E[0;42m 上传到私有仓库 !!!! \E[0m \n"
docker push ${aliImagePath}/${imageVersion}
checkEv $?


echo -e "\E[0;41m 清理镜像!!! \E[0m"
docker rmi ${imagePath}
checkEv $?
docker rmi ${aliImagePath}/${imageVersion}
checkEv $?

使用命令替换为自己的私有仓库路径

sed -i "s/registry.k8s.io\/sig-storage\//registry.cn-chengdu.aliyuncs.com\/gcriosa\//g" *.yaml
sed -i "s/quay.io\/cephcsi\//registry.cn-chengdu.aliyuncs.com\/gcriosa\//g" *.yaml

再次执行,这样就可以拉取自己仓库的镜像

$ kubectl apply -f csi-rbdplugin-provisioner.yaml
$ kubectl apply -f csi-rbdplugin.yaml
$ kubectl get pod -owide
NAME                                        READY   STATUS    RESTARTS        AGE     IP
csi-rbdplugin-j4v86                         3/3     Running   0               7m40s   192.168.102.3
csi-rbdplugin-provisioner-947f4cdc5-mspsn   7/7     Running   0               7m45s   10.244.2.5
csi-rbdplugin-provisioner-947f4cdc5-ptrsz   7/7     Running   1 (4m42s ago)   7m45s   10.244.1.5
csi-rbdplugin-v25zm                         3/3     Running   0               7m40s   192.168.102.3

使用 CEPH 块设备

创建存储类

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

例如,要创建一个映射到上面创建的 kubernetes 池的 ceph-csi StorageClass,可以在确保 “clusterID” 属性与 Ceph 集群的 fsid 匹配:

$ 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: 9532a730-ca55-43a2-b9c2-c1dc1d1d37bc
   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
   fstype: xfs
   imageFormat: "2"
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
   - discard
EOF
$ kubectl apply -f csi-rbd-sc.yaml

请注意,在 Kubernetes v1.14 和 v1.15 中,卷扩展功能处于 alpha 状态 状态和需要启用 ExpandCSIVolumes 功能门。

创建持久卷声明

PersistentVolumeClaim是用户对抽象存储资源的请求。 然后,PersistentVolumeClaim将与Pod资源相关联,以 预配一个持久卷,该卷将由 Ceph 块映像提供支持。 可以包括可选的卷模式,以便在挂载的文件系统之间进行选择 (默认)或基于原始块设备的卷。

使用 ceph-csi,为 volumeMode 指定文件系统可以同时支持 ReadWriteOnce 和 ReadOnlyMany accessMode 声明,为 volumeMode 指定 Block 可以支持 ReadWriteOnce、ReadWriteMany 和 ReadOnlyMany accessMode 声明。

例如,创建一个基于块的 PersistentVolumeClaim,该声明利用 上面创建的基于 ceph-csi 的 StorageClass,以下 YAML 可以是 用于从 CSI-RBD-SC StorageClass 请求原始块存储:

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

下面演示了将上述 PersistentVolumeClaim 作为原始块设备绑定到 Pod 资源的示例:

$ cat <<EOF > raw-block-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-raw-block-volume
spec:
  containers:
    - name: fc-container
      image: nginx:latest
      volumeMounts:
        - mountPath: "/ceph-date"
          name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: raw-block-pvc
EOF
$ kubectl apply -f raw-block-pod.yaml

pod-with-raw-block-volume就是我们创建的pod

$ csi-rbdplugin-j4v86                         3/3     Running   3 (13h ago)     37m
csi-rbdplugin-provisioner-947f4cdc5-bdzh8   7/7     Running   0               19m
csi-rbdplugin-provisioner-947f4cdc5-x64xg   7/7     Running   5 (3m27s ago)   21m
csi-rbdplugin-v25zm                         3/3     Running   3 (16h ago)     37m
pod-with-raw-block-volume                   1/1     Running   0               9m32s

在回到 ceph 集群执行 rbd ls kubernetes,查看发现多了一个镜像文件,镜像文件大小就是 pvc 请求的资源大小

$ rbd ls kubernetes
csi-vol-088bf342-94f7-4ef7-a320-1a951aa7ee9f

$ rbd info kubernetes/csi-vol-088bf342-94f7-4ef7-a320-1a951aa7ee9f
rbd image 'csi-vol-088bf342-94f7-4ef7-a320-1a951aa7ee9f':
        size 1GiB in 256 objects
        order 22 (4MiB objects)
        block_name_prefix: rbd_data.1e54094af269d
        format: 2
        features: layering
        flags:
        create_timestamp: Sun Mar 19 11:38:32 2023

进入pod,就能看见申请的磁盘块已经挂在到/ceph-date文件上了

$ kubectl exec pod-with-raw-block-volume -it -- /bin/bash
$ root@pod-with-raw-block-volume:/# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   55G  0 disk
|-sda1   8:1    0    1G  0 part
|-sda2   8:2    0  3.9G  0 part
`-sda3   8:3    0 50.2G  0 part /etc/hosts
sr0     11:0    1 1024M  0 rom
rbd0   253:0    0    1G  0 disk /ceph-date


在目录下写入文件

$ root@pod-with-raw-block-volume:/ceph-date# echo `date` > date.txt
$ root@pod-with-raw-block-volume:/ceph-date# ls
date.txt
$ root@pod-with-raw-block-volume:/ceph-date# cat date.txt
Sun Mar 19 07:24:24 UTC 2023

验证

回到ceph集群中使用 rbd map 命令将镜像文件映射到当前操作系统中,查看之前在pod中写入的文件

#映射
$ rbd map kubernetes/csi-vol-088bf342-94f7-4ef7-a320-1a951aa7ee9f
/dev/rbd0
#挂载
$ mount /dev/rbd0 /mnt/
$ ls /mnt/
date.txt
$ cat /mnt/date.txt
Sun Mar 19 07:24:24 UTC 2023
#挂载到当前目录的文件及内容相同

#取消挂载
$ umount /dev/rbd0
#取消映射
$ rbd unmap /dev/rbd0
posted @ 2023-03-19 12:14  炒鸡蛋  阅读(786)  评论(0编辑  收藏  举报