找回密码
 立即注册
首页 业界区 业界 Kubernetes存储卷:保障有状态应用的数据持久化 ...

Kubernetes存储卷:保障有状态应用的数据持久化

计海龄 前天 19:40
1.jpeg

  在前面几个章节,介绍了k8s的pod以及网络相关的知识,在这一章,则开始对k8s的存储进行介绍。k8s卷(volumes)为container提供了文件系统访问以及数据共享的能力。
1. 引入

  首先先引入一个问题,为什么k8s要提供文件系统访问以及数据共享的能力?
  如果大家使用docker部署过数据库,就会发现,一般来说,我们都会将容器数据库中的data,log目录挂载到host的目录下,这样即使容器G了,至少我们的数据不会丢失。因此在k8s中,我们也需要某个存储方式,能够让数据脱离容器的生命周期而存在,然后也能够让数据在不同的pod、容器内进行共享存储。例如:

  • 数据库pod:将数据库的数据进行持久化保存,就需要挂载持久化存储。
  • 日志文件:例如一个pod中多个容器,进行共享日志文件。比如说一个pod中的应用容器产生日志,而sidecar容器收集日志,上传到统一的日志中心。
  • 挂载配置文件(configmap):一般来说,我们的应用在启动的过程中,可能需要读取一些配置文件。我们当然可以在打包镜像的时候,将配置文件放进去,但是这样的话,就失去了灵活(配置进行更改的时候,还需要重新打包镜像,上传,部署)。如果我们将配置写入到某个统一的地方,然后挂载到应用容器中去,那么应用便可以实时读取配置(因为修改配置之后,挂载的文件也会自动更新)。
  • 挂载敏感信息(Secret):比如说,我的应用需要使用数据库,我们可以将数据库账号密码设置为环境变量,但是环境变量存在泄露的风险(ps -ef打印环境变量),我们也可以将账号密码放在configmap里面,但是configmap谁都能看到,不符合最小化权限设计原则。因此,我们可以将相关敏感信息放在某中类型的存储卷(Secret)中,然后对其进行权限控制,甚至使用密钥进行加密。
  • 使用云存储:这个就是云厂商的存储卷直接挂载到pod中,方便使用。
  加下来将详细的对各个类型的卷进行介绍。
  1. @startmindmap
  2. * Kubernetes 存储 (Storage)
  3. ** 临时卷 (Ephemeral Volumes) <<Pod 内置>>
  4. *** emptyDir
  5. *** configMap
  6. *** secret
  7. *** 通用临时卷
  8. ** 持久卷 (Persistent Volumes) <<集群级资源>>
  9. *** 持久卷声明 (PVC) <<用户接口>>
  10. **** 通过 StorageClass 动态供应
  11. **** 绑定静态 PV
  12. *** 持久卷 (PV) <<管理员/系统创建>>
  13. **** 本地存储 (Local Storage)
  14. ***** hostPath <<仅单节点>>
  15. ***** local (Local Persistent Volume) <<多节点需调度约束>>
  16. **** 网络/云存储 (Network / Cloud Storage)
  17. ***** 文件存储 (File Storage) <<支持 RWX>>
  18. ****** nfs
  19. ****** cephfs
  20. ****** azureFile
  21. ****** glusterfs
  22. ****** AWS EFS / GCP Filestore
  23. ***** 块存储 (Block Storage) <<通常 RWO>>
  24. ****** awsElasticBlockStore (EBS)
  25. ****** gcePersistentDisk (GCE PD)
  26. ****** azureDisk
  27. ****** cinder (OpenStack)
  28. ****** rbd (Ceph RBD)
  29. ****** iscsi
  30. ****** fc (Fibre Channel)
  31. ***** 分布式/企业存储
  32. ****** portworxVolume
  33. ****** storageos
  34. ****** scaleIO
  35. ****** quobyte
  36. ****** vsphereVolume
  37. ****** photonPersistentDisk
  38. @endmindmap
