K8s-持久化存储

发布于:2025-08-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、emptyDir

  • emptyDir Pod 生命周期内的临时存储卷

  • 当 Pod 被创建时,emptyDir 会被 初始化为空目录

  • Pod 内的所有容器都可以 共享访问同一个 emptyDir

  • 当 Pod 被删除时,emptyDir 中的数据也会被 永久删除

kubectl explain pods.spec.volumes

emptyDir 
hostPath 
nfs 
persistentVolumeClaim 
glusterfs 
cephfs 
configMap 
secret

1、emptyDir 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: emptydir-demo
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "while true; do echo $(date) >> /data/log.txt; sleep 5; done"]
    volumeMounts:
    - name: data-volume
      mountPath: /data
  volumes:
  - name: data-volume
    emptyDir: {}
  • 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: app
    image: busybox
    command: ["sh", "-c", "while true; do ls /host-data; sleep 5; done"]
    volumeMounts:
    - name: host-volume
      mountPath: /host-data
  volumes:
  - name: host-volume
    hostPath:
      path: /tmp/host-data
      type: DirectoryOrCreate
  • path:宿主机上的目录 /tmp/host-data

  • type:指定类型,有以下几种:

    • Directory → 必须是已存在的目录

    • DirectoryOrCreate → 如果不存在就创建

    • File → 必须是已存在的文件

    • FileOrCreate → 如果不存在就创建

    • SocketCharDeviceBlockDevice → 对应特殊文件类型

  • 容器挂载 /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/volumes

service 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-nfs
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      protocol: TCP
    volumeMounts:
    - name: nfs-volumes        # 容器内挂载的卷名称
      mountPath: /usr/share/nginx/html  # 容器内挂载路径
  volumes:
  - name: nfs-volumes           # 卷定义名称
    nfs:
      path: /data/volumes       # NFS 服务器上的共享目录
      server: 192.168.200.167    # NFS 服务器 IP


kubectl apply -f nfs.yaml

kubectl 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 服务器 IP
  persistentVolumeReclaimPolicy: Retain   # Pod 删除 PV 不删除
  • persistentVolumeReclaimPolicy 可选:

    • Retain → 保留数据

    • Delete → 删除 PV 时删除数据(适用于动态存储)

    • Recycle → 清空目录后重用(已废弃)

1.3创建 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

1.4Pod 使用 PVC

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pvc-demo
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "while true; do echo $(date) >> /data/log.txt; sleep 5; done"]
    volumeMounts:
    - mountPath: /data
      name: nfs-storage
  volumes:
  - name: nfs-storage
    persistentVolumeClaim:
      claimName: nfs-pvc
  • 容器 /data 实际访问的是 NFS 服务器 /data/volumes

  • 数据随 Pod 删除或重建 不会丢失

五、StorageClass存储类

  • StorageClass 定义了一类存储的属性,例如存储类型、性能等级、回收策略等。

  • 它允许 PVC 在创建时动态创建 PV,用户无需提前手动创建 PV。

  • 通过 StorageClass,可以实现 存储抽象和统一管理,适合生产环境。

kubectl explain storageclass
字段 说明
provisioner 指定存储插件或 CSI 驱动,例如 kubernetes.io/nfskubernetes.io/aws-ebscsi.xxx
parameters 插件相关参数,例如磁盘类型、文件系统类型、NFS 服务器地址等
reclaimPolicy PV 删除后的回收策略:DeleteRetain
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.180
  path: /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:
    - ReadWriteMany
  storageClassName: nfs-sc    # 指定 StorageClass
  resources:
    requests:
      storage: 5Gi
  • 这个 PVC 会 自动通过 StorageClass 创建 PV

  • 不需要提前手动创建 PV

  • PVC 删除时,可根据 reclaimPolicy 删除或保留 PV

###有待补充。。。。。。

网站公告

今日签到

点亮在社区的每一天
去签到