企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] ### **准备Ceph集群和Kubernetes集群** 首先,我们需要准备一个Ceph集群,安装好CephFS。参考教程 https://www.kancloud.cn/pshizhsysu/ceph/1978070#3CephFS_57 准备好一个K8S集群(本实验中k8s集群的版本为v1.17.3,一个节点,内核为4.19.12);另外,在K8S集群的每个节点上执行以下命令安装ceph ``` $ sudo yum -y install ceph ``` ### **创建secret以保存keyring** 由于访问ceph集群需要身份验证(在kubernetes中我们打算直接使用ceph的admin用户),所以我们先把admin用户的keyring保存在kubernetes的secret中。 我们不能把keyring的内容直接保存在secret中,而要先经过base64编码。假设`ceph.client.admin.keyring`文件(在ceph集群Monitor节点的`/etc/ceph/`目录下)的内容如下: ``` [client.admin] key = AQBRCtFci+UPKxAAvifYirfhtgEMGP46mkre+A== ``` 我们对key进行base64编码,得到 ``` $ echo -n "AQBRCtFci+UPKxAAvifYirfhtgEMGP46mkre+A==" | base64 QVFCUkN0RmNpK1VQS3hBQXZpZllpcmZodGdFTUdQNDZta3JlK0E9PQ== ``` 接下来,我们在kubernetes集群中来创建这个secret,我们把它创建在命名空间kube-system中,名字叫`ceph-admin-secret`,注意下面的type字段的值不用设置,默认为`Opaque`(与CephRBD不同) ``` apiVersion: v1 kind: Secret metadata: name: ceph-adamin-secret namespace: kube-system data: key: QVFCUkN0RmNpK1VQS3hBQXZpZllpcmZodGdFTUdQNDZta3JlK0E9PQ= ``` ### **创建StorageClass** 然后在kubernetes集群中创建StorageClass,这里我们把provisioner设置为 `ccse.io/cephfs` (可以任意值,但注意不能为`kubernetes.io/`开头) ``` apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cephfs provisioner: ccse.io/cephfs reclaimPolicy: Retain volumeBindingMode: Immediate ``` ### **创建PV** 创建如下的PV * `spec.cephfs.path`:cephfs文件系统中目录,如果不设置该字段则默认为根目录`/`,这里我们设置为`/dir1`(注意要提前在cephfs文件系统中创建好该目录) ``` apiVersion: v1 kind: PersistentVolume metadata: name: pv-cephfs spec: accessModes: - ReadWriteMany capacity: storage: 1Gi storageClassName: cephfs persistentVolumeReclaimPolicy: Retain cephfs: monitors: - 192.168.2.107:6789 path: /dir1 secretRef: name: ceph-admin-secret namespace: kube-system user: admin ``` 查看PV的状态,如下: ``` $ kubectl get pv pv-cephfs NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-cephfs 1Gi RWX Retain Available cephfs 9s ``` ### **创建PVC** 创建如下的PVC ``` apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-cephfs spec: accessModes: - ReadWriteMany storageClassName: cephfs resources: requests: storage: 1Gi ``` 创建好PVC后,查看PVC与PV的状态,已绑定 ``` $ kubectl get pvc pvc-cephfs NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-cephfs Bound pv-cephfs 1Gi RWX cephfs 8s $ kubectl get pv pv-cephfs NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-cephfs 1Gi RWX Retain Bound default/pvc-cephfs cephfs 72s ``` ### **创建Pod** 创建如下的Pod,使用PVC ``` apiVersion: v1 kind: Pod metadata: name: tomcat spec: containers: - name: tomcat image: tomcat:8.0 volumeMounts: - mountPath: /test name: pvc1 volumes: - name: pvc1 persistentVolumeClaim: claimName: pvc-cephfs ``` 创建成功后,查看Pod的状态 ``` $ kubectl get pod tomcat -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tomcat 1/1 Running 0 23s 172.26.71.207 peng01 <none> <none> ``` 等到Running后, 在Pod所在的节点上命令查看cephfs的挂载情况: ``` $ df -hT --type ceph Filesystem Type Size Used Avail Use% Mounted on 192.168.2.107:6789:/dir1 ceph 18G 0 18G 0% /var/lib/kubelet/pods/731473e6-2f72-4e57-a6cf-8390ac8ca1f0/volumes/kubernetes.io~cephfs/pv-cephfs ``` 上面的`731473e6-2f72-4e57-a6cf-8390ac8ca1f0`就是Pod tomcat的uid ``` $ kubectl get pod tomcat -o yaml | grep uid uid: 731473e6-2f72-4e57-a6cf-8390ac8ca1f0 ``` ### **两个Pod使用同一PVC** 上面我们发现,cephfs的目录是挂载到`/var/lib/kubelet/pods/<podid>/...`下面,接下来我们来看一下,如果两个Pod使用同一个PVC,且调度到相同的节点上,那么ceph的挂载会是什么样的呢? 我们再新建一个Pod,yaml文件和上面的tomcat的yaml一样,除了把名字改成tomcat1,让它们调度到同一个节点上(这里的实验集群只有一个节点),如下: ``` $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tomcat 1/1 Running 0 14m 172.26.71.207 peng01 <none> <none> tomcat1 1/1 Running 0 29s 172.26.71.208 peng01 <none> <none> ``` 然后,查看该节点上的cephfs的挂载 ``` $ df -hT --type ceph Filesystem Type Size Used Avail Use% Mounted on 192.168.2.107:6789:/dir1 ceph 18G 0 18G 0% /var/lib/kubelet/pods/731473e6-2f72-4e57-a6cf-8390ac8ca1f0/volumes/kubernetes.io~cephfs/pv-cephfs ``` 我们发现,主机的cephfs挂载并没有发生改变。 接下来,由于cephfs是挂载到tomcat这个Pod的目录下,我们把tomcat这个Pod先删掉, ``` $ kubectl delete pod tomcat pod "tomcat" deleted $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tomcat1 1/1 Running 0 6m57s 172.26.71.208 peng01 <none> <none> ``` 然后再查看主机的挂载情况: ``` $ df -hT --type ceph Filesystem Type Size Used Avail Use% Mounted on 192.168.2.107:6789:/dir1 ceph 18G 0 18G 0% /var/lib/kubelet/pods/79ec3cee-70fe-4aa4-8c16-8685568550a1/volumes/kubernetes.io~cephfs/pv-cephfs ``` 此时发现,cephfs的挂载目录变了,变成了tomcat1这个Pod的路径下。 ### **删除Pod** 再删除tomcat1,等删除成功后, 再看刚才Pod节点上cephfs的挂载,发现已经没有了。 ``` $ df -hT --type ceph df: no file systems processed ``` ### **Q&A** Q:根据上面的实验,k8s应该是使用了ceph的内核态挂载,按理说不需要在k8s节点上安装ceph才对? A:待验证 ### **Reference** https://github.com/kubernetes/examples/tree/master/volumes/cephfs