复制代码
2. 临时卷

  K8s中的临时卷(Ephemeral Volumes) 是一种生命周期与 Pod 绑定的存储卷,它在 Pod 创建时动态创建,在 Pod 删除时自动清理。临时卷主要用于提供临时、高性能或特定用途的本地存储,不适用于需要持久化数据的场景。常用的可以分为如下几种:

  • emptyDir:Pod 启动时为空,存储介质可以是磁盘或内存(Node中的磁盘或内存),pod中所有容器共享该卷。在生产中,我们常用emptyDir来收集日志。例如,在一个pod中多个容器,应用容器生成日志在临时卷中,sidecar容器(日志收集容器)将临时卷中的日志上传到ELK。又或者说,CI/CD构建过程中,源码pull在emptyDir中,编译后的产物通过sidecar上传到制品库。
    1. @startuml
    2. ' 启用中文支持(确保环境支持 UTF-8)
    3. skinparam defaultTextAlignment center
    4. skinparam wrapWidth 200
    5. skinparam backgroundColor #FFFFFF
    6. ' 自定义颜色
    7. skinparam component {
    8.   BackgroundColor #E6F3FF
    9.   BorderColor #1E88E5
    10.   FontColor #0D47A1
    11. }
    12. skinparam package {
    13.   BackgroundColor #F0F8E0
    14.   BorderColor #7CB342
    15.   FontColor #33691E
    16. }
    17. skinparam folder {
    18.   BackgroundColor #FFF3E0
    19.   BorderColor #FB8C00
    20.   FontColor #E65100
    21. }
    22. package "Kubernetes 节点" <<Node>> {
    23.   [Pod\n(my-app)] as pod #BBDEFB
    24.   package "容器 1\n(主应用)" <<Container>> {
    25.     [挂载点: /cache] as m1
    26.   }
    27.   package "容器 2\n(日志收集器)" <<Container>> {
    28.     [挂载点: /shared] as m2
    29.   }
    30.   [临时卷 emptyDir\n(名称: temp-storage)] as emptydir #FFECB3
    31.   pod --> m1
    32.   pod --> m2
    33.   m1 --> emptydir : 挂载\nmountPath: /cache
    34.   m2 --> emptydir : 挂载\nmountPath: /shared
    35. }
    36. node "节点本地存储" <<Storage>> {
    37.   folder "/var/lib/kubelet/pods/...\n/temp-storage" as nodeDir
    38. }
    39. emptydir --> nodeDir : 存储位置\n• 默认:节点磁盘\n• 可选:内存 (tmpfs)
    40. @enduml
    复制代码
  • configMap、secret等一类将资源文件挂载为卷:正如我们前面所提到,我们需要将某些配置文件或者私密文件作为pod容器启动或者运行参数配置,而这些配置对于每个容器都是统一的,但是在生产的过程中有可能发生变更(例如nginx的config)。这时候我们就可以定义configMap,或者secret​[注](本质上,这两者都是资源文件,当我们定义它们的时候,相关的配置文件会保存到k8s的etcd中),然后在pod运行的时候,将configMap或者secret文件挂载到容器中(一般来说,都是ready only的)。具体的使用,可以参考5.2 secret 和 ConfigMap 卷 · Kubernetes - 痴者工良​[注]。举个例子:
    1. # nginx-configmap.yaml 定义一个configMap资源
    2. apiVersion: v1
    3. kind: ConfigMap
    4. metadata:
    5.   name: nginx-config
    6. data:
    7.   nginx.conf: |
    8.     events {}
    9.     http {
    10.       server {
    11.         listen 80;
    12.         location / {
    13.           return 200 "Hello from ConfigMap!\n";
    14.           add_header Content-Type text/plain;
    15.         }
    16.       }
    17.     }
    18. #----------另外一个pod定义文件---------------
    19. # nginx-pod.yaml
    20. apiVersion: v1
    21. kind: Pod
    22. metadata:
    23.   name: nginx-with-config
    24. spec:
    25.   containers:
    26.   - name: nginx
    27.     image: nginx:alpine
    28.     volumeMounts:
    29.         # 表示这个挂载点引用的是下面 volumes 中定义的名为 config-volume 的卷
    30.     - name: config-volume
    31.           # 表示要把卷挂载到容器内的 这个具体路径
    32.       mountPath: /etc/nginx/nginx.conf
    33.           # 只挂载卷中的 nginx.conf 这一个文件,而不是整个卷目录。
    34.       subPath: nginx.conf
    35.   volumes:
    36.         # 定义一个名为 config-volume 的卷,供上面的 volumeMounts 引用。
    37.   - name: config-volume
    38.     configMap:
    39.           # 数据来源是一个叫 nginx-config 的 ConfigMap。
    40.       name: nginx-config
    复制代码
  • 通用临时卷:Generic Ephemeral Volume(通用临时卷)的作用基本上和emptyDir很类似,都是k8s为pod提供的临时存储方案,数据的生命周期与pod进行绑定。但是通用临时卷相比于emptyDir,容量可控、性能更强。通用临时卷依靠CSI驱动(Container Storage Interface,容器存储接口, 将外部存储系统翻译为k8s存储系统的插件),可以将外部存储(云盘、本地SSD、网络存储)挂载为pod的临时卷,并支持指定容量大小,以及高级的存储特性(例如加密,快照)。​emptyDir​​ 是“轻量级临时盘”,通用临时卷是“带容量和性能保障的临时云盘”。简单场景用 emptyDir,高性能/大容量/需管控的场景用通用临时卷。 如果用一个形象的例子来理解,就是emptyDir是个人电脑上的临时文件夹,而通用临时卷就是NAS上面的临时文件夹(容量大,有快照,可配置容量限制……)。
