前言
上篇讲了ceph集群的搭建,这篇就来对接k8s存储。
ceph对接k8s在比较新的k8s版本中废弃了对ceph的官方支持,转为社区维护ceph-csi驱动,但是纵观我能搜索到的网上的中文教程,还有驱动官方的readme,都写的不咋样。
ceph接入k8s常见的有两种方式,一种是ceph-rbd,另一种是ceph-fs,两者各有优劣,网上也有性能测试,对k8s而言,rbd不支持ReadWriteMany模式。这篇就来讲讲cephfs和k8s是如何对接的。
正文
cephfs接入k8s
打开驱动官方github地址。由于我们的k8s集群版本是1.29,因此驱动版本就使用3.11.0。
打开deploy-cephfs.md.可以看到教程很复杂,需要部署好几个yaml,但其实根本没那么复杂。。。最简单的方法就是helm.
helm是k8s的包管理工具,可以理解成pip或者npm的作用。官方其实提供了chart包供我们使用。
先安装helm,记得export代理
1 | curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 |
安装完成后添加csi的repo
1 | helm repo add ceph-csi https://ceph.github.io/csi-charts |
先创建k8s命名空间,然后安装ceph-csi-cephfs
1 | kubectl create namespace ceph-csi-cephfs |
可以加上--version
指定版本
等待安装部署完成。
部署完成后,可以在kubepi上看到ceph-csi-cephfs-nodeplugin和ceph-csi-cephfs-provisioner容器在三个节点上运行,说明就成功了,接下来我们就配置如何和ceph对接。
cephfs pool创建
我们需要在ceph上创建两个pool用于构建cephfs,在主节点执行
1 | ceph osd pool create cephfs_k8s_metadata 64 |
最后一个参数pg_num与osd数量相关,我只有三个osd因此我只能设置到64.
接着创建ceph fs
1 | ceph fs new cephfs_k8s cephfs_k8s_metadata cephfs_k8s_data |
设置mds
1 | ceph fs set cephfs_k8s max_mds 2 |
创建subvolumegroup
1 | ceph fs subvolumegroup create cephfs_k8s csi |
我们创建获取两个token用于后续k8s与ceph通信。
1 | // 注意 client.k8s.cephfs必须以client开头 |
分别获取k8s.cephfs和admin的token
利用storageclass自动创建pv
首先我们在ceph-csi-cephfs命名空间下可以看到名为ceph-csi-config的configMap,我们要修改它。主要修改的是config.json的内容。其中clusterID可用通过ceph -s获取。
1 | kubectl edit configmap ceph-csi-config -n ceph-csi-cephfs |
创建secret,将上面获取的两个token填入,vim ceph-secret.yaml
1 | apiVersion: v1 |
接着我们创建storageclass,vim storageclass.yaml
1 |
|
部署secret和storageclass
1 | kubectl apply -f ceph-secret.yaml |
至此,申请pvc时,将会自动向ceph集群申请存储卷,并自动创建pv。
创建测试容器
先创建一个pvc。
1 | --- |
记得apply一下。
如果发现pv无法自动创建出来,记得检查下密码或者subvolume是否创建出来,可以到csi-provisioner看看日志。
再创建一个nginx测试好了,vim nginx-deployment.yaml
1 | apiVersion: apps/v1 |
apply一下看看。
1 | kubectl get pods |
如果容器不是pending,那么说明挂载成功了。我们获取访问端口看看。
1 | nginx-service NodePort 10.43.24.66 <none> 80:31162/TCP 29h app=nginx-pod |
这里提示403是正常的,因为我们挂载的根节点没有东西。
我们进入容器内随意加点东西,可以通过kubepi的进入终端方便一点,也可以kubectl exec -it nginx-deployment-7c565ff488-qqfkz -- /bin/bash
1 | cd /usr/share/nginx/html/ |
再访问发现正常了。
接下来我们结束容器让其重新部署看看。
1 | kubectl delete pod nginx-deployment-7c565ff488-qqfkz |
刚才pod部署在节点3,现在删除后重新部署在了节点2,再次访问http://worker1:31162/
可以看到我们的更改还在。
至此我们便完成了cephfs与k8s的对接,值得一提的是这种方式是支持动态扩容的。只需修改pvc的容量,pv的容量也会自动调整。
至此我们搭建就完成了,但是也存在一些问题。
问题
经常性自动创建PV失败
当声明pvc后,csi-ceph的插件容器会自动向ceph集群创建volume,GRPC调用/csi.v1.Controller/CreateVolume,但是第一次请求总是没有响应,可能是因为超时,所以后续会重复调用CreateVolume,导致后续请求响应都是an operation with the given Volume ID xxx already exists
.我看了下默认的超时时间是60s,provisioner.timeout
,可能是我ceph集群性能不好,没找到原因,但是我重启虚拟机后又正常了,奇怪。
pv无法自动回收
通过storageclass创建的pv,当删除pvc时,pv会被标记为release,但是回收会出现问题,导致pv资源一直存在。看了容器日志应该是和ceph集群通信有问题,导致删除失败,GRPC调用/csi.v1.Controller/DeleteVolume似乎超时了,后续再调用时和上面问题一样一直出现 already exists。这个目前没有找到解决办法。
自动回收不适用生产环境
storageclass中的reclaimPolicy应该修改为Retain,保证数据安全。
总结
尽管搭建了ceph集群,并且使用cephfs对接了k8s,但实际上体验不是很好,不知道是虚拟硬盘导致的ceph集群问题,还是本身就有bug存在,总之一番体验下来,不建议使用cephfs对接k8s。
至于为什么不手动创建pv,是因为网上那些例子其实都是过时的,从k8s1.28开始就已经将pv里的spec.cephfs标记为过时了,并且这种方式需要在pv里声明monitor的地址列表,当pv数量足够多时很难去管理。
目前上一家公司用的就是ceph-rbd对接的k8s。看下后续的ceph-rbd对接能不能有更好的体验,如果还是存在问题,那就是我的ceph集群有问题。