k8s的存储卷、数据卷

容器内的目录和宿主机目录进行挂载。

容器在系统上的生命周期是短暂的。

k8s用控制器创建的pod。delete相当于重启。容器的状态也会恢复到初始状态。一旦恢复到初始状态,所有的后天编辑的文件都会消失

容器和节点之间创建一个可以持久化保存容器内文件的存储卷。即使容器被摧毁、删除、重启,节点上存储卷的数据依旧存在。后续也可以继续使用。可以继续讲容器内的目录和宿主机挂载。保存的数据可以继续使用。

存储卷的方式

  1. emptyDir:

  2. hostPath:

  3. NFS:

emptyDir

emptyDir:容器内部共享存储卷。在k8s中表示一个pod当中的多个容器共享一个存储卷目录。

emptyDir卷可以使pod当中的容器在这个存储卷上读取和写入。

emptyDir不能挂载到节点。随着pod生命周期结束。emptyDir也会结束。数据不会保留

主要用于容器内部共享数据

实验举例:

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
#开始创建挂载卷
        - name: html
#定义存储卷的名称
          mountPath: /usr/share/nginx/html
#mountPath:定义容器内的挂载点。或者其他容器的共享目录
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
#需要和上面定义的名称保持一致
          mountPath: /data
#引用上一个挂载的名称。
#表示我将使用/data目录和/usr/share/nginx/html这个目录挂载
        command: ["/bin/bash", "-c", "while true; do echo $(data) >> /data/index.html; sleep 2; done"]
      volumes:
      - name: html
        emptyDir: {}

hostPath

hostPath:将容器内的挂载点和节点上的目录进行挂载。hostPath可以实现数据持久。node节点被销毁,那么数据也会丢失。

污点设置为NoExecute时节点上的pod会被驱逐。文件数据在不在?

文件数据肯定在的。只是pod节点被销毁了。并不是node节点被销毁。所有数据还保留在节点上。

只有基于控制器创建的pod会在其他节点重新部署。他又会在其他节点生成一个新的存储卷。数据依然可以持久化。

驱逐不会使文件数据丢失

实验举例:

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
#开始创建挂载卷
        - name: html
#定义存储卷的名称
          mountPath: /usr/share/nginx/html
#mountPath:定义容器内的挂载点。或者其他容器的共享目录
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
#需要和上面定义的名称保持一致
          mountPath: /data
#引用上一个挂载的名称。
#表示我将使用/data目录和/usr/share/nginx/html这个目录挂载
        command: ["/bin/bash", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]
      volumes:
      - name: html
        hostPath:
          path: /opt/test
          type: DirectoryOrCreate
#如果节点上没有这个目录则帮你创建这个目录

实现nginx1、nginx2、节点是平级关系实现三方同步

相同pod不同容器的信息

bash 复制代码
kubectl exec -it pod名称 -c 容器名称 bash
#进入相同pod中的不同容器
kubectl logs pod名称 -c 容器名称
#查看相同pod中的不同容器的日志

nfs共享存储

所有pod内的目录都和节点上的nfs共享目录形成数据卷。所有的数据文件都保存在共享目录当中。集中方便管理

nfs共享的工作流程图:

创建nfs共享目录

bash 复制代码
mkdir /data/volumes
chmod 777 /data/volumes
vim /etc/exports
/data/volumes 20.0.0.0/24(rw,no_root_squash)
#rw,no_root_squash:给客户机访问本地提供本地root权限

实验举例:

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
#开始创建挂载卷
        - name: html
#定义存储卷的名称
          mountPath: /usr/share/nginx/html
#mountPath:定义容器内的挂载点。或者其他容器的共享目录
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
#需要和上面定义的名称保持一致
          mountPath: /data
#引用上一个挂载的名称。
#表示我将使用/data目录和/usr/share/nginx/html这个目录挂载
        command: ["/bin/bash", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]
      volumes:
      - name: html
        nfs:
          path: /data/volumes
#表示将容器和节点目录进行挂载
          server: 20.0.0.35
#这里可以使用IP地址也可以使用主机名来替代。但是需要做主机名映射

基于yaml文件删除:

bash 复制代码
kubectl delete -f 文件名称.yaml
#如果是基于这个yaml文件创建的pod。可以使用这种方式删除deployment。

工作中最常见的是hostPath和NFS。推荐使用NFS

PVC和PV

PV:全程Persistent Volume 持久化存储卷。用来描述和定义一个存储卷。

PV是由运维人员来定的。

PVC:全程Persistent Volume Claim 是存储化存储的请求。

PVC是用来描述或者声明我希望使用什么样的PV来进行存储。

PVC和PV是一一对应的关系(描述、存储)

描述:期望的PV的类型是什么

存储:PV存储的大小是什么

PVC请求PV到NFS

PVC发起请求

PV是满足请求的存储卷

