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,适合大规模集群
相关推荐
玄德公笔记2 小时前
GPU节点接入k8s集群的处理
docker·kubernetes·gpu·containerd·nvidia·runtime·fabricmanager
奔跑中的小象2 小时前
统信UOS V2500 环境下K8S 环境部署
云原生·容器·kubernetes·uos
运维李哥不背锅3 小时前
Kubernetes节点维护实战及注意事项
云原生·容器·kubernetes
阿里云云原生3 小时前
一行代码实现智能异常检测:UModel PaaS API 架构设计与最佳实践
云原生
没有bug.的程序员3 小时前
JVM 与 Docker:资源限制的真相
java·jvm·后端·spring·docker·容器
2301_801387293 小时前
devOps项目问题总结
云原生·容器·kubernetes
峰顶听歌的鲸鱼4 小时前
15.docker:容器
运维·笔记·docker·容器·学习方法
农夫山泉2号4 小时前
【docker】——不启用docker的启动命令,使用自己的
docker·容器·eureka
2301_801387294 小时前
网络、API 连接和 pod 启动的问题
运维·网络·kubernetes