Pod 数据持久化(数据卷与数据持久化卷)

1.Volume

volume使用说明

  • Kubernetes中的Volume提供了在容器中挂载外部存储的能力
  • Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可 以使用相应的Volume

volume的分类

大致可以分为三类

volume 官网:https://kubernetes.io/docs/concepts/storage/volumes/

emptyDir

创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除。

应用场景:Pod中容器之间数据共享

read-write-pod.yaml

apiVersion: v1
kind: Pod metadata:  name: my-pod spec:  containers:  - name: write  image: centos  command: ["bash","-c","for i in {1..100};do echo $i>> /data/hello;sleep 1;done"]  volumeMounts:  - name: data  mountPath: /data  - name: read  image: centos  command: ["bash","-c","tail -f /data/hello"]  volumeMounts:  - name: data  mountPath: /data  volumes:  - name: data  emptyDir: {}

两个pod 共用本地存储。

image.png

image.png

去 k8s-node2 查看映射在宿主机 上的目录,这个就是 pod 共享的目录

image.png

hostPath

挂载Node文件系统上文件或者目录到Pod中的容器,pod删除后宿主机上的目录不会被清除

应用场景:Pod中容器需要访问宿主机文件

hostpath.yaml

apiVersion: v1
kind: Pod metadata:  name: my-pod spec:  containers:  - name: busybox  image: busybox  args:  - /bin/sh  - -c  - sleep 36000  volumeMounts:  - name: data  mountPath: /data  volumes:  - name: data  hostPath:  path: /tmp  type: Directory 

pod被调度到 k8s-node2  容器中的/data 目录 映射到宿主机的/tmp目录

image.png

image.png

反之如果在宿主机的/tmp目录下创建文件 在容器中的 /data 目录一样可以看到。

但是如果 重建pod调度到 非之前的节点,那么之前pod 的数据就会看不到了。

NFS

部署nfs:

#nfs服务端
yum install nfs-utils -y 编辑 /etc/exports 增加内容 /opt/nfs *(rw,no_root_squash) mkdir /opt/nfs systemctl start nfs;systemctl enable nfs;systemctl status nfs #nfs客户端 mount -t nfs 192.168.31.65:/opt/nfs /mnt #192.168.31.65是server端 

验证nfs共享存储:

在任意客户端的 挂载目录创建个 123文件

image.png

在其他客户端的 /mnt  或者服务端的 /opt/nfs 都可以看到

image.png

image.png

 

测试k8s中使用nfs存储

apiVersion: apps/v1
kind: Deployment metadata:  name: nginx-deployment spec:  selector:  matchLabels:  app: nginx  replicas: 3  template:  metadata:  labels:  app: nginx  spec:  containers:  - name: nginx  image: nginx  volumeMounts:  - name: wwwroot  mountPath: /usr/share/nginx/html  ports:  - containerPort: 80  volumes:  - name: wwwroot  nfs:  server: 192.168.31.65  path: /opt/nfs

image.png

向 /opt/nfs  目录下创建 test.html 内容为hello test 作为 nginx的首页文件

如果是再nfs client端操作 是 /mnt目录

cd /root/learn/
echo 'hello test' >/mnt/test.html

请求首页进行验证

image.png

当我们重建一个pod 是否有效?

image.png

answer is 有效

image.png

使用nfs 网络共享存储的优势是即使pod 重建后调度到其他node上 依旧可以保留之前的数据。

2.PersistentVolume

  • PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
  • PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节

为什么会有pv和pvc这个概念:

image.png

对于 nfs server的 地址 挂载路径 用户不关心,那么是否可以将这资源抽象出来,将这些存储资源划分给集群管理,定义个名称或者标记,用户直接使用。

pv静态供给

提前申请好 多个pv形成一个pv池子 供pod从pv池里选取存储容量合适的pv申请成pvc 。

image.png

Kubernetes支持持久卷的存储插件: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

向存储池申请3个pv

apiVersion: v1
kind: PersistentVolume metadata:  name: pv001 spec:  capacity:  storage: 5Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv001  server: 192.168.31.65 --- apiVersion: v1 kind: PersistentVolume metadata:  name: pv002 spec:  capacity:  storage: 10Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv002  server: 192.168.31.65 --- apiVersion: v1 kind: PersistentVolume metadata:  name: pv003 spec:  capacity:  storage: 30Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv003  server: 192.168.31.65

image.png

pv对应的各个字段的含义

  • NAME: pv的名称
  • CAPACITY: pv的容量
  • ACCESS MODES: 访问策略

ReadWriteOnce  – RWO - ReadWriteOnce一人读写

ReadOnlyMany  – ROX - ReadOnlyMany 多人只读

ReadWriteMany – RWX - ReadWriteMany多人读写

  • RECLAIM POLICY: 

用户删除PVC释放对PV的占用后,系统根据PV的"reclaim policy"决定对PV执行何种回收操作。 目前,"reclaim policy"有三种方式:Retained、Recycled、Deleted。

官网描述:

PersistentVolumes 可以有多种回收策略,包括 “Retain”、”Recycle” 和 “Delete”。对于动态配置的 PersistentVolumes 来说,默认回收策略为 “Delete”。这表示当用户删除对应的 PersistentVolumeClaim 时,动态配置的 volume 将被自动删除。如果 volume 包含重要数据时,这种自动行为可能是不合适的。那种情况下,更适合使用 “Retain” 策略。使用 “Retain” 时,如果用户删除 PersistentVolumeClaim,对应的 PersistentVolume 不会被删除。相反,它将变为 Released 状态,表示所有的数据可以被手动恢复。

Recycle策略

当 PVC pvc001 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-pv001,这个 Pod 的作用就是清除 PV pv001 的数据。此时 pv001的状态为 Released,表示已经解除了与 pvc001的 Bound,正在清除数据,不过此时还不可用。

