在K8S中使用Local持久卷
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在K8S中使用Local持久卷相关的知识,希望对你有一定的参考价值。
参考技术A 由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过卷解决上述的两个问题。在Docker有卷的概念卷,但Docker中存储卷只是磁盘的或另一个容器中的目录,并没有对其生命周期进行管理。Kubernetes的存储卷有自己的生命周期,它的生命周期与使用的它Pod生命周期一致。因此,相比于在Pod中运行的容器来说,存储卷的存在时间会比的其中的任何容器都长,并且在容器重新启动时会保留数据。当然,当Pod停止存在时,存储卷也将不再存在。在Kubernetes支持多种类型的卷,而Pod可以同时使用各种类型和任意数量的存储卷。在Pod中通过指定下面的字段来使用存储卷:
PV是系统管理员设置的存储,它是群集的一部分,是一种资源,所以它有独立于Pod的生命周期。
PVC是用户存储的请求。它与Pod相似,Pod消耗节点的CPU和内存资源,PVC则消耗PV资源,可以生命特定的容量大小和访问模式。
PV和PVC遵循如下的生命周期管理
PV有两种配置方式:静态或动态
要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的 DefaultStorageClass 准入控制器 。例如,通过确保 DefaultStorageClass 位于 API server 组件的 --admission-control 标志,使用逗号分隔的有序值列表中,可以完成此操作。有关 API server 命令行标志的更多信息,请检查 kube-apiserver 文档。
一旦用户创建或已经创建了具有特定存储量的 PersistentVolumeClaim 以及某些访问模式。Kubernetes控制器会监视到新的 PVC,并寻找匹配的 PV,并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则控制器会始终将该 PV 绑定到 PVC。总之,用户总会得到他们所请求的存储,但是容量可能超出请求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射。
如果没有匹配的PV,PVC将无限期地保持未绑定状态。随着匹配PV的可用,PVC将被绑定。例如,配置了许多 50Gi PV的集群将不会匹配请求 100Gi 的PVC。将100Gi PV 添加到群集时,则可以绑定到该 PVC。
Pod 使用PVC作为卷。集群检查PVC以查找绑定的卷并为集群挂载该卷。对于支持多种访问模式的卷,用户指定在使用声明作为容器中的卷时所需的模式(读写、只读)。
用户生命了PVC,并且该PVC是绑定的,则只要用户需要,绑定的 PV 就属于该用户。用户通过在 Pod 的 volume 配置中包含persistentVolumeClaim来调度 Pod 并访问用户声明的 PV。
K8S支持的卷类型很多,主要分为分布式文件系统、ConfigMap和本地文件系统这几种,其中本地文件系统支持:hostPath和local(从1.11开始出了Beta版本,编写本文时目前K8S最新版本是1.13了)。
在我们目前项目的实际开发中,我们常用两种卷挂载模式:
但是对于使用到本地磁盘来存储数据时,hostPath往往不太适合我们了,虽然它能够让Pod使用本地存储,将Node文件系统中的文件或者目录挂载到容器内,但是在这种应用场景,hostPath并不适合生产环境使用,主要原因如下:
当然hostPath还有其他的缺点,由于以上这两个关键的缺陷,在真正需要持久化数据存储的场景,我们不得不考虑local存储卷了。
Local PV是从kuberntes 1.10开始引入,本质目的是为了解决hostPath的缺陷。通过PV控制器与Scheduler的结合,会对local PV做针对性的逻辑处理,从而,让Pod在多次调度时,能够调度到同一个Node上。
首先,我们要准备好K8S环境,检查一下K8S中的节点。
现在登录到节点10.25.68.239上,然后手工创建一个目录,我们将后在后面创建的local PV绑定到这个目录中。
创建local的Storage Class
查看一下创建的storage class
创建PV:
查看一下pv情况
创建PVC
PVC将会一直处于Pending状态直到我们创建一个Pod使用它。
创建一个deployment使用这个pvc。
pvc现在绑定到对应的pv上面了。
查看pod被调度的节点,可以看到这个pod是会被调度到PV所在的Node:
我们再次登录到10.25.68.239,在/data/pv下生成index.html文件
检查一下index.html文件的服务
Local持久卷基本具备了hostPath的绑定本地文件系统目录的能力和方便性,同时自动具备调度到指定节点的能力,并且可以对持久卷进行管理。
唯一的问题在于,我们还需要手工去对应的节点创建对应的目录和删除对应的目录,这需要结合我们的应用系统来进行统一的设计和管理。
总得来说,对于状态应用程序的部署来说,Local持久卷能够提供分布式存储无法提供的高性能,同时具备了一定的调度的灵活性,是一个不错的选择。
POD崩溃时持久卷声明中的容器数据
我想创建一个带有POD的复制控制器,它将具有PVC(持久卷声明)。我的PVC将使用NFS存储用于PV(持久卷)。
一旦POD运行,RC将保持POD的运行。在这种情况下,POD中的数据是可用/持久的
- 删除命令停止/删除POD,RC重新启动它?这意味着Kubernetes没有关闭。在这种情况下,新POD可以从同一卷中获得相同的数据吗?
- POD停止,Kubernetes进程并重新启动节点。然而,NFS存储仍然作为PV附加。
- 一个新的PV连接到Kubernetes并且旧的PV被拆卸。
答案
这在很大程度上取决于您如何定义PV / PVC。根据我的经验,使用基于NFS的PV非常容易在pod重新创建删除之间保留数据。我采用以下方法来处理多个pod共享的NFS卷。
卷:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvname
spec:
capacity:
storage: 1Mi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: <nfs IP>
path: <nfs path>
要求 :
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvcname
spec:
volumeName: pvname
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
这确保了无论我在k8s中删除了什么,我都可以在NFS服务器上的已知路径上返回我的数据,并通过在k8上重新创建PV / PVC / POD再次重用它,因此它应该能够在你提到的所有三种情况下生存。
另一答案
根据您的提供商/供应商,persistentVolumeReclaimPolicy: Retain
不一定是“回来找我!”处理。根据Kubernetes文档,此策略旨在防止删除卷,以便您以后可以恢复数据(在Kubernetes之外)。
以下是此政策的用途:
$ kubectl get pvc,pv
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/nfs-server Bound nfs-server 100Gi RWX 5d
persistentvolumeclaim/nfs-server-wp-k8specs Bound nfs-server-wp-k8specs 100Gi RWX 2d
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-server 100Gi RWX Retain Bound default/nfs-server 5d
persistentvolume/nfs-server-wp-k8specs 100Gi RWX Retain Bound default/nfs-server-wp-k8specs 2d
以上是关于在K8S中使用Local持久卷的主要内容,如果未能解决你的问题,请参考以下文章