7

K8s持久化存储_11300506的技术博客_51CTO博客

 2 years ago
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.
neoserver,ios ssh client

Volumes

EmptyDir

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

K8s持久化存储_tomcat

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

K8s持久化存储_docker_02

进入busybox可以考到tomcat内容​

K8s持久化存储_tomcat_03

查看pod所在的宿主机并查找目录​

K8s持久化存储_nginx_04

K8s持久化存储_docker_05

删除pod后目录宿主机目录被删除​

K8s持久化存储_docker_06

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​

K8s持久化存储_docker_07

进入tomcat容器​

kubectl exec -it test-hostpath -c test-tomcat -- /bin/sh​

K8s持久化存储_nginx_08

进入nginx容器​

K8s持久化存储_docker_09

调度节点目录​

K8s持久化存储_tomcat_10

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

K8s持久化存储_tomcat_11

Node节点上目录仍然存在​

K8s持久化存储_docker_12

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==​

K8s持久化存储_tomcat_13

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​

K8s持久化存储_docker_14

K8s持久化存储_nginx_15

创建持久卷声明

kind: PersistentVolumeClaim​

apiVersion: v1​

metadata:​

name: ceph-claim​

spec:​

accessModes:​

- ReadWriteOnce​

- ReadOnlyMany​

resources:​

requests:​

storage: 1Gi​

K8s持久化存储_tomcat_16

kubectl apply -f pvc.yaml​

K8s持久化存储_tomcat_17

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​

K8s持久化存储_tomcat_18
K8s持久化存储_nginx_19

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​

K8s持久化存储_docker_20

示例代码

创建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​

K8s持久化存储_nginx_21

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 ​

K8s持久化存储_nginx_22

部署 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。​

K8s持久化存储_nginx_23
创建

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​

K8s持久化存储_nginx_24

创建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名称​

K8s持久化存储_nginx_25

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​

K8s持久化存储_tomcat_26

[root@k8s-master rdb]# rbd showmapped​

K8s持久化存储_docker_27

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​

K8s持久化存储_tomcat_28

ceph fs ls​

K8s持久化存储_nginx_29

安装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文件​

K8s持久化存储_nginx_30
K8s持久化存储_docker_31
K8s持久化存储_docker_32
K8s持久化存储_docker_33
K8s持久化存储_nginx_34
K8s持久化存储_nginx_35

[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资源

K8s持久化存储_tomcat_36

cephfs创建pvc

K8s持久化存储_tomcat_37

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​

K8s持久化存储_nginx_38

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK