k8s-数据持久化存储卷,nfs,pv/pvc


目录

  • 数据持久化-储存卷
    • 官方文档
  • 存储卷类型
  • 1.emptyDir
  • 2.hostpath
  • 3.pv/pvc(推荐使用)
    • nfs官方文档
      • 安装测试nfs
    • pv/pvc管理nfs
      • 官方文档
      • pv/pvc解释
      • 1. PV 的访问模式(accessModes)
      • 2. PV 的回收策略(persistentVolumeReclaimPolicy)
      • 3. PV 的状态
      • 4.创建pv
      • 5.pvc插件
        • 官方文档
        • pvc使用pv-创建pvc
        • pv-pvc.yaml 使用nfs

数据持久化-储存卷
我们知道,Pod是由容器组成的,而容器宕机或停止之后,数据就随之丢了,那么这也就意味着我们在做Kubernetes集群的时候就不得不考虑存储的问题,而存储卷就是为了Pod保存数据而生的。存储卷的类型有很多,我们常用到一般有四种:emptyDir,hostPath,NFS以及云存储(ceph, glasterfs...)等。

官方文档
https://kubernetes.io/zh/docs/concepts/storage/volumes/#emptydirhttps://kubernetes.io/zh/docs/concepts/storage/volumes/#hostpath

存储卷类型
emptyDir,hostPath,NFS以及云存储(ceph, glasterfs...)等。

1.emptyDir
emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Pod从node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录.作用:1.用于容器间分享文件2.用于创建临时目录 注:emptyDir不能够用来做数据持久化

例子1:
kind: Deployment apiVersion: apps/v1 metadata: name: emptydir spec: selector: matchLabels: app: emptydir template: metadata: labels: app: emptydir spec: containers: - name: nginx image: nginx volumeMounts:## 挂载 - mountPath: /usr/share/nginx/nginx## 挂在目录 name: test-emptydir# 存储卷名称 volumes: ## 创建存储卷 - name: test-emptydir # 创建存储卷名称 emptyDir: {}

2.hostpath
https://kubernetes.io/zh/docs/concepts/storage/volumes/#hostpath警告: HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问, 则必须要求 volumeMounts 使用 readOnly 挂载以使策略生效。

hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。
【k8s-数据持久化存储卷,nfs,pv/pvc】例如,hostPath 的一些用法有:
  • 运行一个需要访问 Docker 内部机制的容器;可使用 hostPath 挂载 /var/lib/docker 路径。
  • 在容器中运行 cAdvisor 时,以 hostPath 方式挂载 /sys
  • 允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。
除了必需的 path 属性之外,用户可以选择性地为 hostPath 卷指定 type
支持的 type 值如下:
取值 行为
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。
当使用这种类型的卷时要小心,因为:
  • HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权 API(例如容器运行时套接字), 可用于容器逃逸或攻击集群的其他部分。
  • 具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同 而在不同节点上有不同的行为。
  • 下层主机上创建的文件或目录只能由 root 用户写入。你需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容?能够写入 hostPath
hostPath 配置示例:****
apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: k8s.gcr.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: # 宿主上目录位置 path: /data # 此字段为可选 type: Directory注意: FileOrCreate 模式不会负责创建文件的父目录。 如果欲挂载的文件的父目录不存在,Pod 启动会失败。 为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载,如 FileOrCreate 配置 所示。

hostPath FileOrCreate 配置示例
apiVersion: v1 kind: Pod metadata: name: test-webserver spec: containers: - name: test-webserver image: k8s.gcr.io/test-webserver:latest volumeMounts: - mountPath: /var/local/aaa name: mydir - mountPath: /var/local/aaa/1.txt name: myfile volumes: - name: mydir hostPath: # 确保文件所在目录成功创建。 path: /var/local/aaa type: DirectoryOrCreate - name: myfile hostPath: path: /var/local/aaa/1.txt type: FileOrCreate

3.pv/pvc(推荐使用) nfs官方文档
nfs官方文档:https://kubernetes.io/zh/docs/concepts/storage/volumes/#nfs

安装测试nfs
1. 在所有节点上安装nfs(所有节点) yum -y install nfs-utils rpcbind 2.配置nfs [root@sg-14 opt]# vi /etc/exports /data/k8s*(rw,sync,no_root_squash)# 允许共享的ip和目录 /home/jeff192.168.0.216(rw,sync,no_root_squash)# 允许共享的ip和目录 /nfs/v1/192.168.0.216(rw,no_root_squash) /nfs/v2/192.168.0.216(rw,no_root_squash) /nfs/v3/192.168.0.216(rw,no_root_squash) /nfs/v4/192.168.0.216(rw,no_root_squash) /nfs/v5/192.168.0.216(rw,no_root_squash) /nfs/v6/192.168.0.216(rw,no_root_squash) /nfs/v7/192.168.0.216(rw,no_root_squash) /nfs/v8/192.168.0.216(rw,no_root_squash) /nfs/v9/192.168.0.216(rw,no_root_squash) /nfs/v10/ 192.168.0.216(rw,no_root_squash)[root@sg-14 opt]# systemctl enable --now nfs [root@sg-14 opt]# mkdir -pv /nfs/v{1..10} [root@sg-14 opt]# cd /nfs/ [root@sg-14 opt]# systemctl restart rpcbind.service && systemctl restart nfs.service 3.测试k8s使用nfs apiVersion: apps/v1 kind: Deployment metadata: name: nfs spec: selector: matchLabels: app: nfs template: metadata: labels: app: nfs spec: nodeName: sg-16# 指定部署机器 containers: - name: nginx image: nginx volumeMounts:# 挂载容器内部目录 - mountPath: /home/test name: nfs volumes: ## 存储卷 - name: nfs nfs: path: /nfs/v1# master上目录 server: 192.168.0.214# master机器ip4. 使用pv/pvc来管理nfs ######################################################################################### #1、部署MySQL集群 #1、创建命名空间 #2、创建service提供负载均衡 #3、使用控制器部署MySQL实例 ### #2、部署Discuz应用 #1、创建命名空间 #2、创建Service提供负载均衡(Headless Service) #3、创建服务并挂载代码 #4、创建Ingress,用于域名转发(https) ### #3、服务之间的互连 #1、Discuz连接MySQL--->mysql.mysql.svc.cluster.local #########################################################################################

