𝑰’𝒎 𝒉𝒉𝒈, 𝑰 𝒂𝒎 𝒂 𝒈𝒓𝒂𝒅𝒖𝒂𝒕𝒆 𝒔𝒕𝒖𝒅𝒆𝒏𝒕 𝒇𝒓𝒐𝒎 𝑵𝒂𝒏𝒋𝒊𝒏𝒈, 𝑪𝒉𝒊𝒏𝒂.

  • 🏫 𝑺𝒉𝒄𝒐𝒐𝒍: 𝑯𝒐𝒉𝒂𝒊 𝑼𝒏𝒊𝒗𝒆𝒓𝒔𝒊𝒕𝒚
  • 🌱 𝑳𝒆𝒂𝒓𝒏𝒊𝒏𝒈: 𝑰’𝒎 𝒄𝒖𝒓𝒓𝒆𝒏𝒕𝒍𝒚 𝒍𝒆𝒂𝒓𝒏𝒊𝒏𝒈 𝒅𝒆𝒔𝒊𝒈𝒏 𝒑𝒂𝒕𝒕𝒆𝒓𝒏, 𝑳𝒆𝒆𝒕𝒄𝒐𝒅𝒆, 𝒅𝒊𝒔𝒕𝒓𝒊𝒃𝒖𝒕𝒆𝒅 𝒔𝒚𝒔𝒕𝒆𝒎, 𝒎𝒊𝒅𝒅𝒍𝒆𝒘𝒂𝒓𝒆 𝒂𝒏𝒅 𝒔𝒐 𝒐𝒏.
  • 💓 𝑯𝒐𝒘 𝒕𝒐 𝒓𝒆𝒂𝒄𝒉 𝒎𝒆:𝑽𝑿
  • 📚 𝑴𝒚 𝒃𝒍𝒐𝒈: 𝒉𝒕𝒕𝒑𝒔://𝒉𝒉𝒈𝒚𝒚𝒅𝒔.𝒃𝒍𝒐𝒈.𝒄𝒔𝒅𝒏.𝒏𝒆𝒕/
  • 💼 𝑷𝒓𝒐𝒇𝒆𝒔𝒔𝒊𝒐𝒏𝒂𝒍 𝒔𝒌𝒊𝒍𝒍𝒔:𝒎𝒚 𝒅𝒓𝒆𝒂𝒎

一. Volume

1.1 简介

Volume(存储卷)是Pod中能够被多个容器访问的共享目录。Kubernetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价。首先,Kubernetes中的Volume被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;其次,Kubernetes中的Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时,Volume中的数据也不会丢失。最后,Kubernetes支持多种类型的Volume,例如GlusterFS、Ceph等先进的分布式文件系统。 -------《K8S权威指南》

由上可知

  • Volume是Pod内多个容器共享的卷。
  • 即容器重启volume不会丢失
  • 但是pod重启volume卷会丢失,注意:这里的volume卷丢失不代表volume对应的实际地址会丢失,而是spec.volumes的定义丢失。

1.2 常见的类型

以下列举一些常见或者需要了解的volume类型:

  1. emptyDir
    • 初始内容是空的的卷
  2. hostPath
    • hostpath为在Pod上挂载宿主机上的文件或者目录
  3. secret
    • 使用一个secret volume为pod提供加密信息
  4. configMap
    • 使用一个configMap为pod提供配置信息
  5. gitRepo
    • 通过挂载一个空目录,并且从git库clone一个repository以供pod使用
  6. glusterfs
    • 使用开源的glusterfs网络文件系统的目录挂载到pod
  7. awsElasticBlockStore
    • 对接aws云提供volume,了解即可
  8. gcePersistentDisk
    • 对接谷歌云提供的volume,了解即可
  9. azureDisk & azureFile
    • 对接微软Azure提供的volume,了解即可

1.3 emptyDir

1.3.1 简介

一个emptyDir Volume是在Pod分配到Node时创建的。从它的名称就可以看出,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为这是Kubernetes自动分配的一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。

1.3.2 用途

  • 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留。
  • 长时间任务的中间过程CheckPoint的临时保存目录。
  • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)。就是说emptyDir作为媒介。
    目前,用户无法控制emptyDir使用的介质种类。如果kubelet的配置是使用硬盘,那么所有emptyDir都将被创建在该硬盘上。

1.3.3 最佳实践

此时容器c1下的/path1和容器c2下的/path2是对应的同一个目录。

apiVersion: v1 
kind: Pod 
metadata:
  name: test-pd 
spec:
  containers:
  - image: lzw5399/tocgenerator
    name: c1
    # 把定义的cache-volume挂在到该容器c1下的/path1路径
    volumeMounts:
    - mountPath: /path1 
      name: cache-volume
  - image: lzw5399/codepie
    name: c2
    # 把定义的cache-volume挂在到该容器c2下的/path2路径
    volumeMounts:
    - mountPath: /path2
      name: cache-volume
  # 定义一个emptyDir的volume
  volumes:
  - name: cache-volume 
    emptyDir: {}

1.4 hostPath

hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中。

1.4.1 用途

  • 容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的高速文件系统进行存储。
  • 需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统。

1.4.2 注意点

  • 在不同的Node上具有相同配置的Pod,可能会因为宿主机上的目录和文件不同而导致对Volume上目录和文件的访问结果不一致。
  • 如果使用了资源配额管理,则Kubernetes无法将hostPath在宿主机上使用的资源纳入管理。

注意:

  • volume支持将configMap/Secret挂载在容器的某个目录上,但是会覆盖掉容器路径下原有的文件,如何支持选定configMap/Secret的每个key-value挂载在容器中,且不会覆盖掉原目录下的文件,这个时候也可以用到subpath。同时subPath有一个弊端,就是configMap修改之后,subPath是不会自动更新的,必须要手动更新。这跟普通的挂载整个目录是有区别的。

1.4.3 最佳实践

apiVersion: v1 
kind: Pod 
metadata:
  name: test-pd 
spec:
  containers:
  - image: k8s.gcr.io/test-webserver 
    name: test-container 
    volumeMounts:
    - mountPath: /test-pd 
      name: test-volum
  # 定义一个hostPath类型的volume
  volumes:
  - name: test-volume 
    hostPath:
      # 路径挂载到宿主机的/data下
      path: /data 
      # (可选) 指定类型,见上面的表
      type: Directory

以上内容大部分来自:https://www.cnblogs.com/baoshu/p/13269288.html

二. PersistentVolume(PV)PersistentVolumeClaim(PVC)

2.1 为什么需要Persistent Volume(PV)

Volume是被定义在pod上的(emptyDir或者hostPath),属于计算资源的一部分。所以Volume是有局限性的,因为在实际的运用过程中,我们通常会先定义一个网络存储,然后从中划出一个网盘并挂接到虚拟机上。

为了屏蔽底层存储实现的细节,让用户方便使用,同时让管理员方便管理。Kubernetes从V1.0版本就引入了PersistentVolume(PV)和与之相关联的PersistentVolumeClaim(PVC)两个资源对象来实现对存储的管理

2.2 PersistentVolume(PV)和Volume的区别

PV可以被理解成kubernetes集群中的某个网络存储对应的一块存储,它与Volume类似,但是有如下的区别:

  1. PV只能是网络存储,不属于任何Node,但是可以在每个Node上访问
  2. PV不是被定义在pod上,而是独立在pod之外被定义的。
    意味着pod被删除了,PV仍然存在,这点与Volume不同

2.3 PV和PVC之间的联系

2.3.1 PersistentVolume(PV)

PersistentVolume(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV也是集群中的资源。PV是Volume之类的卷插件,但具有独立于使用PV的Pod的生命周期。此API对象包含存储实现的细节,即NFS、iSCSl或特定于云供应商的存储系统。

2.3.2 PersistentVolumeClaim(PVC)

PersistentVolumeClaim(PVC)是用户存储的请求。它与Pod相似。Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或只读多次模式挂载)

2.3.3 PV和PVC的关系

pvc是一种pv的请求方案,PVC定义我当前需要什么样类型的PV,然后会自动在当前存在的pv中选取一个匹配度最高的pv。

等于pvc是提供给pod用的,它掩盖了pv具体的细节,pod不需要知道pv里面的情况,就像controller只需要调用service而不用管数据库层如何做,它只需要直接使用pvc即可。

在这里插入图片描述
一个PVC只能绑定一个PV!!

2.4 PV种类

2.4.1 静态pv

静态pv比较简单,就是我们通常用yml文件进行编辑的来定义不同的存储与参数,如性能,冗余等,来满足不同需求的PVC,就是静态pv。

2.4.2 动态pv(初学没有尝试过)

当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses,所以要启用基于存储级别的动态存储配置要求:

  • PVC必须请求StorageClasses
  • 管理员必须创建并配置StorageClasses才能进行动态创建
  • 声明该类为“”可以有效地禁用其动态配置
  • 集群管理员需要启用API server上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于API server 组件的–admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作

2.5 PVC保护机制

  PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失 当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何 pod使用

我们可以尝试下

[root@k8s-master nfsData]# kubectl delete pv mysql
persistentvolume "mysql" deleted
[root@k8s-master nfsData]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM           STORAGECLASS   REASON   AGE
mysql   5Gi        RWO            Retain           Terminating   default/mysql                           28h

就可以发现pv一直处于terminating的状态。因为还有Pod在用。正确的做法就是要先删pod再删pvc最后删pv。

2.6 PV的访问模式(spec.accessModes)

访问模式accessModes一共有三种:

  • ReadWriteOnce: 该卷可以被单个节点以读/写模式挂载
  • ReadOnlyMany: 该卷可以被多个节点以只读模式挂载
  • ReadWriteMany: 该卷可以被多个节点以读/写模式挂载

2.7 PV的回收三种策略

  • Retain(保留): pv被删除后会保留内存,手动回收
  • Recycle(回收): 删除卷下的所有内容(rm-rf /thevolume/*)
  • Delete(删除): 关联的存储资产(例如AWS EBS、GCE PD、Azure Disk 和OpenStack Cinder卷)将被删除。即直接把卷给删除了

2.8 PV的状态

  • Available(可用): 块空闲资源还没有被任何声明绑定
  • Bound(已绑定): 卷已经被声明绑定, 注意:但是不一定不能继续被绑定,看accessModes而定
  • Released(已释放): 声明被删除,但是资源还未被集群重新声明
  • Failed(失败): 该卷的自动回收失败

2.9 最佳实践NFS + PVC

K8S(八):NFS + PV + ConfigMap + Service 部署MySQL
这个是NFS+ConfigMap+PV/PVC部署MySQL的一个例子。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