k8s-持久化存储

Kubernetes 持久化存储全解析:从基础到实践

在 Kubernetes 集群中,Pod 作为最小部署单元具有生命周期特性,当 Pod 被删除或重启时,容器内的数据会随之丢失。对于 MySQL、Redis 等需要持久化数据的应用来说,这是不可接受的。因此,Kubernetes 提供了多种持久化存储方案,本文将详细介绍常用的存储方式及其使用方法。

一、Kubernetes 持久化存储概述

Kubernetes 支持多种存储卷类型,通过 kubectl explain pods.spec.volumes 命令可以查看所有支持的存储类型,其中常用的包括:

  • emptyDir
  • hostPath
  • nfs
  • persistentVolumeClaim(PVC)
  • glusterfs
  • cephfs
  • configMap
  • secret

使用存储卷通常需要两步:

  1. 定义 Pod 的 volume,指定关联的存储
  2. 在容器中通过 volumeMounts 挂载对应的存储

二、emptyDir:临时存储卷

emptyDir 是在 Pod 分配到 Node 时自动创建的临时目录,其生命周期与 Pod 一致,当 Pod 从 Node 上移除时,emptyDir 中的数据会被永久删除。适用于临时目录或多容器共享目录。

使用示例

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-empty
spec:
  containers:
  - name: container-empty
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume  # 与volumes中的name保持一致
  volumes:
  - emptyDir: {}
    name: cache-volume

特点

  • 自动创建,无需指定宿主机目录
  • 随 Pod 生命周期存在
  • 适用于临时数据存储

三、hostPath:节点级存储卷

hostPath 允许 Pod 挂载宿主机上的目录或文件,数据存储在宿主机上,当 Pod 被删除后数据不会丢失,但需要 Pod 重新调度到同一节点才能访问数据。

使用示例

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  nodeName: k8s-node2  # 指定节点,确保重新调度到同一节点
  containers:
  - image: nginx
    name: test-nginx
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data
      type: DirectoryOrCreate  # 目录不存在则自动创建

特点

  • 数据存储在宿主机,Pod 删除后数据保留
  • 存在单点故障,Pod 必须调度到同一节点
  • 适用于需要在节点本地存储数据的场景

四、NFS:网络文件系统

NFS(Network File System)是一种网络文件系统,通过网络共享存储目录,解决了 hostPath 的单点故障问题,支持多节点访问。

部署步骤

  • 搭建 NFS 服务端(以 k8s-master 为例)

    安装 NFS 服务

    yum install -y nfs-utils

    创建共享目录

    mkdir /data -pv

    配置共享权限

    echo "/data 192.168.166.0/24(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports

    生效配置

    exportfs -avr

    启动服务

    systemctl enable --now nfs

  • 所有 Worker 节点安装客户端

    yum install nfs-utils -y
    systemctl enable --now nfs

  • 创建使用 NFS 的 Pod

    apiVersion: v1
    kind: Pod
    metadata:
    name: test-nfs
    spec:
    containers:
    - name: test-nfs
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nfs-volumes
    mountPath: /usr/share/nginx/html
    volumes:
    - name: nfs-volumes
    nfs:
    path: /data # NFS共享目录
    server: 192.168.166.7 # NFS服务器地址

特点

  • 支持多节点访问,解决单点故障
  • 数据集中存储,Pod 调度不受节点限制
  • 依赖 NFS 服务可用性

五、PVC/PV:持久化存储声明与卷

PersistentVolume(PV)是集群中的存储资源,由管理员配置;PersistentVolumeClaim(PVC)是用户对存储资源的请求。PV 和 PVC 解耦了存储资源的供应和使用。

核心概念

  • PV:集群中的存储资源,生命周期独立于 Pod
  • PVC:用户对存储的请求,类似 Pod 对 CPU 和内存的请求
  • 绑定:PVC 与匹配的 PV 绑定,一对一关系
  • 回收策略 :
    • Retain:删除 PVC 后,PV 保留,数据不丢失(默认)
    • Delete:删除 PVC 时,PV 及其存储资产一并删除

使用步骤

  • 创建 PV

    pv.yaml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
    name: v2
    spec:
    capacity:
    storage: 2Gi
    accessModes: ["ReadWriteMany"] # 支持多节点读写
    nfs:
    path: /data/v2
    server: 192.168.166.7

  • 创建 PVC

    pvc.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: my-pvc
    spec:
    accessModes: ["ReadWriteMany"]
    resources:
    requests:
    storage: 2Gi

  • 在 Pod 中使用 PVC

    pod_pvc.yaml

    apiVersion: v1
    kind: Pod
    metadata:
    name: pod-pvc
    spec:
    containers:
    - name: nginx
    image: nginx
    volumeMounts:
    - name: nginx-html
    mountPath: /usr/share/nginx/html
    volumes:
    - name: nginx-html
    persistentVolumeClaim:
    claimName: my-pvc # 关联PVC

特点

  • 解耦存储管理和使用
  • 支持多种回收策略
  • 静态供应需要预先创建 PV

六、StorageClass:动态存储供应

StorageClass 用于动态创建 PV,解决了静态 PV 维护成本高的问题,管理员通过定义 StorageClass 作为 PV 的模板,Kubernetes 可根据 PVC 自动创建匹配的 PV。

核心组件

  • Provisioner:存储供应者,决定使用哪种存储插件创建 PV
  • StorageClass:定义 PV 属性和使用的 Provisioner
  • NFS Provisioner:用于 NFS 的自动供应程序

部署步骤

  • 创建服务账号和权限

    sa.yaml

    apiVersion: v1
    kind: Namespace
    metadata:
    name: newnfs

    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: nfs-client-provisioner
    namespace: newnfs

    省略ClusterRole、ClusterRoleBinding等权限配置

  • 部署 NFS Provisioner(配置略,需指定 NFS 服务器地址和共享目录)

  • 创建 StorageClass

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: nfs-storage
    provisioner: nfs-client-provisioner # 与Provisioner名称一致
    reclaimPolicy: Delete # 回收策略
    allowVolumeExpansion: true # 允许卷扩展

  • 创建 PVC 使用 StorageClass

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: dynamic-pvc
    spec:
    storageClassName: nfs-storage # 指定StorageClass
    accessModes: ["ReadWriteMany"]
    resources:
    requests:
    storage: 5Gi

特点

  • 动态创建 PV,减少运维成本
  • 支持卷扩展
  • 可定义多种存储类型满足不同需求

总结

Kubernetes 提供了多种持久化存储方案,适用于不同场景:

  • emptyDir:临时存储,随 Pod 生命周期
  • hostPath:节点本地存储,适用于单节点场景
  • NFS:网络共享存储,支持多节点访问
  • PVC/PV:解耦存储供应和使用,适合静态存储管理
  • StorageClass:动态供应 PV,适合大规模集群
相关推荐
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
分布式存储与RustFS5 天前
MinIO 官方 Docker 镜像被移除:依赖它的项目该怎么办
docker·云原生·devops·对象存储·minio·分布式存储
codeejun5 天前
每日一Go·MySQL-5、锁机制全解析
云原生·golang
赵文宇(温玉)5 天前
CoreDNS的hosts插件的缺行配置导致k8s集群异常
容器·kubernetes·rancher
guo_wen_qiang5 天前
上传本地镜像到harbor中
docker·容器·持续部署
张洛闻Eren5 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
忆~遂愿5 天前
本地片库怎么在外面打开?Plex + cpolar 搭一套可远程访问的私人影音库
docker·容器
Thneonl5 天前
你的 Pod 为什么 Pending:调度器两阶段
后端·kubernetes
不吃香菜kkk、5 天前
CI/CD(GitOps)学习与部署手册
运维·云原生·容器·kubernetes·云计算·jenkins·argocd
ChaITSimpleLove5 天前
云原生性能对决:JDK21虚拟线程+GraalVM vs .NET10/11 技术栈深度对比
微服务·云原生·serverless·graalvm native·native aot·runtime async·.net11/java21