当数据清除完毕,pv001的状态重新变为 Available,此时则可以被新的 PVC 申请。

 

Retain策略

当绑定再pv上的pvc被删除后,并不会启动一个 recycler-for-xxx 的pod来回收pv,删除pvc后pv的状态直接变为released,虽然pvc被删除了,但是pv上的数据得到了保留,此时pv状态一直是Released的不能被其他pvc 绑定,如果想要这个pv重新被使用只有删除该pv 重建,重建后的pv状态重新变成Available再次可以被其他pvc 绑定使用。

 

Delete策略

只有使用了 动态pv的才可以支持该策略,而且pv动态供给默认使用该模式,删除pvc时同时删除与之绑定的pv,共享存储里之前pv的数据将会被归档,当pv 和pvc重新创建后会重新生成一个新目录。

之前目录将重命名为 archived-xxxxxxxxxx     xxxxxxx代表删除pvc之前的名称

  • STATUS :pv的状态
  • CLAIM:   与pv绑定的pvc名称
  • STORAGECLASS: 存储插件类型
apiVersion: v1
kind: Pod metadata:  name: my-pod spec:  containers:  - name: nginx  image: nginx:latest  ports:  - containerPort: 80  volumeMounts:  - name: www  mountPath: /usr/share/nginx/html  volumes:  - name: www  persistentVolumeClaim:  claimName: my-pvc  --- apiVersion: v1 kind: PersistentVolumeClaim metadata:  name: my-pvc spec:  accessModes:  - ReadWriteMany  resources:  requests:  storage: 5Gi

image.png

image.png

如果pv,pvc一直处于Terminating

kubectl patch pv pv001 -p '{"metadata":{"finalizers":null}}'
kubectl patch pvc my-pvc -p '{"metadata":{"finalizers": []}}' --type=merge

pv动态供给

Kubernetes支持持久卷的存储插件: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

image.png

Dynamic Provisioning机制工作的核心在于StorageClass的API对象。

StorageClass声明存储插件,用于自动创建PV

k8s支持动态供给的存储插件

https://kubernetes.io/docs/concepts/storage/storage-classes/

社区开发nfs 支持动态供给的存储插件 https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy

image.png

实现动态pv供给需要解决的问题:

1.创建共享目录

2.创建pv

3.pv使用哪个存储后端(ip)

这些步骤将会由 支持pv动态供给的插件自动化完成

部署nfs动态供给支持插件

rbac.yaml

kind: ServiceAccount
apiVersion: v1 metadata:  name: nfs-client-provisioner --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: nfs-client-provisioner-runner rules:  - apiGroups: [""]  resources: ["persistentvolumes"]  verbs: ["get", "list", "watch", "create", "delete"]  - apiGroups: [""]  resources: ["persistentvolumeclaims"]  verbs: ["get", "list", "watch", "update"]  - apiGroups: ["storage.k8s.io"]  resources: ["storageclasses"]  verbs: ["get", "list", "watch"]  - apiGroups: [""]  resources: ["events"]  verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: run-nfs-client-provisioner subjects:  - kind: ServiceAccount  name: nfs-client-provisioner  namespace: default roleRef:  kind: ClusterRole  name: nfs-client-provisioner-runner  apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: leader-locking-nfs-client-provisioner rules:  - apiGroups: [""]  resources: ["endpoints"]  verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: leader-locking-nfs-client-provisioner subjects:  - kind: ServiceAccount  name: nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: default roleRef:  kind: Role  name: leader-locking-nfs-client-provisioner  apiGroup: rbac.authorization.k8s.io

class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass metadata:  name: managed-nfs-storage provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' parameters:  archiveOnDelete: "true" 

deployment.yaml

apiVersion: v1
kind: ServiceAccount metadata:  name: nfs-client-provisioner --- kind: Deployment apiVersion: apps/v1 metadata:  name: nfs-client-provisioner spec:  replicas: 1  strategy:  type: Recreate  selector:  matchLabels:  app: nfs-client-provisioner  template:  metadata:  labels:  app: nfs-client-provisioner  spec:  serviceAccountName: nfs-client-provisioner  imagePullSecrets:  - name: myregistry  containers:  - name: nfs-client-provisioner  image: registry.cn-hangzhou.aliyuncs.com/benjamin-learn/nfs-client-provisioner:latest  volumeMounts:  - name: nfs-client-root  mountPath: /persistentvolumes  env:  - name: PROVISIONER_NAME  value: fuseim.pri/ifs  - name: NFS_SERVER  value: 192.168.31.65  - name: NFS_PATH  value: /opt/nfs  volumes:  - name: nfs-client-root  nfs:  server: 192.168.31.65  path: /opt/nfs 

image.png

pv动态供给示例

dynamic-pv-pod.yaml

apiVersion: v1
kind: Pod metadata:  name: my-pod spec:  containers:  - name: nginx  image: nginx:latest  ports:  - containerPort: 80  volumeMounts:  - name: www  mountPath: /usr/share/nginx/html  volumes:  - name: www  persistentVolumeClaim:  claimName: my-pvc  --- apiVersion: v1 kind: PersistentVolumeClaim metadata:  name: my-pvc spec:  storageClassName: "managed-nfs-storage"  accessModes:  - ReadWriteMany  resources:  requests:  storage: 5Gi

image.png

进入my-pod 容器创建 index.html

image.png

default-my-pvc-pvc-f5ce89a7-b566-44df-affe-8221f13db74f 这个目录由插件自动完成创建

image.png

这样就可以完成了 自动pv供给,不需要再 手动申请pv

猜你喜欢

转载自www.cnblogs.com/benjamin77/p/12446765.html
今日推荐