戳下方名片 ,关注并 星标 !
回复「 1024 」获取 2TB 学习资源!
👉 体系化学习:
— 特色专栏 —
/ /
/ /
/ /
/ /
/ /
大家好,我是民工哥!
今天来聊一聊 k8s 使用 rbd 作为存储的方案!
如果需要使用 rbd 作为后端存储的话,需要先安装 ceph-common。
ceph 集群创建 rbd
需要提前在 ceph 集群上创建 pool,然后创建 image
[root@ceph01 ~]# ceph osd pool create pool01
[root@ceph01 ~]# ceph osd pool application enable pool01 rbd
[root@ceph01 ~]# rbd pool init pool01
[root@ceph01 ~]# rbd create pool01/test --size 10G --image-format 2 --image-feature layerin
[root@ceph01 ~]# rbd info pool01/test
k8s 编写 yaml 文件
apiVersion:apps/v1
kind:Deployment
metadata:
creationTimestamp:null
labels:
app:rbd
name:rbd
spec:
replicas:1
selector:
matchLabels:
app:rbd
strategy:{}
template:
metadata:
creationTimestamp:null
labels:
app:rbd
spec:
volumes:
-name:test
rbd:
fsType:xfs
keyring:/root/admin.keyring
monitors:
-192.168.200.230:6789
pool:pool01
image:test
user:admin
readOnly:false
containers:
-image:nginx
imagePullPolicy:IfNotPresent
volumeMounts:
-mountPath:/usr/share/nginx/html
name:test
name:nginx
resources:{}
status: {}
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
rbd-888b8b747-n56wr 1/1 Running 0 26m
这个时候 k8s 就使用了 rbd 作为存储。
如果这个地方一直显示 ContainerCreating 的话,可能是没有安装 ceph-common,也可能是你的 keyring 或者 ceph.conf 没有发放到 node 节点,具体可以使用 describe 来看。
进入容器查看挂载
[root@master euler]# kubectl exec -it rbd-5db4759c-nj2b4 -- bash
root@rbd-5db4759c-nj2b4:/# df -hT |grep /dev/rbd0
/dev/rbd0 xfs 10G 105M 9.9G 2% /usr/share/nginx/html
可以看到,/dev/rbd0 已经被格式化成 xfs 并且挂载到了/usr/share/nginx/html。
进入容器修改内容
root@rbd-5db4759c-nj2b4:/usr/share/nginx# cd html/
root@rbd-5db4759c-nj2b4:/usr/share/nginx/html# ls
root@rbd-5db4759c-nj2b4:/usr/share/nginx/html# echo 123 > index.html
root@rbd-5db4759c-nj2b4:/usr/share/nginx/html# chmod 644 index.html
root@rbd-5db4759c-nj2b4:/usr/share/nginx/html# exit
[root@master euler]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rbd-5db4759c-nj2b4 1/1 Running 0 8m5s 192.168.166.131 node1 <none> <none>
访问容器查看内容
[root@master euler]# curl 192.168.166.131123
内容可以正常被访问到,我们将容器删除,然后让他自己重新启动一个来看看文件是否还存在。
[root@master euler]# kubectl delete pods rbd-5db4759c-nj2b4
pod "rbd-5db4759c-nj2b4" deleted
[root@master euler]# kubectl get pods
NAME READY STATUS RESTARTS AGE
rbd-5db4759c-v9cgm 0/1ContainerCreating02s
[root@master euler]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rbd-5db4759c-v9cgm 1/1Running040s192.168.166.132 node1 <none><none>
[root@master euler]# curl 192.168.166.132
123
可以看到,也是没有问题的,这样 k8s 就正常的使用了 rbd 存储。
有一个问题,那就是开发人员他们并不是很了解 yaml 文件里面改怎么去写挂载,每种类型的存储都是不同的写法,那有没有一种方式屏蔽底层的写法,直接告诉 k8s 集群我想要一个什么样的存储呢?
有的,那就是 pv。
pv 使用 rbd
[root@mastereuler]# vim pvc.yaml
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:myclaim
spec:
accessModes:
-ReadWriteOnce
volumeMode:Block
resources:
requests:
storage:8Gi
这里的 pvc 使用的是块设备,8 个 G,目前还没有这个 pv 可以给到他。
具体的这里不细说,CKA 里面有写。
注意,这里是 pvc,并不是 pv,pvc 就是开发人员定义想要的存储类型,大小,然后我可以根据你的 pvc 去给你创建 pv,或者提前创建好 pv 你直接申领。
[root@mastereuler]# vim pv.yaml
apiVersion:v1
kind:PersistentVolume
metadata:
name:rbdpv
spec:
capacity:
storage:8Gi
volumeMode:Block
accessModes:
-ReadWriteOnce
persistentVolumeReclaimPolicy:Recycle
mountOptions:
-hard
-nfsvers=4.1
rbd:
fsType:xfs
image:test
keyring:/etc/ceph/ceph.client.admin.keyring
monitors:
-172.16.1.33
pool:rbd
readOnly:false
user:admin
查看 pvc 状态
[root@master euler]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGE class AGE
myclaim Bound rbdpv 8Gi RWO 11s
这个时候 pv 和就和 pvc 绑定上了,一个 pv 只能绑定一个 pvc,同样,一个 pvc 也只能绑定一个 pv。
使用 pvc
[root@mastereuler]# vim pod-pvc.yaml
apiVersion:v1
kind:Pod
metadata:
creationTimestamp:null
labels:
run:pvc-pod
name:pvc-pod
spec:
volumes:
-name:rbd
persistentVolumeClaim:
claimName:myclaim
readOnly:false
containers:
-image:nginx
imagePullPolicy:IfNotPresent
name:pvc-pod
volumeDevices:# 因为是使用的块设备,所以这里是volumeDevices
-devicePath:/dev/rbd0
name:rbd
resources:{}
dnsPolicy:ClusterFirst
restartPolicy:Always
status:{}
~
[root@master euler]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pvc-pod 1/1 Running 0 2m5s
rbd-5db4759c-v9cgm 1/1 Running 0 39m
进入容器查看块设备
root@pvc-pod:/# ls /dev/rbd0/dev/rbd0
可以看到,现在 rbd0 已经存在于容器内部了。
这样做我们每次创建 pvc 都需要创建对应的 pv,我们可以使用动态制备。
动态制备
使用 storage class,但是目前欧拉使用的 k8s 太老了,所以需要下载欧拉 fork 的一个 storage class。
[root@master ~]# git clone https://gitee.com/yftyxa/ceph-csi.git
[root@master ~]# cd ceph-csi/deploy/
[root@master deploy]# ls
ceph-conf.yaml csi-config-map-sample.yaml rbd
cephcsi Makefile scc.yaml
cephfs nfs service-monitor.yaml
动态制备 rbd
这里我们需要修改这个文件:
/root/ceph-csi/deploy/rbd/kubernetes/csi-config-map.yaml
# 先创建一个csi命名空间
[root@master ~]# kubectl create ns csi
修改文件内容
[root@master kubernetes]# vim csi-rbdplugin-provisioner.yaml
# 将第63行的内容改为false
63-"--extra-create-metadata=false"
# 修改第二个文件
[root@master kubernetes]# vim csi-config-map.yaml
# 这里尽量不要复制,因为测试过程中复制粘贴到文件里会导致k8s不识别
apiVersion: v1
kind:ConfigMap
metadata:
name:"ceph-csi-config"
data:
config.json:|-
[
{
"clusterID":"c1f213ae-2de3-11ef-ae15-00163e179ce3",
"monitors":["172.16.1.33","172.16.1.32","172.16.1.31"]
}
]
[root@master kubernetes]# kubectl apply -f csi-config-map.yaml -n csi
• 这里面的 clusterID 可以通过 ceph -s 去查看
修改第三个文件
[root@master kubernetes]# vim csidriver.yaml
---
apiVersion: storage.k8s.io/v1
kind:CSIDriver
metadata:
name:"rbd.csi.ceph.com"
spec:
attachRequired:true
podInfoOnMount:false
# seLinuxMount: true # 将这一行注释
fsGroupPolicy: File
自行编写一个文件
[root@masterkubernetes]# vim csi-kms-config-map.yaml
---
apiVersion:v1
kind:ConfigMap
metadata:
name:ceph-csi-encryption-kms-config
data:
config-json:|-
{}
获取 admin 的 key
[root@ceph001 ~]# cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
key = AQC4QnJmng4HIhAA42s27yOflqOBNtEWDgEmkg==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
• AQC4QnJmng4HIhAA42s27yOflqOBNtEWDgEmkg== 只要这部分。
然后自行编写一个
csi-secret.yaml
的文件
[root@masterkubernetes]# vim csi-secret.yaml
apiVersion:v1
kind:Secret
metadata:
name:csi-secret
stringData:
userID:admin
userKey:AQC4QnJmng4HIhAA42s27yOflqOBNtEWDgEmkg==
adminID:admin
adminKey:AQC4QnJmng4HIhAA42s27yOflqOBNtEWDgEmkg==
[root@masterkubernetes]# kubectl apply -f csi-secret.yaml -n csi
secret/csi-secretcreated
[root@masterkubernetes]# cd ../../
[root@masterdeploy]# kubectl apply -f ceph-conf.yaml -n csi
configmap/ceph-configcreated
[root@masterdeploy]# cd -
/root/ceph-csi/deploy/rbd/kubernetes
4替换所有的 namespace
[root@master kubernetes]# sed -i "s/namespace: default/namespace: csi/g"
*.yaml
部署
[root@master kubernetes]# kubectl apply -f . -n csi
注意
:如果你的 worker 节点数量少于 3 个的话,是需要将
csi-rbdplugin-provisioner.yaml
这个文件里面的 replicas 改小一点的。
[root@master kubernetes]# kubectl get pods -n csi
NAME READY STATUS RESTARTS AGE
csi-rbdplugin-cv455 3/3Running1(2m14s ago)2m46s
csi-rbdplugin-pf5ld 3/3Running04m36s
csi-rbdplugin-provisioner-6846c4df5f-dvqqk 7/7Running04m36s
csi-rbdplugin-provisioner-6846c4df5f-nmcxf 7/7Running1(2m11s ago) 4m36s
使用动态制备
创建 storage class
[root@master rbd]#/root/ceph-csi/examples/rbd
[root@master rbd]# grep -Ev"\s*#|^$" storage class.yaml
---
apiVersion: storage.k8s.io/v1
kind:Storage class
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID:<cluster-id>
pool:<rbd-pool-name>
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
csi.storage.k8s.io/fstype: ext4
reclaimPolicy:Delete
allowVolumeExpansion:true
mountOptions:
- discard
将这里的内容复制出来
---
apiVersion:storage.k8s.io/v1
kind:Storage class
metadata:
name:csi-rbd-sc
provisioner:rbd.csi.ceph.com
parameters:
clusterID:c1f213ae-2de3-11ef-ae15-00163e179ce3
pool:rbd
imageFeatures:"layering"
csi.storage.k8s.io/provisioner-secret-name:csi-secret
csi.storage.k8s.io/provisioner-secret-namespace:csi
csi.storage.k8s.io/controller-expand-secret-name:csi-secret
csi.storage.k8s.io/controller-expand-secret-namespace:csi
csi.storage.k8s.io/node-stage-secret-name:csi-secret
csi.storage.k8s.io/node-stage-secret-namespace:csi
csi.storage.k8s.io/fstype:ext4
reclaimPolicy:Retain
allowVolumeExpansion:true
mountOptions:
-discard
修改成这个样子,这里面的 clusterID 改成自己的,secret-name 自己查一下。
创建 pvc
[root@mastereuler]# cp pvc.yaml sc-pvc.yaml
[root@mastereuler]# vim sc-pvc.yaml
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:sc-pvc
spec:
accessModes:
-ReadWriteOnce
volumeMode:Block
storage className:"csi-rbd-sc"
resources:
requests:
storage:15Gi
• storage className 可以使用 kubectl get sc 查看。
现在我们只需要创建 pvc,他就自己可以创建 pv 了。
[root@master euler]# kubectl apply -f sc-pvc.yaml
persistentvolumeclaim/sc-pvc created
[root@master euler]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGE class AGE
myclaim Bound rbdpv 8Gi RWO 111m
sc-pvc Bound pvc-dfe3497f-9ed7-4961-9265-9e7242073c28 15Gi RWO csi-rbd-sc 2s
回到 ceph 集群查看 rbd
[root@ceph001 ~]# rbd ls
csi-vol-56e37046-b9d7-4ef1-a534-970a766744f3
test
[root@ceph001 ~]# rbd info csi-vol-56e37046-b9d7-4ef1-a534-970a766744f3
rbd image 'csi-vol-56e37046-b9d7-4ef1-a534-970a766744f3':
size 15GiBin3840 objects
order 22(4MiB objects)
snapshot_count:0
id:38019ee708da
block_name_prefix: rbd_data.38019ee708da
format:2
features: layering
op_features:
flags:
create_timestamp:WedJun1904:55:352024
access_timestamp:WedJun1904:55:352024
modify_timestamp:WedJun1904:55:35 2024
将 sc 设为默认
如果不设置为默认的话,每次写 yaml 文件都需要指定 sc,将 sc 设为默认的话就不用每次都指定了
[root@master euler]# kubectl edit sc csi-rbd-sc
# 在注释里面写入这一行
annotations:
storage class.kubernetes.io/is-default- class: "true"
测试默认 pvc
[root@master euler]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
csi-rbd-sc (default) rbd.csi.ceph.com Retain Immediate true 29m
再去查看 sc 就会有一个 default 的显示
[root@master euler]# cp sc-pvc.yaml sc-pvc1.yaml
[root@master euler]# cat sc-pvc1.yaml
apiVersion: v1
kind:PersistentVolumeClaim
metadata:
name: sc-pvc1
spec:
accessModes:
-ReadWriteOnce
volumeMode:Block
resources:
requests:
storage: 20Gi
这个文件里面是没有指定 storage className 的。
[root@master euler]# kubectl apply -f sc-pvc1.yaml
persistentvolumeclaim/sc-pvc1 created
[root@master euler]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGE class AGE
myclaim Bound rbdpv 8Gi RWO 138m
sc-pvc Bound pvc-dfe3497f-9ed7-4961-9265-9e7242073c28 15Gi RWO csi-rbd-sc 27m
sc-pvc1 Bound pvc-167cf73b-4983-4c28-aa98-bb65bb966649 20Gi RWO csi-rbd-sc 6s
这样就好了
作者:FuShudi 链接:
https://cnblogs.com/fsdstudy/p/18254695
👍 如果你喜欢这篇文章,请点赞并分享给你的朋友!
公众号读者专属技术群
构建高质量的技术交流社群,欢迎从事后端开发、运维技术进群( 备注岗位,已在技术交流群的请勿重复添加微信好友 )。主要以技术交流、内推、行业探讨为主,请文明发言。 广告人士勿入,切勿轻信私聊,防止被骗。
扫码加我好友,拉你进群
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下 「 在看 」 ,加个 「 星标 」 ,这样每次新文章推送才会第一时间出现在你的订阅列表里。 点 「 在看 」 支持我们吧!