

K8s持久化存储_11300506的技术博客_51CTO博客
source link: https://blog.51cto.com/u_11310506/5682484
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Volumes
EmptyDir
类型的Volume在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的

进入tomcat容器可以看到empty内容

进入busybox可以考到tomcat内容

查看pod所在的宿主机并查找目录
删除pod后目录宿主机目录被删除
hostPath
为Pod挂载宿主机上的目录或文件。 hostPath Volume使得容器可以使用宿主机的高速文件系统进行存储; hostpath(宿主机路径):节点级别的存储卷,在pod被删除,这个存储卷还是存在的,不会被删除,所以只要同一个pod被调度到同一个节点上来,在pod被删除重新被调度到这个节点之后,对应的数据依然是存在的。
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath
spec:
containers:
- image: nginx
name: test-nginx
volumeMounts:
- mountPath: /test-nginx
name: test-volume
- image: tomcat
name: test-tomcat
volumeMounts:
- mountPath: /test-tomcat
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data1
type: DirectoryOrCreate

进入tomcat容器
kubectl exec -it test-hostpath -c test-tomcat -- /bin/sh
进入nginx容器
调度节点目录

pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失

Node节点上目录仍然存在

nfs
以master1节点作为nfs服务端:
在master1上操作:
安装nfs:
yum install nfs-utils -y
创建共享目录:
mkdir /data/volumes -pv
cat /etc/exports
/data/volumes 192.168.0.0/24(rw,no_root_squash)
注意:所有node节点上都需要安装nfs-utils包,否则pod无法正常挂载,pod无法正常运行。节点最好是k8s内集群节点做nfs服务
exportfs -arv
systemctl start nfs
apiVersion: v1
kind: Pod
metadata:
name: test-nfs-volume
spec:
containers:
- name: test-nfs
image: nginx:latest
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: nfs-volumes
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-volumes
nfs:
path: /volumes
server: 192.168.211.105
k8s-PV&PVC
PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像节点是集群资源一样。PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统
PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建pod时可以定义这个类型的存储卷。 它类似于一个pod。 Pod消耗节点资源,PVC消耗PV资源。 Pod可以请求特定级别的资源(CPU和内存)。pvc在申请pv的时候也可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)。
pv&pvc使用
a)需要找一个存储服务器,把它划分成多个存储空间;
b)k8s管理员可以把这些存储空间定义成多个pv;
c)在pod中使用pvc类型的存储卷之前需要先创建pvc,通过定义需要使用的pv的大小和对应的访问模式,找到合适的pv;
d)pvc被创建之后,就可以当成存储卷来使用了,我们在定义pod时就可以使用这个pvc的存储卷
e)pvc和pv它们是一一对应的关系,pv如果被被pvc绑定了,就不能被其他pvc使用了;
f)我们在创建pvc的时候,应该确保和底下的pv能绑定,如果没有合适的pv,那么pvc就会处于pending状态。
PersistentVolume(PV),PV不属于任何命名空间,PV是集群层面的资源。
PersistentVolumeClaim
cephrdb静态持久卷
每次需要使用存储空间,需要存储管理员先手动在存储上创建好对应的image,然后k8s才能使用。
k8s添加一个访问ceph的secret
1)使用如下命令在安装ceph的客户端需要安装ceph-common
2)k8s集群和ceph集群 kernel版本不一样,k8s集群的kernel版本较低,rdb块存储的一些feature 低版本kernel不支持,需要disable
rbd feature disable rbd/image1 exclusive-lock object-map fast-diff deep-flatten
3)找不到key的报错是由于k8s节点要和ceph交互以把image映射到本机,需要每台k8s节点的/etc/ceph目录都要放置ceph.client.admin.keyring文件,映射的时候做认证使用。
故给每个节点创建了/etc/ceph目录,写脚本放置了一下key文件。
scp /etc/ceph/ceph.client.admin.keyring root@k8s-node:/etc/ceph
ceph auth get-key client.admin | base64
vim ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
data:
key: QVFCd3BOQmVNMCs5RXhBQWx3aVc3blpXTmh2ZjBFMUtQSHUxbWc9PQ==

kubectl apply -f ceph-secret.yaml
ceph创建image
ceph osd lspools
ceph osd pool create rbd 32 32
ceph osd pool application enable rbd rbd
rbd create image1 -s 1024
创建持久卷
apiVersion: v1
kind: PersistentVolume
metadata:
name: ceph-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
- ReadOnlyMany
rbd:
monitors:
- 192.168.1.26:6789
- 192.168.1.74:6789
- 192.168.1.191:6789
user: admin
secretRef:
name: ceph-secret
fsType: ext4
persistentVolumeReclaimPolicy: Retain

创建持久卷声明
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: ceph-claim
spec:
accessModes:
- ReadWriteOnce
- ReadOnlyMany
resources:
requests:
storage: 1Gi

kubectl apply -f pvc.yaml
pod使用持久卷
apiVersion: v1
kind: Pod
metadata:
name: ceph-pod1
spec:
containers:
- name: ceph-centos
image: centos
一定要注意容器有进程在运行
volumeMounts:
- name: ceph-mnt
mountPath: /mnt
readOnly: false
volumes:
- name: ceph-mnt
persistentVolumeClaim:
claimName: ceph-claim


Ceph rdb动态持久卷
不需要存储管理员干预,使k8s使用的存储image创建自动化,即根据使用需要可以动态申请存储空间并自动创建。需要先定义一个或者多个StorageClass,每个StorageClass都必须配置一个provisioner,用来决定使用哪个卷插件分配PV。然后,StorageClass资源指定持久卷声明请求StorageClass时使用哪个provisioner来在对应存储创建持久卷。
第三方的rbd provisioner,其对应的rbd provisioner内置的ceph-common版本已经跟不上ceph的版本了,现在其内置的ceph-common版本是m版,如果集群是m版可以考虑使用使用官方的ceph csi, 一定要记得k8s的版本与ceph-csi对应!否则会有很多bug
https://zhuanlan.zhihu.com/p/267347779
在ceph创建ceph用户pool
ceph version
ceph version 13.2.10
kubelet --version
Kubernetes v1.20.0
新建
ceph osd pool create kubernetes
ceph osd lspools
新建用户
ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
ceph auth get client.kubernetes
部署
Github的访问地址: https://github.com/ceph/ceph-csi
https://github.com/ceph/ceph-csi/tree/release-v3.4/deploy/rbd/kubernetes

