pvc
约 2307 字大约 8 分钟
2025-09-07
Volume挂载概述
在Kubernetes中,Volume(卷)是Pod中可以被多个容器访问的共享存储。与Docker的volume不同,Kubernetes的volume具有明确的生命周期,与Pod的生命周期相同。
Volume的主要特点:
- 生命周期与Pod绑定:当Pod被删除时,volume也会被清理
- 支持多种存储类型:本地存储、网络存储、云存储等
- 容器间共享:Pod内的多个容器可以共享同一个volume
PV (PersistentVolume) 和 PVC (PersistentVolumeClaim)
PV (PersistentVolume)
PV是集群级别的存储资源,由管理员预先配置。它代表集群中的一块存储空间,可以是:
- 本地存储
- NFS
- AWS EBS
- GCE Persistent Disk
- Azure Disk等
PVC (PersistentVolumeClaim)
PVC是用户对存储的请求,类似于Pod对Node资源的请求。用户通过PVC来申请存储资源,Kubernetes会根据PVC的要求找到合适的PV进行绑定。
PV和PVC的关系
用户创建PVC → Kubernetes匹配PV → 绑定 → Pod使用PVC实际使用例子
1. 创建PV示例
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.1.100
path: /data/nfs2. 创建PVC示例
# nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi3. Pod使用PVC示例
# pod-with-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-pvc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: nfs-pvc4. 本地存储PV示例
# local-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node1其他Volume类型的使用场景
1. ConfigMap Volume
用于将ConfigMap数据挂载到容器中:
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: nginx-config2. Secret Volume
用于挂载敏感数据:
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: myapp
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: my-secret3. EmptyDir Volume
临时存储,Pod删除时数据也会删除:
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: writer
image: busybox
command: ['sh', '-c', 'echo "Hello" > /data/hello.txt; sleep 3600']
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
image: busybox
command: ['sh', '-c', 'cat /data/hello.txt; sleep 3600']
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
emptyDir: {}4. HostPath Volume
直接挂载宿主机路径:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: host-storage
mountPath: /usr/share/nginx/html
volumes:
- name: host-storage
hostPath:
path: /data
type: DirectoryOrCreate关键概念总结
AccessModes(访问模式)
- ReadWriteOnce (RWO):可读可写,但只能被一个节点挂载
- ReadOnlyMany (ROX):只读,可被多个节点挂载
- ReadWriteMany (RWX):可读可写,可被多个节点挂载
ReclaimPolicy(回收策略)
- Retain:保留数据,需要手动清理
- Delete:自动删除PV和存储
- Recycle:已废弃,使用Delete替代
StorageClass
用于动态创建PV,支持按需分配存储资源:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
fsType: ext4最佳实践建议
- 生产环境推荐使用StorageClass进行动态存储分配
- 根据应用需求选择合适的访问模式
- 合理设置回收策略,避免数据丢失
- 使用ConfigMap和Secret管理配置和敏感信息
- 避免使用HostPath,除非有特殊需求
Pod的Volume
Volumes。
核心概念:为什么需要 Volume?
在理解 Volume 之前,必须先明白一个关键问题:容器中的文件是临时的。
- 当容器崩溃或重启时,容器内部的文件系统会被重置到镜像的初始状态。
- 在同一个 Pod 中运行的多个容器,默认拥有各自独立的文件系统,彼此隔离。
Volume(存储卷)就是为了解决这些问题而存在的,它提供了:
- 数据持久化:即使 Pod 被重新调度或重启,Volume 中的数据也能保留。
- Pod 内容器间共享数据:同一个 Pod 中的多个容器可以挂载同一个 Volume,从而共享文件。
Volume 的定义与生命周期
- 定义位置:Volume 在 Pod 级别定义,而不是在容器级别。它在
spec.volumes中声明。 - 挂载使用:容器通过
spec.containers.volumeMounts将已定义的 Volume 挂载到自身文件系统的特定路径下。 - 生命周期:Volume 的生命周期与 Pod 绑定。
- 只要 Pod 存在,Volume 就存在。
- 如果 Pod 被删除,对应的 Volume 通常也会被清理(具体取决于 Volume 类型,例如
hostPath和持久化卷的数据会保留)。
一个简单的 Pod Volume 示例
下面是一个定义并使用 Volume 的经典例子:一个 Pod 包含两个容器(一个写日志,一个读日志),它们通过 Volume 共享数据。
apiVersion: v1
kind: Pod
metadata:
name: shared-volume-pod
spec:
# 1. 在 Pod 级别定义 Volume
volumes:
- name: shared-log-volume # Volume 的名称
emptyDir: {} # Volume 的类型:初始为空的目录
containers:
- name: app-container
image: busybox
command: ['sh', '-c', 'while true; do echo "$(date): Hello from App!" >> /app-logs/log.txt; sleep 5; done']
# 2. 将 Volume 挂载到容器的特定路径
volumeMounts:
- name: shared-log-volume # 要挂载的 Volume 名称
mountPath: /app-logs # 在容器内的挂载点
- name: sidecar-container
image: busybox
command: ['sh', '-c', 'tail -f /sidecar-logs/log.txt']
volumeMounts:
- name: shared-log-volume # 挂载同一个 Volume
mountPath: /sidecar-logs # 可以挂载到不同的路径解释:
volumes: 定义了一个名为shared-log-volume的卷,类型是emptyDir。volumeMounts: 两个容器都通过name字段引用了这个卷,并分别将其挂载到各自的文件路径(/app-logs和/sidecar-logs)。- 效果:
app-container写入/app-logs/log.txt的文件,sidecar-container从/sidecar-logs/log.txt可以立即看到。数据在容器重启后也会保留,直到 Pod 被删除。
常见的 Volume 类型
Kubernetes 支持非常丰富的 Volume 类型,以适应不同的存储后端和用途。
1. emptyDir
- 描述:随 Pod 创建的一个空目录。Pod 被删除时,
emptyDir中的数据也会被永久删除。 - 用途:临时空间、磁盘缓存、或同一个 Pod 中容器间的文件共享。
- 存储介质:可以是节点磁盘,也可以是节点内存(通过设置
emptyDir: { medium: "Memory" })。
2. hostPath
- 描述:将节点主机上的一个文件或目录挂载到 Pod 中。
- 用途:访问宿主机系统信息(如
/var/lib/docker)、运行需要访问主机设备的守护进程(如监控代理)。 - 风险:Pod 与节点紧密耦合,不利于调度和迁移。可能带来安全风险。
- 示例:
volumes: - name: host-volume hostPath: path: /data # 节点上的目录 type: DirectoryOrCreate # 如果路径不存在则创建
3. 网络存储卷(Cloud & Network)
这些是用于数据持久化的核心类型,即使 Pod 被调度到另一个节点,数据依然可访问。
- NFS: 挂载 NFS 网络文件系统。
- CSI: 容器存储接口,是现在推荐的标准方式。它允许第三方存储提供商(如 AWS, GCP, Azure, Ceph, GlusterFS 等)将其存储系统集成到 Kubernetes 中。
awsElasticBlockStore(EBS)gcePersistentDisk(PD)azureDiskcephfs
- 配置示例(NFS):
volumes: - name: nfs-volume nfs: server: 10.0.0.41 path: /exports/data readOnly: false
4. 特殊用途卷
configMap/secret/downwardAPI- 这些不是传统的“存储卷”,而是用于将 Kubernetes 集群的元数据或配置信息以文件的形式注入到 Pod 中。
configMap: 将配置数据挂载为文件。volumes: - name: app-config configMap: name: my-app-configsecret: 类似 ConfigMap,但用于存储敏感信息(如密码、令牌),内容会以 Base64 编码。downwardAPI: 让 Pod 能够方便地获取自身或节点的元数据(如 Pod 名称、命名空间、标签等)。
最佳实践与高级模式:PersistentVolume (PV) & PersistentVolumeClaim (PVC)
对于生产环境,不建议直接在 Pod 定义里使用具体的网络存储卷(如 nfs, csi 等),而是推荐使用 PV 和 PVC 这种声明式模型。
- PersistentVolume (PV): 由集群管理员预先配置好的一块网络存储。它是集群中的资源,就像节点一样。
- PersistentVolumeClaim (PVC): 由用户发起的对存储的请求。它向集群申请特定大小和访问模式的 PV。
工作流程:
- 管理员创建 PV(例如,一个 100Gi 的 NFS 卷)。
- 用户在 Pod 的 YAML 中创建一个 PVC,请求 10Gi 的存储。
- Kubernetes 系统为这个 PVC 找到一个合适的 PV 并与之绑定。
- 用户在 Pod 的
volumes中引用这个 PVC,而不是具体的存储类型。
示例:
# 1. 定义 PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-app-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
# 2. 在 Pod 中引用 PVC
apiVersion: v1
kind: Pod
metadata:
name: app-with-pvc
spec:
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: my-app-pvc # 关键:这里指向 PVC 的名称
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: app-storage这种方式实现了存储的抽象和解耦,开发者无需关心底层存储的具体实现,只需要声明自己需要什么样的存储即可。
总结
| 特性 | 描述 |
|---|---|
| 目的 | 数据持久化、Pod 内容器间共享数据。 |
| 定义位置 | Pod 级别的 spec.volumes。 |
| 使用方式 | 容器级别的 spec.containers.volumeMounts。 |
| 生命周期 | 与 Pod 绑定(持久化卷的数据生命周期独立)。 |
| 常见类型 | emptyDir, hostPath, nfs, csi, configMap, secret。 |
| 最佳实践 | 生产环境使用 PV/PVC 模式来管理持久化存储。 |
- PV是由管理员或者StorageClass创建
更新日志
2025/11/2 08:25
查看所有更新日志
dfa6b-add cloneset于1561c-pvc add于