在k8s中PVC和PV都是虚拟化的概念。是一种虚拟存储资源。

PVC和PV的结构图:

PVC提供读写方式、存储空间等等。

PV的虚拟存储会通过NFS共享存储的方式挂载到提供共享目录的服务器

PVC发起请求的读写方式会和PV保持一致。

PVC会匹配最完整、最优路径。如果pv3被占用了,则会选择pv4。

PV和PVC静态请求的工作流程:

1、 pod内设定声明一个PVC请求。

2、 PVC请求会找一个最合适的PV来作为pod的存储卷。

3、 PV和共享目录在一一映射。

4、 最终由NFS共享目录来提供实际物理上的共享存储空间。

PV是集群当中的存储资源。PVC请求存储资源。也是对存储资源的一个检索(检查索引),选择一个最合适的PV来存储资源。

PV和PVC的生命周期管理:

  1. Provisioning(配置)配置两种方式选择动态还是静态PVC

  2. PVC请求request

  3. 检索。找一个合适的PV

  4. PVC和PV会binding(绑定):就是将PV分配给PVC

  5. 然后开始使用:就是pod通过PVC使用存储资源NFS

删除pod时:

  1. pod被删除

  2. PV会releasing(释放):pod解除和volume共享挂载卷的关系,删除PVC

  3. 最后recycling(回收资源):保留PV。保证下一个PVC也可以使用。

PV的状态

  1. Available:可用,没有被任何PVC绑定。

  2. Bound:绑定,PV已经绑定了PVC,绑定即使用。

  3. released:PVC已经被删除了,但是PV的存储资源还没有被集群回收

  4. Failed:表示PV的资源回收失败。而且PV不可用状态。

PVC支持的读写方式

ReadWriteOnce:简称RWO。配置文件中是全称。表示存储PV可读可写。但是只能被单个pod挂载

ReadOnlyMany:简称ROX。在配置文件中是全称。表示存储PV可用以只读的方式被多个pod挂载。

ReadWriteMany: 简称RWX。在配置文件中是全称。表示存储可以支持读写的方式被多个pod共享。

NFS:可以支持三种读写和挂载方式

hostPath:只支持ReadWriteOnce方式

SCSI:

ISCSI:不支持ReadWriteMany

环境检擦

bash 复制代码
lsscsi
#查看当前设备上的SCSI设备
iscsiadm -m session -P 3
#查看服务器是否有iscsi设备
#-m session:指定操作的会话模块,管理iscsi的会话
#-P 3:显示详细信息的级别。级别是3.显示详细信息。

集群回收PV资源的方式

  1. Retain:表示保留。pod和挂载点的数据不会被删除。默认方式。

  2. Recycle:表示回收。PV上的数据将会被删除。挂载点的数据也会被删除。

  3. Delete:表示删除。解绑时自动删除PV上的数据。本地硬盘不能使用只有云平台可以使用(AWS/EBS/GCE)。支持动态卷可用。PV不再使用(云平台自己处理)

当pod运行之后通过PVC请求到PV之后,除非pod被销毁,否则无法删除PVC

PVC和PV静态实验举例:

bash 复制代码
master01:20.0.0.32
node01:20.0.0.34
node02:20.0.0.35
k8s4主机:20.0.0.36

k8s5主机:
mkdir v{1,2,3,4,5}
vim /etc/exports
/data/v1 20.0.0.0/24(rw,no_root_squash)
/data/v2 20.0.0.0/24(rw,no_root_squash)
/data/v3 20.0.0.0/24(rw,no_root_squash)
/data/v4 20.0.0.0/24(rw,no_root_squash)
/data/v5 20.0.0.0/24(rw,no_root_squash)
exportfs -arv
#发布出去
showmount -e
#在每个节点上查看

到master01主节点上创建PV.yaml文件
vim pv.yaml
apiVersion: v1
kind: PersistentVolume
#PersistentVolume就是PV但是yaml文件中要用全称
metadata:
  name: pv001
  labels:
    name: pv001
spec:
#设定pv的参数
  nfs:
    path: /data/v1
#定义pv的挂载位置
    server: 20.0.0.36
#声明pv来自哪个IP地址
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
#ReadWriteMany表示支持多个pod挂载
#ReadWriteOnly表示只支持单个pod挂载
#支持多种挂载方式
  capacity:
    storage: 1Gi
#定义pv的大小

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/v2
    server: 20.0.0.36
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/v3
    server: 20.0.0.36
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  capacity:
    storage: 2Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/v4
    server: 20.0.0.36
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  capacity:
    storage: 4Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/v5
    server: 20.0.0.36
  accessModes: ["ReadWriteMany", "ReadWriteOnce", "ReadOnlyMany"]
  capacity:
    storage: 5Gi

kubectl apply -f pv.yaml
#创建PV
kubectl get pv
#查看PV状态

定义一个请求向PV发起请求
vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
#定义这是PVC请求类型
metadata:
  name: mypvc