3. 持久卷

3.1 PV & PVC

  在生产中,我们当然不仅仅是使用临时卷,还需要使用持久卷(Persistent Volume,PV),以实现数据的持久化。这样及时pod被删除、重建也能够实现数据的保留以支持有状态应用(StatefulSets,例如数据库,redis,kafka、对象存储),或者实现跨节点共享数据。

  • PV 是集群中由管理员预先配置或由存储类(StorageClass,本质上是一个 “存储模板”,告诉k8s如何动态创建持久卷)动态创建的一块存储资源(如 NFS、iSCSI、云盘等)。它是集群级别的资源,生命周期独立于使用它的 Pod。
  • Persistent Volume Claim(PVC) ,PVC 是用户对存储资源的“申请”,类似于 Pod 对 CPU/内存的请求,定义了用户希望使用的存储大小、访问模式(如只读、读写、单节点或多节点访问)。k8s会根据 PVC 的要求,自动绑定一个合适的PV。
  1. # pv配置文件 pv.yaml
  2. apiVersion: v1
  3. # 资源类型:PersistentVolume(持久卷)
  4. kind: PersistentVolume
  5. metadata:
  6.   # PV 的名称,在整个集群中必须唯一
  7.   name: my-pv
  8. spec:
  9.   # 定义该 PV 的存储容量
  10.   capacity:
  11.     # 请求的存储大小,单位可以是 Gi(Gibibyte)、Mi 等
  12.     storage: 5Gi
  13.   # 访问模式:定义该卷如何被挂载
  14.   # - ReadWriteOnce (RWO):只能被单个节点以读写方式挂载
  15.   # - ReadOnlyMany (ROX):可被多个节点以只读方式挂载
  16.   # - ReadWriteMany (RWX):可被多个节点以读写方式挂载
  17.   accessModes:
  18.     - ReadWriteOnce
  19.   # 回收策略:当 PVC 被删除后,PV 如何处理
  20.   # - Retain(保留):手动回收,数据不会被删除(适合重要数据)
  21.   # - Delete(删除):自动删除底层存储(如云盘),仅适用于动态供应
  22.   # - Recycle(已废弃):旧版本的自动清理方式,不推荐使用
  23.   persistentVolumeReclaimPolicy: Retain
  24.   # hostPath 是一种 将宿主机(Node)上的文件或目录挂载到 Pod 中 的方式。
  25.   hostPath:
  26.     # 宿主机上的实际路径,PV 的数据将存储在此目录
  27.     path: /mnt/data
  28. # -------pvc配置文件------ pvc.yaml
  29. apiVersion: v1
  30. # 资源类型:PersistentVolumeClaim(持久卷声明)
  31. kind: PersistentVolumeClaim
  32. metadata:
  33.   # PVC 的名称,在命名空间内唯一 Pod 将通过此名称引用该 PVC
  34.   name: my-pvc
  35.   # namespace: my-namespace
  36. # PVC 的规格
  37. spec:
  38.   # 期望的访问模式,必须与 PV 的 accessModes 兼容
  39.   accessModes:
  40.     - ReadWriteOnce
  41.   resources:
  42.     requests:
  43.       # k8s会寻找 capacity.storage >= 3Gi 且未被绑定的 PV
  44.       storage: 3Gi
  45. # ----------pod.yaml 文件
  46. apiVersion: v1
  47. kind: Pod
  48. metadata:
  49.   # Pod 的名称
  50.   name: nginx-pod
  51. # Pod 的规格
  52. spec:
  53.   containers:
  54.     - name: nginx                    # 容器名称
  55.       image: nginx:alpine            # 使用的镜像
  56.       volumeMounts:                  # 挂载卷到容器内
  57.         - name: web-content          # 与下方 volumes.name 对应
  58.           mountPath: "/usr/share/nginx/html"  # 容器内的挂载路径
  59.   # 定义 Pod 使用的卷(volumes)
  60.   volumes:
  61.     - name: web-content             # 卷名称,需与 volumeMounts.name 一致
  62.       persistentVolumeClaim:        # 表示该卷使用 PVC 提供的存储
  63.         claimName: my-pvc           # 引用前面创建的 PVC 名称 必须在同一命名空间下
