Kubernetes添加带Quota限额的CephFS StorageClass

小编 2026-06-11 阅读:1464 评论:0
1. 在Ceph上为Kubernetes创建一个文件系统# ceph osd pool crea...

1. Ceph上为Kubernetes创建一个文件系统

# ceph osd pool create cephfs_data 128# ceph osd pool create cephfs_metadata 128# ceph fs new cephfs cephfs_metadata cephfs_data

 

2. CephFS配置Quotas

CephFSmount方式分为内核态mount和用户态mount,内核态使用mount命令挂载,用户态使用ceph-fuse。内核态只有在kernel 4.17 + Ceph mimic以上的版本才支持Quotas,用户态则没有限制。

内核态mount

# mount -t ceph 10.32.3.70:/k8s_test /mnt/cephfs/ -o name=admin,secret=AQCs2Q9bqAjCHRAAlQUF+hAiXhbErk4NdtvORQ==

用户态mount

# ceph-fuse -r /k8s_test /mnt/cephfs/ --name client.admin

配置quota

1) 首先在CephFS创建一个要限额的目录

# mkdir /mnt/cephfs# ceph-fuse /mnt/cephfs# mkdir /mnt/cephfs/k8s_test

2) 然后在目录上使用setfattr设置限额属性

# setfattr -n ceph.quota.max_bytes -v 100000000 /mnt/cephfs/k8s_test

比如上面这条命令限制/k8s_test目录只能使用100MB大小的空间。

3) 挂载限额目录并测试

# mkdir /mnt/k8s_test# ceph-fuse -r /k8s_test /mnt/k8s_test/ --name client.admin --client-quota

由于使用的内核和Ceph版本比较低,只能在用户态测试。在Jewel及之前版本的ceph-fuse,挂载时要指定--client-quota参数,限额才会生效。而在Luminous之后的版本,则不支持这个参数了,会自动识别quota。由于我这里使用的是Jewel版本,所以指定了--client-quota参数。然后写入200MB数据测试一下:

# cd /mnt/k8s_test# dd if=/dev/zero of=test1.bin bs=1M count=200dd: error writing ‘test1.bin’: Disk quota exceeded129+0 records in128+0 records out134348800 bytes (134 MB) copied, 0.428233 s, 314 MB/s# df -hFilesystem      Size  Used Avail Use% Mounted onceph-fuse        92M  -64Y  -36M 100% /mnt/cephfs

可以看到中途提示超出配额,但是写入了134MB数据,超过了指定的配额100MB。这是因为CephFSQuotas不是严格的,按官方说法判断检测周期是10s

再次写入数据,可以发现完全写不进去了:

# dd if=/dev/zero of=test2.bin bs=1M count=200dd: error writing ‘test2.bin’: Disk quota exceeded1+0 records in0+0 records out0 bytes (0 B) copied, 0.00162182 s, 0.0 kB/s

 

3. 更新k8s用户权限

# ceph auth caps client.k8s mon 'allow rwx' osd 'allow rwx pool=k8s, allow rw pool=cephfs_data' mds 'allow rwp'

如果还没有创建k8s用户,则使用下面的命令创建:

# ceph auth get-or-create client.k8s mon 'allow rwx' osd 'allow rwx pool=k8s, allow rw pool=cephfs_data' mds 'allow rwp' -o ceph.client.k8s.keyring

Kubernets中创建访问CephSecret的步骤见Kubernetes配置Ceph RBD StorageClasses作为Persistent Volumes Claims后端》3~5步。

 

4. Kubernetes Volume使用CephFS

Kubernetes Volume原生支持CephFS类型,使用方法:

# echo ‘apiVersion: v1kind: Podmetadata:  name: nginx-test-cephfsspec:  containers:  - name: nginx-test-cephfs    image: registry.exmaple.com/base/nginx:v1.0    volumeMounts:    - name: cephfs      mountPath: "/data/"  volumes:  - name: cephfs    cephfs:      monitors:      - 10.32.3.70:6789      - 10.32.3.71:6789      - 10.32.3.72:6789      path: /k8s_test      user: k8s      secretRef:        name: ceph-k8s-secret      readOnly: false’ | kubectl create -f -

进入容器查看:

# kubectl exec nginx-test-cephfs -it -- /bin/bash                                                                                                        [root@nginx-test-cephfs ~]# df -hFilesystem            Size  Used Avail Use% Mounted on10.32.3.70:6789,10.32.3.71:6789,10.32.3.72:6789:/k8s_test                      5.2T  1.1G  5.2T   1% /data

 

5. Kubernetes Persistent Volume使用CephFS

Kubernetes Persistent Volume原生支持CephFS类型,使用方法:

# echo 'apiVersion: v1kind: PersistentVolumemetadata:  name: nginx-test-cephfs-pv-01  namespace: testspec:  capacity:    storage: 100Mi  accessModes:    - ReadWriteMany  cephfs:    monitors:    - 10.32.3.70:6789    - 10.32.3.71:6789    - 10.32.3.72:6789    path: /k8s_test    user: k8s    secretRef:      name: ceph-k8s-secret    readOnly: false---kind: PersistentVolumeClaimapiVersion: v1metadata:  name: nginx-test-cephfs-pvc-01spec:  accessModes:    - ReadWriteMany  resources:    requests:      storage: 50Mi---apiVersion: v1kind: Podmetadata:  name: nginx-test-cephfs-01spec:  containers:  - name: nginx-test-cephfs    image: registry.exmaple.com/base/nginx:v1.0    volumeMounts:    - name: cephfs-vol1      mountPath: "/data/"  volumes:  - name: cephfs-vol1    persistentVolumeClaim:      claimName: nginx-test-cephfs-pvc-01' | kubectl create -f -

进入容器查看:

# kubectl exec nginx-test-cephfs -it -- /bin/bash                                                                                                        [root@nginx-test-cephfs ~]# df -hFilesystem            Size  Used Avail Use% Mounted on10.32.3.70:6789,10.32.3.71:6789,10.32.3.72:6789:/k8s_test                      5.2T  1.1G  5.2T   1% /data

 

6. Kubernetes StorageClass使用CephFS

Kubernetes StorageClass原生不支持CephFS,但是在社区的孵化项目External Storage中添加了CephFS类型的StorageClassExternal Storage是对核心的Kubernetes controller manager的扩展,其中包含的每个external provisioner可以独立部署以支持扩展的StorageClass类型。

部署CephFS external provisioner

1) 下载External Storage代码

# go get github.com/kubernetes-incubator/external-storage

同时要保证CephFS external provisioner依赖的package源码存在于$GOPATH/src目录下,如果有缺失,后面编译会报错,按照报错使用go get下载就行。

2) 编译、打包镜像、上传镜像

进入CephFS external provisioner的源码目录:

# cd $GOPATH/src/github.com/kubernetes-incubator/external-storage/ceph/cephfs

修改Makefile,将REGISTRY变量改成自己的镜像仓库地址,注意结尾要带/

# vim Makefileifeq ($(REGISTRY),)    REGISTRY = registry.example.com/endif

修改Dockerfile,指定CEPH_VERSION与自己Ceph Cluster的版本一致:

# vim DockerfileENV CEPH_VERSION "mimic"

编译,生成cephfs-provisioner二进制文件:

# make

打包docker镜像,并上传到镜像仓库:

# make push

3) 部署CephFS external provisioner

进入部署目录:

# cd $GOPATH/src/github.com/kubernetes-incubator/external-storage/ceph/cephfs/deploy

修改镜像地址:

# vim rbac/deployment.yamlimage: "registry.example.com/cephfs-provisioner:latest"

修改希望部署到的namespace

# NAMESPACE=kube-system# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/*.yaml

部署:

# kubectl -n $NAMESPACE apply -f ./rbac

4) 创建cephfs StorageClass

# echo ‘apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:   name: cephfsprovisioner: ceph.com/cephfsparameters:  monitors: 10.32.3.70:6789,10.32.3.71:6789,10.32.3.72:6789  adminId: k8s  adminSecretName: ceph-k8s-secret  adminSecretNamespace: kube-system‘ | kubectl create -f -

5) 创建一个PersistentVolumeClaim

# echo ‘apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: nginx-test-cephfs-pvc-03  annotations:    volume.beta.kubernetes.io/storage-class: "cephfs"spec:  accessModes:    - ReadWriteMany  resources:    requests:      storage: 100Mi’ | kubectl create -f -

6) 创建使用PVCPod

