一文搞懂k8s中临时卷与PV的用法
本篇文章主要介绍卷的用途、卷的类型,以及卷是如何工作的。
1. 卷的用途
容器中的文件在磁盘上是临时存放的,当容器崩溃或被停止时,容器的状态不会被保存,因此在容器生命期内创建或修改的所有文件都将丢失。 在崩溃之后,kubelet 会以干净的状态重启容器。
卷为Pod中的容器提供了数据持久和共享存储的方式。

- 在同一个 Pod 中的两个不同容器之间共享文件系统
- 在两个不同的 Pod 之间共享文件系统(即使这些 Pod 运行在不同的节点上)
- 数据共享可以发生在容器内不同本地进程之间,或在不同容器之间,或在多个 Pod 之间。
- 持久化存储数据,这样即使 Pod 重启或被替换,存储的数据仍然可用

- K8s 中,卷基于ConnfigMap 或 Secret 为Pod填充配置文件
- 基于容器所在 Pod 的详细信息,将配置信息传递给运行在容器中的应用
- 以只读权限访问另一个容器镜像中的数据
2. 卷的类型

临时卷:是一种生命周期与 Pod 紧密绑定的存储卷。当 Pod 被删除时,Kubernetes 会自动销毁并清理这个临时卷及其上的所有数据。
它与持久卷(Persistent Volume, PV)形成鲜明对比,持久卷的生命周期是独立的,Pod 被删除后,持久卷及其数据依然存在,可以被其他 Pod 重新挂载使用。

Kubernetes 中的临时卷主要包含以下几类:
emptyDir:最基础、最常用的临时卷类型。
configMap、secret、downwardAPI:这些特殊的卷类型,其数据由 Kubernetes API 本身提供(分别是 ConfigMap 资源、Secret 资源和 Pod 的元数据),它们也是临时的,因为卷本身(挂载点)随 Pod 的创建而创建,随 Pod 的删除而消失。但需要注意的是,它们的数据来源(如 ConfigMap)的生命周期可能是独立的。CSI 临时卷:这是一个更强大的功能,允许支持特定 CSI 驱动程序的第三方存储提供商也提供临时卷。这为临时存储带来了持久化存储才有的高级功能(如快照、扩容等)。
3. 卷的用法
3.1临时卷的用途及示例:
1. 容器间数据共享
这是 emptyDir 最经典的用途。一个 Pod 中可能运行多个协作的容器(Sidecar 模式),它们需要共享一些数据。
示例--Web 服务器与日志收集器:
一个容器(如 Nginx)将访问日志写入 emptyDir 卷中的某个文件,另一个容器(如 Filebeat 或 Fluentd 的 Sidecar)从同一个卷中读取日志文件并将其发送到中央日志系统(如 Elasticsearch)。
apiVersion: v1
kind: Pod
metadata:
name: shared-volume-pod
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: shared-data
mountPath: /var/log/nginx # Nginx将日志写入这里
- name: log-collector
image: fluent/fluentd:latest
volumeMounts:
- name: shared-data
mountPath: /fluentd/log # Fluentd从这里读取日志
volumes:
- name: shared-data
emptyDir: {} # 关键:定义一个emptyDir临时卷
2. 作为缓存或临时工作区
应用程序可能需要一个磁盘空间来存放临时计算数据、缓存文件或中间结果。使用临时卷非常合适,因为当 Pod 完成工作或被驱逐时,这些数据就不再需要,会自动清理。
示例:
大型软件编译:在一个 CI/CD 流水线的 Pod 中,编译容器可以将依赖库(如 node_modules 或
.m2仓库)缓存到emptyDir中,以加速后续的编译步骤(在同一 Pod 内)。数据批处理:一个数据处理任务可以将中间结果暂存到
emptyDir,任务完成后数据即可丢弃。
3. 检查点或恢复
有些应用程序在运行过程中需要定期将状态保存到磁盘,以便在崩溃时能够快速恢复。由于 Pod 可能被重新调度到另一个节点,这种状态通常不适合用 emptyDir 来持久化。但在某些单次运行或可容忍从头开始的场景下,可以使用它来暂存状态,以应对容器内进程的重启(而非整个 Pod 的重启)。
3.2 持久卷的用途及示例
Kubernetes 的持久卷类别非常丰富,以下是按照技术实现分类的持久卷类别,并以表格形式总结。

在Kubernetes中,持久卷(PersistentVolume, PV)和持久卷声明(PersistentVolumeClaim, PVC)是用于管理存储资源的重要资源。它们使得Pod可以持久化存储数据,这对于状态持久化应用(如数据库)非常关键。

1. 创建持久卷(PersistentVolume, PV)
首先,你需要创建一个或多个持久卷,这些卷代表了底层的存储资源,如NFS、GlusterFS、Ceph、AWS EBS等。
示例:创建一个NFS类型的PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /path/to/nfs/export
server: nfs-server.example.com
2. 创建持久卷声明(PersistentVolumeClaim, PVC)
然后,你可以创建一个或多个持久卷声明,这些声明代表了用户对存储资源的需求。PVC会绑定到一个PV上。
示例:创建一个PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-storage
resources:
requests:
storage: 1Gi
3. 在Pod中使用PVC
最后,你可以在Pod的配置中引用这个PVC,以使用持久存储。
示例:在Pod中使用PVC
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: my-volume
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: nfs-pvc
4. 验证和测试
部署Pod后,你可以检查Pod的状态,并验证是否正确挂载了PVC。使用kubectl命令:
kubectl get pod my-pod
kubectl exec -it my-pod -- df -hT | grep /var/www/html
3.3 HostPath 和Local
在Kubernetes中,Local和HostPath都是用于本地存储的持久卷类型,但它们在设计目标和使用场景上有重要区别。
HostPath适用场景:
开发和测试环境
需要访问节点系统文件的场景(如日志收集)
单节点集群或不需要数据持久性的场景
Local Volume适用场景:
生产环境本地存储
需要数据持久性和卷生命期管理
使用本地SSD等高性能存储的场景
HostPath将节点上的文件系统目录挂载到Pod中,主要用于开发测试或需要访问节点特定文件的场景。
Local Volume是Kubernetes 1.14后稳定的功能,专为本地存储设计,支持动态 provisioning,更适合生产环境。

HostPath示例:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
- name: hostpath-volume
mountPath: /host-data
volumes:
- name: hostpath-volume
hostPath:
path: /data/hostpath
type: DirectoryOrCreate # 目录不存在时自动创建
local 卷只能用作静态创建的持久卷。不支持动态配置。
与 hostPath 卷相比,local 卷能够以持久和可移植的方式使用,而无需手动将 Pod 调度到节点。系统通过查看 PersistentVolume 的节点亲和性配置,就能了解卷的节点约束。
然而,local 卷仍然取决于底层节点的可用性,并不适合所有应用程序。 如果节点变得不健康,那么 local 卷也将变得不可被 Pod 访问。使用它的 Pod 将不能运行。 使用 local 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。
下面是一个使用 local 卷和 nodeAffinity 的持久卷示例:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
使用 local 卷时,你需要设置 PersistentVolume 对象的 nodeAffinity 字段。 Kubernetes 调度器使用 PersistentVolume 的 nodeAffinity 信息来将使用 local 卷的 Pod 调度到正确的节点。
更多推荐


所有评论(0)