示例代码
创建namespace专门用来部署 ceph-csi
kubectl create ns ceph-csi
apiVersion: v1
kind: ConfigMap
data:
config.json: |-
集群的id,通过ceph -s获取
"monitors": [
集群的monitor节点的ip
"192.168.1.74:6789",
"192.168.1.191:6789"
metadata:
name: ceph-csi-config
将Configmap存储到Kubernetes集群中:
$ kubectl -n ceph-csi apply -f csi-config-map.yaml
新建
----
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi
stringData:
userID: kubernetes #ceph集群的用户名ceph auth get client.kubernetes获取
userKey: AQBnz11fclrxChAAf8TFw8ROzmr8ifftAHQbTw== #ceph用户的密码要,通过ceph auth get client.kubernetes获取
部署 Secret:
$ kubectl apply -f csi-rbd-secret.yaml
RBAC授权
注意文件名中的namespace用工具做替换
将所有配置清单中的namespace改成ceph-csi:
$ kubectl create -f csi-provisioner-rbac.yaml
$ kubectl create -f csi-nodeplugin-rbac.yaml
创建
将所有配置清单中的namespace改成ceph-csi:
$ kubectl create -f csi-provisioner-psp.yaml
$ kubectl create -f csi-nodeplugin-psp.yaml
部署
将 csi-rbdplugin-provisioner.yaml 和 csi-rbdplugin.yaml 中的 kms 部分配置注释掉:
将所有配置清单中的namespace改成ceph-csi:
拉取镜像
docker search quay.io/k8scsi/csi-provisioner:v2.0.4
docker search quay.io/k8scsi/csi-resizer:v1.0.1
docker search quay.io/k8scsi/csi-snapshotter:v4.0.0
docker search quay.io/k8scsi/csi-attacher:v3.0.2
docker search quay.io/cephcsi/cephcsi:v3.3-canary
docker search quay.io/k8scsi/csi-node-driver-registrar:v2.0.1
docker pull antmoveh/csi-node-driver-registrar:v2.2.0
docker pull carloscao/csi-resizer:v1.2.0
docker pull registry.aliyuncs.com/google_containers/csi-provisioner:v2.2.2
docker pull registry.aliyuncs.com/google_containers/csi-snapshotter:v4.1.1
docker pull registry.aliyuncs.com/google_containers/csi-attacher:v3.2.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.5.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-snapshotter:v6.0.1
镜像打tag
docker tag carloscao/csi-resizer:v1.2.0 k8s.gcr.io/sig-storage/csi-resizer:v1.2.0
部署 csi-rbdplugin-provisioner:
$ kubectl -n ceph-csi create -f csi-rbdplugin-provisioner.yaml
这里面包含了6个Sidecar容器,包括 external-provisioner、external-attacher、csi-resizer 和 csi-rbdplugin。
最后部署 RBD CSI Driver:
$ kubectl -n ceph-csi create -f csi-rbdplugin.yaml
Pod 中包含两个容器:CSI node-driver-registrar 和 CSI RBD driver。

创建
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
namespace: ceph-csi #namespace
provisioner: rbd.csi.ceph.com
parameters:
clusterID: 2a4519a6-9324-4bc9-982f-a21721d492be #ceph集群的id
pool: kubernetes #ceph存储池
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
创建pvc
persistentvolume-controller waiting for a volume to be created, either by external provisioner "xxxx" or manually created by system administrator
PVC绑定报错需要在apiservice添加一条参数
/usr/lib/systemd/system/kube-apiserver.service
下面添加
--feature-gates=VolumeSnapshotDataSource=true,RemoveSelfLink=false \
systemctl daemon-reload && systemctl start kube-apiserver
systemctl status kube-apiserver
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
namespace: ceph-csi #指定namespace,与storageclass的namespace一致
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc #storageclass名称
Pod挂载ceph-csi
apiVersion: v1
kind: Pod
metadata:
名称自定义
namespace: ceph-csi
spec:
containers:
容器名称自定义最好与pod一致
image: centos
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
volumeMounts:
mountPath: /mnt
readOnly: false
volumes:
persistentVolumeClaim:
查看申请的ceph相关信息
列出 kubernetes pool 中的 rbd images:
[root@k8s-master rdb]# rbd ls -p kubernetes
csi-vol-fa295b7a-34e2-11ed-a999-261751919c9e
查看该 image 的特征
[root@k8s-master rdb]# rbd info csi-vol-fa295b7a-34e2-11ed-a999-261751919c9e -p kubernetes

[root@k8s-master rdb]# rbd showmapped
Ceph cephfs动态持久卷
https://blog.51cto.com/leejia/2583381
前提条件
cephfs需要至少一个mds(Ceph Metadata Server)服务用来存放cepfs服务依赖元数据信息,有条件的可以创建2个会自动成为主备。在ceph1上创建mds服务:
ceph1上来创建存储池和和cephfs
ceph osd pool create cephfs-data 128 128
ceph osd pool create cephfs-metadata 128 128
ceph fs new cephfs cephfs-metadata cephfs-data
ceph mds stat
ceph fs ls
安装cephfs-provisioner
# git clone https://github.com/kubernetes-retired/external-storage.git
# cd external-storage/ceph/cephfs/deploy/
# NAMESPACE=kube-system
# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/*.yaml
#sed -i "/PROVISIONER_SECRET_NAMESPACE/{n;s/value:.*/value: $NAMESPACE/;}" rbac/deployment.yaml
# kubectl -n $NAMESPACE apply -f ./rbac
创建cephfs-provisioner的yaml文件






[root@k8s-master cephfs]# NAMESPACE=kube-system
[root@k8s-master cephfs]# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./*.yaml
[root@k8s-master cephfs]# sed -i "/PROVISIONER_SECRET_NAMESPACE/{n;s/value:.*/value: $NAMESPACE/;}" deployment.yaml
serviceaccount.yaml
role.yaml
rolebinding.yaml
clusterrole.yaml
clusterrolebinding.yaml
deployment.yaml
[root@k8s-master cephfs]# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl apply -f rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl apply -f clusterrole.yaml
clusterrole.rbac.authorization.k8s.io/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl apply -f clusterrolebinding.yaml
clusterrolebinding.rbac.authorization.k8s.io/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl apply -f serviceaccount.yaml
serviceaccount/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl apply -f deployment.yaml
deployment.apps/cephfs-provisioner created
[root@k8s-master cephfs]# kubectl get pods -n kube-system|grep 'cephfs-provisioner'
cephfs-provisioner-7799f97d57-gk8rt 1/1 Running 0 23s
cephfs创建stoageclass资源

cephfs创建pvc

Pod挂载cephfs
跨不同node的pod之间存储共享
给node添加标签使调度不同的node上面
kubectl label nodes k8s-node02 type=test02
kubectl label nodes k8s-node01 type=test01
apiVersion: v1
kind: Pod
metadata:
name: ceph-fs-pod01
spec:
containers:
- name: ceph-fs-centos01
image: centos
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
volumeMounts:
- name: ceph-fs-mnt
mountPath: /mnt
readOnly: false
volumes:
- name: ceph-fs-mnt
persistentVolumeClaim:
claimName: claim-local
nodeSelector:
type: test01
apiVersion: v1
kind: Pod
metadata:
name: ceph-fs-pod02
spec:
containers:
- name: ceph-fs-centos02
image: centos
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
volumeMounts:
- name: ceph-fs-mnt
mountPath: /mnt
readOnly: false
volumes:
- name: ceph-fs-mnt
persistentVolumeClaim:
claimName: claim-local
nodeSelector:
type: test02

Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK