编辑
2025-08-21
K8S(重新复习)
00

目录

一、概念
二、静态供给
三、动态供给

一、概念

PV(Persistent Volume)和PVC(Persistent Volume Claim)是Kubernetes中用于管理存储资源的两个核心概念,它们通过解耦存储资源与应用需求实现灵活管理。以下是两者的核心区别及协作机制:

PV‌ 是集群管理员预先配置的‌物理存储资源‌,如NFS、云存储或本地磁盘等,其生命周期独立于Pod存在‌。

‌PVC‌ 是用户为应用程序提交的‌存储需求申请‌,通过声明容量、访问模式等参数匹配可用PV‌

image.png

  • 管理员创建PV或定义存储模板(如StorageClass)‌

  • 用户提交PVC申请,Kubernetes自动匹配符合条件的PV‌

  • 若动态供给已启用,未匹配的PVC可触发自动创建新PV‌

二、静态供给

在Kubernetes中,‌静态供给(Static Provisioning)‌是指管理员预先创建并配置好PV(PersistentVolume),然后由用户通过PVC(PersistentVolumeClaim)申请匹配的存储资源。

yml
# ========== PersistentVolume (PV) 定义 ========== apiVersion: v1 kind: PersistentVolume metadata: name: static-pv-nfs spec: capacity: storage: 1Gi # PV的总容量 accessModes: - ReadWriteMany # 支持多节点同时读写 persistentVolumeReclaimPolicy: Retain # Pod删除后保留PV和数据 nfs: server: 192.168.201.104 # NFS服务器地址 path: "/data/nfs_share" # NFS服务器共享路径 # 可选参数:readOnly: false # 默认可读写 --- # ========== PersistentVolumeClaim (PVC) 定义 ========== apiVersion: v1 kind: PersistentVolumeClaim metadata: name: static-pvc-app # PVC名称,Pod中会引用此名称 spec: accessModes: - ReadWriteMany # 必须与PV的accessModes匹配 resources: requests: storage: 1Gi # 申请1GB存储空间,申请的容量必须和PV一样 storageClassName: "" # 显式设置为空字符串以确保使用静态供给 --- # ========== Pod 定义 ========== apiVersion: v1 kind: Pod metadata: name: nginx-with-pvc # Pod名称 spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: nfs-storage # 必须与volumes.name匹配 mountPath: "/usr/share/nginx/html" # 容器内挂载路径 # 可选参数:readOnly: false # 默认可读写 volumes: - name: nfs-storage # 卷名称 persistentVolumeClaim: claimName: static-pvc-app # 绑定前面定义的PVC # 可选参数:readOnly: false # 默认可读写

三、动态供给

Kubernetes中PV(PersistentVolume)和PVC(PersistentVolumeClaim)的动态供给是一种自动化存储资源分配机制。

动态供给‌:当用户创建PVC时,系统根据预定义的StorageClass自动创建并绑定匹配的PV,无需管理员手动预置PV。

yml
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: chronolaw/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: 192.168.201.104 #nfs服务器ip地址 - name: NFS_PATH value: /root/nfs/data #nfs服务器共享数据目录 volumes: - name: nfs-client-root nfs: server: 192.168.201.104 #nfs服务器ip地址 path: /root/nfs/data #nfs服务器共享数据目录
yml
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system roleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: kube-system roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
yml
# ==================== 存储类配置 ==================== apiVersion: storage.k8s.io/v1 # 存储类API版本标识 kind: StorageClass # 声明资源类型为存储类 metadata: # 资源元数据开始 name: mysql-nfs-sc # 存储类命名(MySQL专用NFS存储类) namespace: ems # 归属ems命名空间 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # 指定NFS子目录动态供应器 parameters: # 供应器参数配置开始 onDelete: "remain" # 数据保留策略:删除时不清理
yml
# ==================== 命名空间配置 ==================== apiVersion: v1 # Kubernetes核心API版本标识 kind: Namespace # 声明资源类型为命名空间 metadata: # 资源元数据开始 name: ems # 定义命名空间名称为ems(Enterprise Management System) --- # ==================== 有状态应用配置 ==================== apiVersion: apps/v1 # 应用API版本标识 kind: StatefulSet # 声明资源类型为有状态副本集 metadata: # 资源元数据开始 name: mysql # StatefulSet名称 namespace: ems # 归属ems命名空间 labels: # 标签集合开始 app: mysql # 应用标识标签 spec: # 规格定义开始 serviceName: mysql-headless # 关联的无头服务名(用于DNS解析) replicas: 1 # 副本数配置(MySQL单实例部署) template: # Pod模板定义开始 metadata: # Pod元数据开始 labels: # Pod标签集合开始 app: mysql # 应用标识标签(需与selector匹配) spec: # Pod规格定义开始 containers: # 容器定义列表开始 - name: mysql # 容器名称标识 image: mysql/mysql-server:8.0 # 官方MySQL 8.0镜像 ports: # 端口映射列表开始 - containerPort: 3306 # MySQL服务默认端口 env: # 环境变量列表开始 - name: MYSQL_ROOT_PASSWORD # root密码变量名 value: "root" # 密码明文值(测试环境使用) volumeMounts: # 存储卷挂载列表开始 - name: data # 引用下方PVC模板名称 mountPath: /var/lib/mysql # MySQL数据存储路径 volumeClaimTemplates: # PVC模板列表开始 - metadata: # PVC元数据开始 name: data # PVC资源名称 spec: # PVC规格定义开始 accessModes: [ "ReadWriteMany" ] # 存储访问模式(多节点读写) storageClassName: "mysql-nfs-sc" # 绑定前文定义的存储类 resources: # 资源请求定义开始 requests: # 资源请求参数开始 storage: 2Gi # 存储空间大小请求值 selector: # Pod选择器定义开始 matchLabels: # 标签匹配规则开始 app: mysql # 需匹配的Pod标签键值

本文作者:松轩(^U^)

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

Document