复制代码
  上面的代码,是我们手动创建了一个pv,pvc,然后pod去使用pvc。在k8s中,创建pv有两种方式,一种是上面的这种,用户手动创建一个pv,指定pv相关的配置,然后让pvc消费,这种称之为静态制备。还有一种,是pvc进行制备,比如说pvc指定了一个不存在pv,则就根据pvc里面StorageClass的配置,制作出一块pv出来,称之为动态制备
方式是否涉及StorageClass静态制备不涉及管理员手动提前创建好 PV(比如用hostPath​、NFS 等),PVC 去匹配它。PV 里没有 ​storageClassName​字段动态制备涉及PVC 指定 StorageClass → 系统自动创建 PV →这个 PV 会自动带上  ​.spec.storageClassName​字段,值等于 PVC 请求的 StorageClass 名称。3.2 本地存储

  本地存储分为hostPath和local PV:

  • hostPath:hostPath 卷能将Node工作节点文件系统上的文件或目录挂载到你的 Pod 中。也就是说,如果pod部署在A节点上,就会使用A节点的某个目录,如果pod被删除重新部署到B节点上,那么就会使用B节点的某个目录,之前的数据就丢失了(因为数据在A节点上)。因此多副本 Pod 无法共享数据(每个节点数据独立),只适合单节点应用测试,不适宜生产环境。

    • 没有 PVC,没有 PV。
    • Pod 被调度到哪个节点,就用哪个节点的 /mnt/data。
    1. # pod.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. spec:
    5.   containers:
    6.     - name: app
    7.       volumeMounts:
    8.         - name: data
    9.           mountPath: /data
    10.   volumes:
    11.     - name: data
    12.       hostPath:
    13.         path: /mnt/data   # ← 直接指定节点路径!
    复制代码
  • local PV:在hostPath中,我们无法控制pod部署在哪个节点(即使我们通过nodeSelector​来进行控制,如果未来pod需要重新部署在其他节点,那么我们所有的pod配置都需要修改,也就是说pod和node进行了一个强耦合。)而localPV就是为了解决这个问题,localPV只支持静态制备。管理员预先在特定节点上准备磁盘或目录,然后创建local PV,显式的声明该存储位于哪个节点,然后pod使用pvc去挂载目录。在这种情况下,pod并没有与节点node形成一个强依赖,pod只是依赖于pvc。在下面的依赖配置中,pv-local指定为node-1节点,也就是说pv部署在node-1中。而pvc通过storageClassName: local-storage​,可以将pvc-local​与pv-local​进行绑定。而pod通过使用pvc-local就会将pod调度到node-1中。
    默认情况下,k8s在 PVC 创建后立即尝试绑定一个 PV(称为 Immediate Binding)。而 volumeBindingMode: WaitForFirstConsumer 表示:“不要急着绑定 PV!等第一个使用这个 PVC 的 Pod 被调度时,再根据 Pod 的调度结果来绑定合适的 PV。”
    这是因为如果我们有两个pv,pv-1绑定在node1中,pv-2绑定在node2中。如果创建pvc的时候,立即绑定pv(比如说随机选到了pv-1,绑定到了node1),但是创建pod的时候,node1对应的cpu或者内存资源又不足,调度器想把pod调度到node2中,那么肯定会调度失败,因为Pod 要去 node-2​,但存储在 node-1,因此会调度失败。因此我们需要进行延迟绑定。
    1. # storageclass-local.yaml
    2. apiVersion: storage.k8s.io/v1
    3. kind: StorageClass
    4. meta
    5.   name: local-storage
    6. provisioner: kubernetes.io/no-provisioner
    7. volumeBindingMode: WaitForFirstConsumer
    8. # pv-local.yaml
    9. apiVersion: v1
    10. # 资源类型:PersistentVolume(持久卷)
    11. kind: PersistentVolume
    12. metadata:
    13.   name: pv-local
    14. spec:
    15.   capacity:
    16.     # 请求的存储大小,这只是声明值,Kubernetes 不会验证底层实际大小
    17.     storage: 100Gi
    18.   # 卷的模式:指定存储是作为文件系统还是原始块设备使用
    19.   # - Filesystem(默认):挂载为目录,Pod 通过文件读写(绝大多数场景)
    20.   # - Block:作为原始块设备暴露给容器(需容器内格式化,高级用法)
    21.   volumeMode: Filesystem
    22.   # 访问模式:定义该卷如何被节点挂载
    23.   accessModes:
    24.     - ReadWriteOnce
    25.   # 回收策略:当绑定的 PVC 被删除后,PV 如何处理
    26.   persistentVolumeReclaimPolicy: Delete
    27.   storageClassName: local-storage
    28.   local:
    29.     # 节点上实际的目录或挂载点路径
    30.     path: /mnt/disks/ssd1
    31.   # 节点亲和性:强制指定该 PV 只能被调度到特定节点
    32.   nodeAffinity:
    33.     required:
    34.       nodeSelectorTerms:
    35.         - matchExpressions:
    36.             # 匹配节点的标签
    37.             - key: kubernetes.io/hostname
    38.               # In 表示节点 hostname 必须在 values 列表中
    39.               operator: In
    40.               # 允许使用该 PV 的节点主机名列表
    41.               # 通常只写一个节点(因为本地存储不共享)
    42.               values: ["node-1"]   # ← 明确绑定到 node-1
    43. ---
    44. # pvc.yaml
    45. apiVersion: v1
    46. kind: PersistentVolumeClaim
    47. metadata:
    48.   name: pvc-local
    49. spec:
    50.   storageClassName: local-storage
    51.   accessModes: [ReadWriteOnce]
    52.   resources:
    53.     requests:
    54.       storage: 100Gi
    55. ---
    56. # pod.yaml
    57. spec:
    58.   volumes:
    59.     - name: data
    60.       persistentVolumeClaim:
    61.         claimName: pvc-local   # ← 通过 PVC 间接使用
    复制代码