pv/pvc管理nfs 官方文档
https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#reclaim-policy

pv/pvc解释
注:pv是集群级资源,pvc是名称空间级资源PVC和PV的设计,类似“接口”和“实现”的思想,开发者只知道使用“接口”PVC,运维人员负责给“接口”绑定具体的实现PV,说白了PVC就是一种特殊的Volume存储卷 PVC和PV的实现原理 PVC:描述 Pod想要使用的持久化属性,比如存储大小、读写权限等 PV:描述一个具体的Volume属性,比如Volume的类型、挂载目录、远程存储服务器地址等

1. PV 的访问模式(accessModes)
模式 解释
ReadWriteOnce(RWO) 可读可写,但只支持被单个节点挂载。
ReadOnlyMany(ROX) 只读,可以被多个节点挂载。
ReadWriteMany(RWX) 多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。
2. PV 的回收策略(persistentVolumeReclaimPolicy)
策略 解释
Retain 不清理, 保留 Volume(需要手动清理)
Recycle 删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
Delete 删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
3. PV 的状态
状态 解释
Available 可用。
Bound 已经分配给 PVC。
Released PVC 解绑但还未执行回收策略。
Failed 发生错误。
4.创建pv
kind: PersistentVolume apiVersion: v1 metadata: name: pv001 labels: app: pv001 spec: nfs: path: /nfs/v2# master机器共享目录 server: 192.168.0.214# master机器 capacity: storage: 20Gi# 指定存储卷大小 persistentVolumeReclaimPolicy: Retain# 回收策略 accessModes: # 访问模式,支持缩写 - "ReadWriteMany" - "ReadWriteOnce"kubectl apply -f pv.yaml

[root@sg-14 nfs]# kubectl get pv NAMECAPACITYACCESS MODESRECLAIM POLICYSTATUSCLAIMSTORAGECLASSREASONAGE pv00120GiRWO,RWXRetainAvailable7sSTATUS状态:无

5.pvc插件
官方文档
https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#access-modes

pvc使用pv-创建pvc
--- # 创建pv kind: PersistentVolume apiVersion: v1 metadata: name: pv001 labels: app: pv001 spec: nfs: path: /nfs/v2# master机器共享目录 server: 192.168.0.214# master机器 capacity: storage: 20Gi# 指定存储卷大小 persistentVolumeReclaimPolicy: Retain# 回收策略 accessModes: # 访问模式,支持缩写 - "ReadWriteMany" - "ReadWriteOnce" --- # 创建名称空间 apiVersion: v1 kind: Namespace metadata: name: mysql labels: app: test-Namespace --- # 创建pvc存储卷 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1# 存储卷名字 namespace: mysql # 指定名称空间,pvc是名称空间级资源 spec: accessModes:# 访问模式 - "ReadWriteMany" resources: requests: storage: "6Gi"kubectl apply -f pvc.yaml

[root@sg-14 nfs]# kubectl get pv NAMECAPACITYACCESS MODESRECLAIM POLICYSTATUSCLAIMSTORAGECLASSREASONAGE pv00120GiRWO,RWXRetainBounddefault/pvc147m[root@sg-14 nfs]# kubectl get pvc NAMESTATUSVOLUMECAPACITYACCESS MODESSTORAGECLASSAGE pvc1Boundpv00120GiRWO,RWX2m22s状态:Bound CLAIM:default/pvc1

pv-pvc.yaml 使用nfs
apiVersion: apps/v1 kind: Deployment metadata: name: pv-pvc-mysql namespace: mysql # 指定名称空间 spec: replicas: 3 # 部署个数 selector: matchLabels: app: pv-pvc template: metadata: labels: app: pv-pvc spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: "123456" volumeMounts:# 挂载容器内部目录 - mountPath: /var/lib/mysql name: pv-pvc volumes: ## 存储卷master - name: pv-pvc persistentVolumeClaim: claimName: pvc1# 指定存储卷名字kubectl apply -f pv-pvc.yaml 此时:所有的容器/var/lib/mysql目录和master的/nfs/v2实现共享kubectl exec -it npv-pvc-f76d748dd-ps7rs -- bash# 进入容器 mysql -u root -p # 登陆数据库

    推荐阅读