# echo ‘apiVersion: v1kind: Podmetadata:  name: nginx-test-cephfs-03spec:  containers:  - name: nginx-test-cephfs-03    image: registry.example.com/base/nginx:v1.0    volumeMounts:      - name: pvc        mountPath: "/data/"  volumes:    - name: pvc      persistentVolumeClaim:        claimName: nginx-test-cephfs-pvc-03’ | kubectl create -f -

7) 查看容器状态

# kubectl exec nginx-test-cephfs-03 -it -- /bin/bash# df -hFilesystem            Size  Used Avail Use% Mounted on10.32.3.70:6789,10.32.3.71:6789,10.32.3.72:6789:/volumes/kubernetes/kubernetes-dynamic-pvc-6bfb0ff3-6980-11e8-aa58-5a90b87a7c36                      5.2T  1.1G  5.2T   1% /data

 

7. CephFS StorageClass添加Quotas支持

注意容器中CephFS的挂载方式,使用的是内核态mount,挂载目录的容量并不是PVC声明的100MiB,而是整个CephFS的可用大小。

查看源码发现在Kubernetes 1.10之后的版本才会尝试用户态mount。而且目前使用的Kubernetes 1.10.4版本存在bugceph-fuse挂载时指定了-k参数,却没有指定-i或者-n参数,导致尝试使用ceph-fuse挂载会报错,最终后还是回退到内核态挂载。

另外目前CephFS external provisioner中创建目录时,并没有指定ceph.quota.max_bytes属性,为了添加配额限制,需要修改代码。

1) 修改CephFS external provisioner

CephFS external provisioner的结构比较简单,主要就是cephfs-provisioner.gocephfs_provisioner.py两个文件。cephfs-provisioner.go是主程序,创建CephFS Provisionercephfs_provisioner.py 是对ceph_volume_client.CephFSVolumeClient的封装,方便调用。

修改思路就是在CephFS中创建目录时指定size参数,底层的CephFSVolumeClient.create_volume()判断size存在时会调用setattr设置ceph.quota.max_bytes属性。

具体修改内容可以参考这个PR。修改完后,重新执行第6步中的打包部署操作使之生效。

2) 修改Kubelet

由于1.10.4版本的kubelet存在bug,使用ceph-fuse挂载目录时指定了-k参数却没有指定-i或者-n参数,导致挂载报错。需要修改代码,加上-i参数。具体位置是kubernetes/pkg/volume/cephfs/cephfs.goexecFuseMount()函数,原来的mount参数:

func (cephfsMounter *cephfsMounter) checkFuseMount() bool {    …    mountArgs := []string{}    mountArgs = append(mountArgs, "-k")    mountArgs = append(mountArgs, keyring_file)    mountArgs = append(mountArgs, "-m")    mountArgs = append(mountArgs, src)    mountArgs = append(mountArgs, mountpoint)    mountArgs = append(mountArgs, "-r")mountArgs = append(mountArgs, cephfsVolume.path)…}

追加两行:

    mountArgs = append(mountArgs, "--id")    mountArgs = append(mountArgs, cephfsVolume.id)

如果使用的ceph-fuse版本低于Luminous,还要加上--client-quota参数:

    mountArgs = append(mountArgs, "--client-quota")

然后重新编译kubelet,替换安装文件,重启服务生效。编译方法参考《编译Kubelet二进制文件》

3) 验证Quota

重新使用第6步的配置创建一个Pod,进入容器查看:

# kubectl exec nginx-test-cephfs-03 -it -- /bin/bashroot@nginx-test-cephfs-03:/# df -hFilesystem    Size    Used    Avail     Use%     Mounted onceph-fuse    100M        0    100M        0%     /data

看到挂载方式是ceph-fuse,目录可用大小也是quota配置的100M。写入数据测试一下:

# dd if=/dev/zero of=/data/test.bin bs=1M count=200dd: error writing '/data/test.bin': Disk quota exceeded123+0 records in122+0 records out128421888 bytes (128 MB, 122 MiB) copied, 4.32033 s, 29.7 MB/s# df -hFilesystem    Size    Used    Avail   Use%    Mounted onceph-fuse     100M    100M        0   100%    /data

Quota确实生效了。

 

参考资料

CephFS Admin Tips – Create a new user and share

kubernetes笔记: Cephfs

 

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表