spec:
#定义参数
  accessModes: ["ReadWriteMany"]
#这里表示PVC期望请求的PV的读写挂载类型是什么。我希望能和PV请求到的是ReadWriteMany模式
  resources:
    requests:
      storage: 2Gi
#PVC期望请求PV的存储大小是2Gi
#期望的PV的读写权限模式是ReadWriteMany,并且存储大小最好是2Gi。
#最好是2G。只能比2G不能比2G小

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx2
  name: nginx2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx2
  template:
    metadata:
      labels:
        app: nginx2
    spec:
      containers:
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: mypvc
#定义pvc的名称.由mypc获取PV

kubectl get pv
#查看PV状态
表示请求成功

到k8s
kubectl get pv
cd v3
echo 123 > index.html

回到master01主机
kubectl get pod -o wide
curl nginx副本IP测试

PVC发起请求选择使用哪个PV的存储

PV通过挂载的方式和物理存储做映射

最终由物理设备提供存储卷

资源回收的方式实验举例:

bash 复制代码
保留策略:
kubectl delete pvc mypvc
#pod还存在无法删除PVC

kubectl delete deployment nginx
#删除pod后再删除PVC即可

出现released表示回收完毕
回到k8s5主机查看共享文件是否存在

kubectl edit pv pv003
把claimRef字段的内容全部删除保存推测出即可
kubectl get pv

---
回收策略:

回到pv.yaml添加回收策略
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/v3
    server: 20.0.0.36
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  persistenVolumeReclaimPolicy: Recycle
  capacity:
    storage: 2Gi

kubectl apply -f pv.yaml
kubectl get pv

到k8s5
echo 123 > index.html

回到master01
开始删除
kubectl delete deployment nginx
kubectl delete pvc mypvc
#先删除相关联的pod再删除pvc
kubectl get pv
一段时间之后会自动变成正常状态
再回到k8s5查看资源是否被回收

---
delete策略:
delete只能在云平台且支持动态卷。本地硬盘并不支持。只能使用无法删除
回到pv.yaml添加回收策略
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/v3
    server: 20.0.0.36
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  persistenVolumeReclaimPolicy: Delete
  capacity:
    storage: 2Gi

kubectl apply -f pv.yaml
kubectl get pv

回到k8s5
echo 123 > index.html

回到master01
开始删除
kubectl delete deployment nginx
kubectl delete pvc mypvc
#先删除相关联的pod再删除pvc
kubectl get pv
这时会变为Failled状态
kubectl edit pv pv003
把claimRef字段的内容全部删除保存推测出即可
kubectl get pv
PV状态恢复正常
实验完成!!!

总结

k8s中存储卷的模式:

  1. emptyDir:容器内存储卷,锁着pod被销毁,他也会被销毁。数据不保留

  2. hostPath:节点目录的存储卷,可用实现持久化存储。数据在每个节点上都有。不方便集中管理

  3. nfs:共享目录存储卷。既可以实现持久化也可也实现数据集中在一个目录。这样方便管理。

PV和PVC:

  1. PVC是一种请求。请求的是PV的存储资源。PV通过挂载的方式与硬盘空间共享资源

  2. NFS支持PVC的所有挂载方式和读写模式

  3. hostPath只支持ReadWriteOnce模式

  4. PVC是以检索的方式找到匹配的PV资源

检索挂载方式和读写模式

检索PV能提供的存储资源的大小

谁合适选谁

资源回收的三种方式:

  1. 保留:默认可用不写

  2. 回收:自动回收,节点上的数据会被删除

  3. 删除:PV会变成failed模式。此时是不可用状态。数据也会被删除。

PVC和PV之间静态请求。一旦成百个PVC负载能力将会下降,这就需要使用动态PVC

静态比较麻烦。动态PVC实现自动的匹配PV资源

相关推荐
能不能别报错4 小时前
K8s学习笔记(十六) 探针(Probe)
笔记·学习·kubernetes
一水鉴天5 小时前
整体设计 逻辑系统程序 之18 Source 容器(Docker)承载 C/P/D 三式的完整设计与双闭环验证 之2
docker·架构·认知科学·公共逻辑
能不能别报错6 小时前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
飞快的蜗牛7 小时前
利用linux系统自带的cron 定时备份数据库,不需要写代码了
java·docker
火星MARK7 小时前
k8s面试题
容器·面试·kubernetes
香吧香8 小时前
Docker Registry 使用总结
docker
赵渝强老师9 小时前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
haicome10 小时前
deepseek部署
docker·ragflow·deepseek 部署
能不能别报错10 小时前
K8s学习笔记(十五) pause容器与init容器
笔记·学习·kubernetes
稚辉君.MCA_P8_Java10 小时前
kafka解决了什么问题?mmap 和sendfile
java·spring boot·分布式·kafka·kubernetes