K8s-持久化存储
一、emptyDir
emptyDir
是 Pod 生命周期内的临时存储卷。当 Pod 被创建时,
emptyDir
会被 初始化为空目录。Pod 内的所有容器都可以 共享访问同一个
emptyDir
。当 Pod 被删除时,
emptyDir
中的数据也会被 永久删除。kubectl explain pods.spec.volumesemptyDir hostPath nfs persistentVolumeClaim glusterfs cephfs configMap secret
1、emptyDir
配置示例
apiVersion: v1 kind: Pod metadata:name: emptydir-demo spec:containers:- name: appimage: busyboxcommand: ["sh", "-c", "while true; do echo $(date) >> /data/log.txt; sleep 5; done"]volumeMounts:- name: data-volumemountPath: /datavolumes:- name: data-volumeemptyDir: {}
volumes
定义了一个emptyDir
卷。
volumeMounts
将这个卷挂载到容器的/data
目录。容器会向
/data/log.txt
写日志,Pod 删除后这些日志也会消失。
二、hostPath
hostPath
是 将宿主机(Node)上的目录或文件挂载到 Pod 内的卷。容器可以直接访问宿主机文件系统。
数据 随着 Pod 删除不会消失,因为它存在于宿主机上。
强依赖节点:Pod 必须调度到拥有对应路径的节点,否则会报错。
kubectl explain pods.spec.volumes.hostPath
apiVersion: v1 kind: Pod metadata:name: hostpath-demo spec:containers:- name: appimage: busyboxcommand: ["sh", "-c", "while true; do ls /host-data; sleep 5; done"]volumeMounts:- name: host-volumemountPath: /host-datavolumes:- name: host-volumehostPath:path: /tmp/host-datatype: DirectoryOrCreate
path
:宿主机上的目录/tmp/host-data
type
:指定类型,有以下几种:
Directory
→ 必须是已存在的目录
DirectoryOrCreate
→ 如果不存在就创建
File
→ 必须是已存在的文件
FileOrCreate
→ 如果不存在就创建
Socket
、CharDevice
、BlockDevice
→ 对应特殊文件类型容器挂载
/host-data
后,访问的就是宿主机/tmp/host-data
的内容。
三、nfs
NFS 是一种 网络文件系统,允许不同的主机通过网络访问同一个共享目录。
Kubernetes 可以通过 NFS 挂载一个共享目录到 Pod,数据存放在 独立的存储服务器上,不依赖 Pod 或 Node 的生命周期。
数据持久化,Pod 删除或重建 数据不会丢失。
1、安装配置nfs
yum install nfs-utils -y##共享目录 mkdir /data/volumes -pv#配置 nfs 共享服务器上的/data/volumes 目录 vim /etc/exports/data/volumes 192.168.200.0/24(rw,no_root_squash) #no_root_squash: 用户具有根目录的完全管理访问权限###使 NFS 配置生效 exportfs -arv ----exporting 192.168.200.0/24:/data/volumesservice nfs start ----Redirecting to /bin/systemctl start nfs.service###设置成开机自启动 systemctl enable nfs #查看 nfs 是否启动成功 systemctl status nfs Active: active ##看到 nfs 是 active,说明 nfs 正常启动了 ##k8s2 也安装 nfs 驱动 yum install nfs-utils -y systemctl enable nfs 在 k8s2 上手动挂载试试: [root@k8s2 ~]# mkdir /test [root@k8s2 ~]# mount 192.168.200.167:/data/volumes /test/df -h 192.168.200.167:/data/volumes 40G 5.2G 35G 11% /test
2、使用例子
apiVersion: v1 kind: Pod metadata:name: test-nfs-volume spec:containers:- name: test-nfsimage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80protocol: TCPvolumeMounts:- name: nfs-volumes # 容器内挂载的卷名称mountPath: /usr/share/nginx/html # 容器内挂载路径volumes:- name: nfs-volumes # 卷定义名称nfs:path: /data/volumes # NFS 服务器上的共享目录server: 192.168.200.167 # NFS 服务器 IPkubectl apply -f nfs.yamlkubectl get pods -o wide | grep nfs test-nfs-volume 1/1 Running 10.244.185.105 k8s2
volumes
定义了 Pod 可以使用的存储卷。这里使用的是 NFS 卷,指向服务器192.168.200.167
的/data/volumes
。
volumeMounts
指容器内部访问卷的路径。这里将 NFS 挂载到 Nginx 的默认网页目录/usr/share/nginx/html
,意味着 NFS 里的文件会直接被 Nginx 访问。
imagePullPolicy: IfNotPresent
表示如果本地已有 nginx 镜像,则不拉取。
四、k8s 持久化存储: PVC、PV
名称 含义 特点 PV (PersistentVolume) 集群中的一块存储资源(可以是 NFS、Ceph、HostPath、iSCSI 等) 由管理员配置,生命周期独立于 Pod PVC (PersistentVolumeClaim) 用户对存储的申请(请求容量、访问模式等) Pod 使用 PVC 来挂载存储,无需关心具体 PV
PV 是 “存储资源池”,PVC 是 “存储需求申请”。
Kubernetes 会 自动把 PVC 绑定到合适的 PV,实现存储与 Pod 解耦。
1、PV + PVC + Pod 使用 NFS 的例子
##NFS 服务器 IP 是 192.168.200.167,共享目录为 /data/volumes,确保目录有读写权限: sudo mkdir -p /data/volumes sudo chmod 777 /data/volumes
1.2创建 PV
apiVersion: v1 kind: PersistentVolume metadata:name: nfs-pv spec:capacity:storage: 5Gi # PV 总容量accessModes:- ReadWriteMany # 多 Pod 可读写nfs:path: /data/volumes # NFS 共享目录server: 192.168.200.167 # NFS 服务器 IPpersistentVolumeReclaimPolicy: Retain # Pod 删除 PV 不删除
persistentVolumeReclaimPolicy
可选:
Retain
→ 保留数据
Delete
→ 删除 PV 时删除数据(适用于动态存储)
Recycle
→ 清空目录后重用(已废弃)
1.3创建 PVC
apiVersion: v1 kind: PersistentVolumeClaim metadata:name: nfs-pvc spec:accessModes:- ReadWriteManyresources:requests:storage: 5Gi
1.4Pod 使用 PVC
apiVersion: v1 kind: Pod metadata:name: nfs-pvc-demo spec:containers:- name: appimage: busyboxcommand: ["sh", "-c", "while true; do echo $(date) >> /data/log.txt; sleep 5; done"]volumeMounts:- mountPath: /dataname: nfs-storagevolumes:- name: nfs-storagepersistentVolumeClaim:claimName: nfs-pvc
容器
/data
实际访问的是 NFS 服务器/data/volumes
数据随 Pod 删除或重建 不会丢失
五、StorageClass存储类
StorageClass 定义了一类存储的属性,例如存储类型、性能等级、回收策略等。
它允许 PVC 在创建时动态创建 PV,用户无需提前手动创建 PV。
通过 StorageClass,可以实现 存储抽象和统一管理,适合生产环境。
kubectl explain storageclass
字段 说明 provisioner
指定存储插件或 CSI 驱动,例如 kubernetes.io/nfs
、kubernetes.io/aws-ebs
、csi.xxx
parameters
插件相关参数,例如磁盘类型、文件系统类型、NFS 服务器地址等 reclaimPolicy
PV 删除后的回收策略: Delete
或Retain
volumeBindingMode
卷绑定模式: Immediate
(立即绑定)或WaitForFirstConsumer
(延迟绑定)allowVolumeExpansion
是否允许 PVC 扩容 mountOptions
挂载时的额外选项,例如 rw
,noatime
1、StorageClass 示例(NFS)
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: nfs-sc provisioner: example.com/nfs # 你集群的 NFS CSI 驱动 parameters:server: 192.168.40.180path: /data/volumes reclaimPolicy: Retain volumeBindingMode: Immediate allowVolumeExpansion: true mountOptions:- hard- nfsvers=4.1
provisioner
→ CSI 驱动名称,K8s 用它动态创建 PV
parameters.server
→ NFS 服务器 IP
parameters.path
→ NFS 共享目录
reclaimPolicy: Retain
→ Pod 删除后 PV 数据保留
allowVolumeExpansion: true
→ PVC 可以在线扩容
2、使用 StorageClass 动态创建 PVC
apiVersion: v1 kind: PersistentVolumeClaim metadata:name: dynamic-pvc spec:accessModes:- ReadWriteManystorageClassName: nfs-sc # 指定 StorageClassresources:requests:storage: 5Gi
这个 PVC 会 自动通过 StorageClass 创建 PV
不需要提前手动创建 PV
PVC 删除时,可根据
reclaimPolicy
删除或保留 PV