3.3 网络存储

  前面我们介绍的local pv,hostPath,都存在一个问题,那就是pv是跟node节点进行了一个强绑定,多节点多pod没法使用同一个pv。因此“网络存储”出来了,网络存储的数据不绑定在某一台物理节点上,因此更适合多节点集群中的持久化需求,还能够实现快照,副本等等高级存储特性,听起来是不是跟通用临时卷很像。在 Kubernetes(k8s)中,持久卷(PersistentVolume, PV)的“网络存储” 是指通过网络协议访问的、可跨节点共享或挂载的存储系统。

  • 文件存储(File Storage) ​:多个 Pod(跨节点)可同时读写同一份数据,适合共享配置、上传目录等场景。
    存储类型说明适应场景NFS经典网络文件系统,开源、轻量、广泛支持中小规模集群,自建存储CephFSCeph 提供的 POSIX 兼容文件系统大规模分布式存储,高可用GlusterFS开源分布式文件系统(Red Hat 支持)已逐渐被 Ceph 取代AWS EFSAmazon Elastic File SystemAWS 上的托管 RWX 文件存储Azure Files微软 Azure 的 SMB/NFS 文件服务Azure 云环境GCP FilestoreGoogle Cloud 的托管 NFS 服务GCP 云环境例如,定义一个NFS PV:
    1. apiVersion: v1
    2. kind: PersistentVolume
    3. spec:
    4.   capacity:
    5.     storage: 100Gi
    6.   accessModes: [ReadWriteMany]
    7.   nfs:
    8.     server: nfs.example.com
    9.     path: "/shared/data"
    复制代码
  • 块存储(Block Storage): 将远程块设备(如云硬盘)挂载到单个节点不能跨节点共享,但性能高。需要 Pod 自己格式化和管理文件系统
    1. # ebs-sc.yaml
    2. apiVersion: storage.k8s.io/v1
    3. kind: StorageClass
    4. metadata:
    5.   name: ebs-sc
    6. provisioner: ebs.csi.aws.com
    7. volumeBindingMode: WaitForFirstConsumer
    复制代码
