十二、kubernetes 1.29 之 存储 Volume、pv/pvc
一、Volume
1、定义
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失一一容器以干净的状态(镜像最初的状态)重新启动。其次,在 Pod 中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的 Volume 抽象就很好的解决了这些问题。
2、类型-emptyDir
2.1 概念
当 Pod 被分配给节点时,首先创建 emptyDir 卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir 中的数据将被永久删除。
容器崩溃不会从节点中移除 Pod,因此 emptyDir 卷中的数据在容器崩溃时是安全的。
emptyDir 的用法有:
暂存空间,例如用于基于磁盘的合并排序、用作长时间计算崩溃恢复时的检查点
Web 服务器容器提供数据时,保存内容管理器容器提取的文件
2.2 存储机制
📋 技术说明
kubelet 的 emptyDir 卷存储机制
在 kubelet 的工作目录(由
root-dir
参数控制,默认为/var/lib/kubelet
)中,会为每个使用emptyDir: {}
空目录卷的 Pod 创建一个特定格式的子目录:/var/lib/kubelet/pods/{podid}/volumes/kubernetes.io~empty-dir/
核心要点:
工作目录:
/var/lib/kubelet
(可通过root-dir
参数配置)目录结构:
pods/{podid}/volumes/kubernetes.io~empty-dir/
数据存储:所有放在 emptyDir 卷中的数据最终都存储在节点的上述路径中
实际示例:
如果 Pod 的 ID 为
abc123
,那么对应的 emptyDir 卷数据将存储在:/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~empty-dir/
这个机制确保了 emptyDir 卷的数据在 Pod 运行期间持久存储在节点上,但在 Pod 被删除时会被清理。
2.3 演示
emptyDir: {} 空方式
创建资源清单,
Pod基本信息:
名称:
volume-emptydir-pod
命名空间:
default
容器配置:
myapp容器:运行Nginx应用,挂载卷到
/usr/local/nginx/logs
busybox容器:执行日志监控命令,挂载卷到
/logs
卷配置:
使用
emptyDir
类型的卷logs-volume
两个容器共享同一个卷,但挂载到不同路径
功能说明:
此配置实现了两个容器间的文件共享
busybox容器创建并监控access.log文件
myapp容器(Nginx)可以将日志写入同一位置
适合用于容器间的日志共享和监控场景
apiVersion: v1
kind: Pod
metadata:name: volume-emptydir-podnamespace: default
spec:containers:- name: myappimage: wangyanglinux/myapp:v1.0ports:- containerPort: 80volumeMounts:- name: logs-volumemountPath: /usr/local/nginx/logs- name: busyboximage: wangyanglinux/tools:busyboxcommand: ["/bin/sh", "-c", "touch /logs/access.log && tail -f /logs/access.log"]volumeMounts:- name: logs-volumemountPath: /logsvolumes:- name: logs-volumeemptyDir: {}
创建运行
安装树文件系统
注意linux时间是否正常,否则无法获取资源
yum -y install tree
查看当下目录层级
tree .
共享内存
存储卷配置(核心特性)
卷类型:
emptyDir
(临时存储卷)存储介质:
Memory
(使用内存而非磁盘)大小限制:
500Mi
(最大使用500MB内存)挂载路径: 容器内的
/data
目录技术特点说明
emptyDir卷的特性:
生命周期与Pod绑定,Pod删除时数据自动清除
适合临时数据存储和容器间文件共享
使用场景:
临时缓存文件存储
容器间高速数据共享
需要高性能读写的临时工作目录
apiVersion: v1
kind: Pod
metadata:name: volume-emptydir-memnamespace: default
spec:containers:- name: myappimage: wangyanglinux/myapp:v1.0ports:- containerPort: 80resources:limits:cpu: "1"memory: 1024Mirequests:cpu: "1"memory: 1024MivolumeMounts:- name: mem-volumemountPath: /datavolumes:- name: mem-volumeemptyDir:medium: MemorysizeLimit: 500Mi
3、hostPath 主机路径
3.1 概念
hostPath 卷将主机节点的文件系统中的文件或目录挂载到集群中
hostPath 用途如下:
运行需要访问 Docker 内部的容器;使用
/var/lib/docker
的hostPath
在容器中运行 cAdvisor;使用
/dev/cgroups
的hostPath
允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在
除了所需的
path
属性之外,用户还可以为hostPath
卷指定type 类型
3.2 type 类型
3.3 注意
环境一致性风险 - hostPath 依赖节点本地文件系统,可能导致跨节点部署不一致
资源调度盲区 - 未来的资源感知调度器无法统计 hostPath 的资源占用
权限管理挑战 - 默认 root 权限要求,需要特殊配置才能正常写入
3.4 实验
存储卷配置:
卷名称:
test-volume
卷类型:
hostPath
(主机路径卷)主机路径:
/data
(节点上的目录)路径类型:
Directory
(必须是已存在的目录)使用说明:
此配置将节点上的
/data
目录挂载到Pod容器的/test-pd
路径容器内对
/test-pd
的读写操作将直接反映在节点的/data
目录上适合需要访问节点本地文件系统的场景,如日志收集、配置文件访问等
apiVersion: v1
kind: Pod
metadata:name: hostpath-pod
spec:containers:- name: myappimage: wangyanglinux/myapp:v1.0volumeMounts:- name: test-volumemountPath: /test-pdvolumes:- name: test-volumehostPath:path: /datatype: Directory
如果/data不存在,就会报错,目录不存在
二、PV/PVC 持久卷和持久卷申请
1、概念
为了减少跨部门沟通和分工明确,
业务工程师需要使用存储的时候,会去写一个PVC来申请存储
存储工程师为了满足业务工程师的存储需求,会写PV来被PVC匹配
匹配的时候有初选和优选
2、关联条件
3、回收策略
4、状态表示
5、PVC保护
PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失。
注意:当pod状态为
Pending
并且pod已经分配给节点或pod为Running
状态时,PVC处于活动状态。当启用PVC保护功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何pod使用。
实验
(搭建一个NFS的服务器,然后PV匹配,产生保护)
安装NFS服务器
(每一个节点)
# 1. 安装 NFS 相关软件包
k8s 7 不需要安装 nfs-common
yum install -y nfs-common nfs-utils rpcbind
(主节点)
# 2. 创建 NFS 共享目录
mkdir /nfsdata# 3. 设置目录权限
chmod 666 /nfsdata
chown nobody /nfsdata# 4. 配置 NFS 导出目录
cat /etc/exports
echo '/nfsdata *(rw,no_root_squash,no_all_squash,sync)' >> /etc/exportscd /nfsdata/
mkdir {1..10}echo "1" > 1/index.html
echo "2" > 2/index.html
echo "3" > 3/index.html
echo "4" > 4/index.html
echo "5" > 5/index.html
echo "6" > 6/index.html
echo "7" > 7/index.html
echo "8" > 8/iadex.html
echo "9" > 9/index.html
echo "10" > 10/index.htmlvim /etc/exports
/nfsdata/1 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/2 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/3 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/4 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/5 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/6 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/7 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/8 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/9 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/10 *(rw,no_root_squash,no_all_squash,sync)# 5. 启动 NFS 相关服务
systemctl start rpcbind
systemctl start nfs-server#6查看
showmount -e 192.168.125.101
(节点01 挂载)
sudo mkdir -p /nfstest
mount -t nfs 192.168.125.101:/nfsdata/1 /nfstest/
解除从几点挂载
umount /nfstest/
装换成PV
存储配置
存储容量: 1GiB
访问模式: ReadWriteOnce (单节点读写)
回收策略: Recycle (回收)
存储类名称:
nfs
3. NFS 存储后端
NFS服务器:
10.66.66.10
共享路径:
/data/nfs
4. 关键特性说明
ReadWriteOnce: 只能被单个节点以读写方式挂载
Recycle策略: 当PV被释放后,会自动清理数据(删除目录内容)
NFS存储: 使用网络文件系统作为后端存储
这个PV定义创建了一个使用NFS作为后端存储的持久卷,可供Kubernetes集群中的Pod通过PersistentVolumeClaim来申请使用。
apiVersion: v1 kind: PersistentVolume metadata:name: nfspv1 spec:capacity:storage: 1GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RecyclestorageClassName: nfsnfs:path: /nfsdata/1server: ip.....一直到 nfspv10 ,改path和内容、类、读写模式
保存创建
无头服务、给StateFulset,没有负载均衡
会将标签匹配到的pod ,ip添加到,svc的解析结果去
apiVersion: v1 kind: Service metadata:name: nginxlabels:app: nginx spec:ports:- port: 80name: webclusterIP: None # 无头服务selector:app: nginx
StateFulset 有状态POD控制器
1、有序创建,(先1后2),有序回收(倒序)
2、数据持久化(pod级别),
3、稳定的网络访问方式(重建地址不变),
域名:podname.无头svcname.nsname.svc.domainName.
apiVersion: apps/v1 kind: StatefulSet metadata:name: web spec:selector:matchLabels:app: nginxserviceName: "nginx"replicas: 3template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestvolumeMounts:- name: wwwmountPath: /usr/local/nginx/htmlvolumeClaimTemplates:- metadata:name: wwwspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "nfs"resources:requests:storage: 1Gi
回收
删除本身资源清单,
名字不变重启后自动挂载
PVC得手动删,保护数据挂载
(现在成了释放状态,无法被自动关联,如果想关联得变成活跃状态哦)
干掉申请来源(期望和nfs之间),PV就会变成可用状态