Kubernetes 卷是一个包含数据的目录,可由 Kubernetes Pod 中的容器访问。目录的位置、支持该目录的存储介质及其内容取决于使用的卷的特定类型。
在 Pod 中的容器内运行的进程会看到由以下组件组成的文件系统视图:
卷在 Pod 模板的 .spec.containers[*].volumeMounts 字段中定义。对于每个 Pod 和 Pod 中的每个容器镜像,需要指定要挂载的卷以及路径(每个容器的路径可能不同)。
Kubernetes 中有几种类型的卷。最重要的是临时卷,它们本地存储在 Kubernetes 节点上,并在 pod 重启时删除,以及Kubernetes 持久卷 (PV),即使在 pod 关闭后仍保留数据。
在本文中:
Kubernetes 支持各种卷,允许每个 pod 同时使用多种卷类型。临时卷与 pod 的生命周期绑定,而持久卷可以在 pod 生命周期之外持续存在。这意味着一旦 pod 不再存在,Kubernetes 就会销毁临时卷,同时保留持久卷的数据。
Kubernetes 提供了一个 PersistentVolume 子系统,其中包含抽象存储配置和消费的 API。它使用两个 API 资源——PersistentVolume (PV) 和 PersistentVolumeClaim (PVC)。
PersistentVolume (PV)
PV 是位于集群中的存储资源。管理员可以手动配置 PV,Kubernetes 可以使用存储类动态配置 PV。与卷一样,PV 也是插件,但其生命周期与使用 PV 的任何 pod 无关。
PV 用作捕获存储实施详细信息的 API 对象,包括 iSCSI、NFS 和云提供商存储系统。它的工作原理类似于节点,但提供存储资源而不是计算。
PersistentVolumeClaim (PVC)
PVC 是用户提出的存储请求。它的工作原理类似于 pod,但消耗的是 PV 资源而不是节点资源。PVC 可以请求特定的存储资源,指定大小访问模式,例如 ReadWriteOnce、ReadWriteMany 和 ReadOnlyMany。
PVC 使用户能够使用抽象存储资源,但用户通常需要针对不同问题具有不同属性的 PV。这就是为什么集群管理员通常需要提供不同的 PV,而不仅仅是大小和访问模式。他们可以做到这一点,而无需通过 StorageClass 资源让用户了解实施细节。
相关内容:阅读我们的 Kubernetes PVC 指南
临时卷不会在重新启动后持续存储数据。这些卷与 pod 的生命周期绑定,这意味着它们与 pod 一起创建和删除。它可以停止和重新启动 pod,而不会限制它们对持久卷可用性的依赖。
临时卷易于部署和管理。您可以在 pod 规范中内联指定它们。临时卷非常适合不需要持久存储的应用程序,例如缓存服务。
当 Kubernetes 将 pod 分配给节点时,会创建一个 emptyDir 卷。此卷的生命周期与该特定节点上存在的 pod 的生命周期相关联。当容器重新启动或崩溃时,emptyDir 卷会重新创建。但是,当 pod 从节点中删除、崩溃或死亡时,此卷中的数据将被删除并丢失。
创建 emptyDir 卷后,您可以将卷类型名称声明为 Pod 清单文件中的字段。它在卷属性部分下显示空大括号 {} 作为值。EmptyDir 卷主要适用于临时数据存储。例如,您可以将其用于临时空间,例如基于磁盘的合并。
您可以在支持节点的介质上存储 emptyDir 卷。例如,您可以使用网络存储或 SSD。或者,您可以在 emptyDir.medium 字段中设置"memory",Kubernetes 将挂载一个 RAM 支持的文件系统 (tmpfs)。请注意,Kubernetes 会在节点重新启动时清除 tmpfs。
hostPath 卷将目录或文件从主机节点的文件系统装载到 Pod 中。
以下是 hostPath 卷的主要使用案例:
HostPath 卷安全
HostPath 卷会带来许多安全风险。请尽量避免使用。如果必须使用 HostPath 卷,则应将其范围仅限于所需的目录或文件,并将其装载为 ReadOnly。
以下是主要的安全风险:
您可以使用 AdmissionPolicy 来限制对某些目录的 HostPath 访问。但是,该策略仅在您要求 volumeMounts 使用 readOnly 装载时才有效。
ConfigMap 可以将配置数据注入到 Pod 中。存储在 ConfigMap 中的数据可以在 configMap 卷类型中引用,然后由在 Pod 中运行的容器化应用程序使用。在引用 ConfigMap 时,您需要在卷中提供 ConfigMap 的名称。Kubernetes 允许您自定义 ConfigMap 中特定条目的路径。
Kubernetes 提供了几个存储插件,可以访问部署在 Kubernetes 集群中的存储设备。这些是使用 StorageClass 对象实现的。
Kubernetes 目前支持的一些主要插件有 GCEPersistentDisk、AWSElasticBlockStore、AzureDisk、Glusterfs、NFS 和 iSCSI。有关这些插件的更多详细信息,请参见 StorageClass 文档。
让我们更详细地回顾两个值得注意的存储插件。
网络文件系统 (NFS) 是将存储设备装载为本地驱动器的标准协议。Kubernetes 允许您将 NFS 卷装载为容器中的本地驱动器。由于遗留代码经常通过 NFS 访问数据,因此该插件对于将遗留工作负载迁移到 Kubernetes 非常有用。
通过 NFS 和 Kubernetes 访问数据有两种方式:
容器存储接口 (CSI) 是一个标准接口,允许容器编排器将存储系统暴露给他们管理的容器。CSI 允许存储供应商创建"树外"的插件,这意味着它们不需要签入 Kubernetes 代码存储库,也不会随 Kubernetes 一起发布。
存储供应商直接提供许多基于 CSI 的树外插件。CSI 的出现使存储技术支持 Kubernetes 变得更加容易。
相关内容:阅读我们的 Container Storage Interface 指南
创建卷并使其可供 pod 访问涉及两个步骤:
这些步骤齐头并进。创建卷时,您还必须将其装载到容器中,并且不能在未在 pod 模板中声明的情况下装载卷。
以下是一个示例,显示了在 Pod 模板 YAML 配置中创建和挂载卷的过程:
spec: containers: —name: my-app image: nginx volumeMounts: —name: my-volume mountPath: /app/config volumes: —name: my-volume
在此代码中:
要创建 Kubernetes 卷,请部署一个或多个声明该卷的 pod。实现此目的的常用方法是通过 Deployment 对象。以下是执行以下操作的 Deployment 清单示例:
apiVersion: apps/v1 kind: Deployment metadata: name: pods-with-volumes spec: replicas: 3 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: —name: my-container image: nginx:1.14.2 volumeMounts: —mountPath: / name: my-volume volumes: —name: my-volume emptyDir: {}
请注意,此 Deployment 的名称在 pods-with-volumes 中定义——这就是在 Kubernetes 环境中引用它的方式。
正如我们在上一节中看到的,此 Deployment 对象执行创建卷所需的两个操作:
假设此 YAML 文件以 my-deployment.yaml 的名称保存。您可以使用以下命令在 Kubernetes 集群中创建 Deployment:
kubectl apply -f my-deployment.yaml
要验证 Deployment 是否正确运行并使用预期的卷,请运行以下命令:
kubectl describe pods pods-with-volumes
如果一切正常,输出将显示每个 pod 都有一个名为 my-container 的容器,其中包含请求的挂载点:
挂载:/ 从 my-volume (rw)
输出还将显示在每个 Pod 下运行的卷:
Volumes: my-volume: Type: EmptyDir (共享 pod 生存期的临时目录)
NetApp Cloud Volumes ONTAP,领先的企业级存储管理解决方案,在 AWS、Azure 和 Google Cloud 上提供安全、成熟的存储管理服务。Cloud Volumes ONTAP 容量可以扩展到数 PB,它支持各种用例,如文件服务、数据库、DevOps 或任何其他企业工作负载,具有强大的功能,包括高可用性、数据保护、存储效率、Kubernetes 集成等。
特别是,Cloud Volumes ONTAP 支持Kubernetes 持久卷配置和管理 容器化工作负载的要求。
详细了解 Cloud Volumes ONTAP 如何在这些 Kubernetes 工作负载与 Cloud Volumes ONTAP 案例研究中帮助解决容器化应用程序的挑战。