4. 4. 总结

  卷(Volume)是 Kubernetes 中用于解决容器临时性文件系统问题的机制,它允许:

  • 容器重启后数据不丢失(持久化)
  • 同一 Pod 内多个容器共享数据
  • 应用与存储解耦,实现可移植
  1. @startuml
  2. ' 设置样式
  3. skinparam defaultTextAlignment center
  4. skinparam wrapWidth 200
  5. skinparam shadowing false
  6. skinparam component {
  7.   backgroundColor<<Pod>> LightBlue
  8.   borderColor<<Pod>> #336699
  9.   backgroundColor<<Ephemeral>> LightGreen
  10.   borderColor<<Ephemeral>> #2E8B57
  11.   backgroundColor<<PVC>> LightYellow
  12.   borderColor<<PVC>> #DAA520
  13.   backgroundColor<<Storage>> LightPink
  14.   borderColor<<Storage>> #FF6347
  15.   backgroundColor<<CSI>> LightGray
  16.   borderColor<<CSI>> #696969
  17.   backgroundColor<<Backend>> Wheat
  18.   borderColor<<Backend>> #8B4513
  19. }
  20. package "Kubernetes 集群" {
  21.   [Pod\n(应用容器)] as pod <<Pod>>
  22.   
  23.   package "卷定义(Pod 内)" {
  24.     [emptyDir\n(临时卷)] as emptyDir <<Ephemeral>>
  25.     [configMap\n(配置注入)] as configMap <<Ephemeral>>
  26.     [secret\n(密钥注入)] as secret <<Ephemeral>>
  27.     [persistentVolumeClaim\n(持久卷声明引用)] as pvcRef <<PVC>>
  28.   }
  29.   [持久卷声明(PVC)\n• 存储大小:10Gi\n• 访问模式:RWO\n• 存储类:fast-ssd] as pvc <<PVC>>
  30.   [存储类(StorageClass)\n• 名称:fast-ssd\n• 供应器:ebs.csi.aws.com\n• 参数:类型、加密等] as sc <<Storage>>
  31.   [持久卷(PV)\n• 容量:10Gi\n• 后端:AWS EBS / NFS / 本地磁盘\n• 节点亲和性] as pv <<Storage>>
  32.   [CSI 存储驱动\n• Controller 服务\n• Node 服务\n• Sidecar 容器:\n  - external-provisioner\n  - node-driver-registrar] as csi <<CSI>>
  33. }
  34. [底层存储系统\n(AWS EBS / NFS / Ceph / 本地 SSD)] as storage <<Backend>>
  35. ' 连接关系
  36. pod --> pvcRef : 挂载卷
  37. pod --> emptyDir : 挂载卷
  38. pod --> configMap : 挂载卷
  39. pod --> secret : 挂载卷
  40. pvcRef --> pvc : 引用
  41. pvc --> sc : 使用存储类
  42. sc --> csi : 触发动态供应
  43. csi --> pv : 创建 PV 和底层存储
  44. pvc --> pv : 绑定关系
  45. pv --> storage : 由...提供支持
  46. ' 布局优化(隐藏连线调整位置)
  47. pod -[hidden]d-> emptyDir
  48. emptyDir -[hidden]r-> configMap
  49. configMap -[hidden]r-> secret
  50. secret -[hidden]r-> pvcRef
  51. pvcRef -[hidden]d-> pvc
  52. pvc -[hidden]r-> sc
  53. sc -[hidden]r-> csi
  54. csi -[hidden]d-> pv
  55. pv -[hidden]d-> storage
  56. @enduml
复制代码
  StorageClass、PV、PVC关系如下:
PVC →(引用)→ StorageClass →(触发创建)→ PV
资源角色创建者生命周期StorageClass存储模板集群管理员集群级,长期存在PV实际存储资源管理员(静态)或系统(动态)集群级,独立于 PodPVC存储申请单应用开发者命名空间级,绑定 PV 后长期存在  前面我们在很多地方都定义了accessModes,以下是对Access Modes做的一个总结表格:
模式含义支持的存储关键说明​​ReadWriteOnce​卷可以被单个节点以读写模式挂载绝大多数存储(包括本地存储、块存储如 AWS EBS、GCP PD)​这是最常用的模式。一个节点上可以运行多个 Pod 并同时访问该卷。​​ReadOnlyMany​卷可以被多个节点以只读模式挂载NFS、CephFS 等​文件存储/共享存储常用于需要跨多个 Pod 分发只读配置、数据或代码的场景。​​ReadWriteMany​卷可以被多个节点以读写模式挂载主要限于文件存储(如 NFS, CephFS, Azure Files)需要多个 Pod 同时写入同一存储的场景(如内容管理系统)。​​ReadWriteOncePod​卷可以被单个 Pod 以读写模式挂载仅支持 CSI 卷,且需要 Kubernetes v1.22+​确保卷的独占性。这是有状态工作负载的理想选择,可防止其他 Pod 误挂载。5. 脚注

[注]
卷 | Kubernetes
[注]
5.2 secret 和 ConfigMap 卷 · Kubernetes - 痴者工良

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

昨天 20:32

举报

感谢发布原创作品,程序园因你更精彩
您需要登录后才可以回帖 登录 | 立即注册