Kubernetes存储原理详解

网友投稿 251 2022-09-10

Kubernetes存储原理详解

1 简介

这是一张 K8S CSI 系统架构图

2 相关解释

CSI是​​Container Storage Interface​​(容器存储接口)的简写。

CSI 的目的是定义行业标准“容器存储接口”,使存储供应商能够开发一个符合CSI标准的插件并使其可以在多个容器编排系统中工作。

CSI组件一般采用容器化部署,减少了环境依赖。

3 K8S对象

3.1 PersistentVolume

集群级别的资源,持久存储卷,由 集群管理员 或者 External Provisioner 创建。

PV 的生命周期独立于使用 PV 的 Pod,PV 的 ​​.Spec​​ 中保存了存储设备的详细信息。

回收策略

retain:保留策略,当删除PVC的时候,PV与外部存储资源仍然存在。delete:删除策略,当与PV绑定的PVC被删除的时候,会从K8S集群中删除PV对象,并执行外部存储资源的删除操作。resycle(已废弃)

包含状态:

AvailableBoundReleased

3.2 PersistentVolumeClaim

PVC 类似于 Pod,Pod 消耗 Node 资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存),而 PVC 可以请求特定存储卷的大小及访问模式(Access Mode)

apiVersion: v1kind: PersistentVolumeClaimmetadata: name: nginx-pvcspec: storageClassName: cbs accessModes: - ReadWriteOnce resources: requests: storage: 10Gi复制代码

包含状态:

PendingBound

3.3 StorageClass

StorageClass 是集群级别的资源,由集群管理员创建。定义了创建pv的模板信息,用于动态创建PV。

apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: cbsparameters: type: cbsprovisioner: cloud.tencent.com/qcloud-cbsreclaimPolicy: DeletevolumeBindingMode: Immediate复制代码

3.4 VolumeAttachment

记录了PV的相关挂载信息,如挂载到哪个node节点,由哪个​​volume plugin​​来挂载等。

​​AD Controller​​ 创建一个​​VolumeAttachment​​,而 ​​External-attacher​​ 则通过观察该 ​​VolumeAttachment​​,根据其状态属性来进行存储的挂载和卸载操作。

3.5 CSINode

CSINode 记录了​​csi plugin​​的相关信息(如nodeId、driverName、拓扑信息等)。

当Node Driver Registrar向kubelet注册一个csi plugin后,会创建(或更新)一个CSINode对象,记录csi plugin的相关信息

apiVersion: storage.k8s.io/v1beta1kind: CSINodemetadata: name: 10.1.2.11spec: drivers: - allocatable: count: 18 name: com.tencent.cloud.csi.cbs nodeID: ins-ig73rt44 topologyKeys: - topology.com.tencent.cloud.csi.cbs/zone复制代码

4 存储组件及作用

4.1 Volume Plugin

扩展各种存储类型的卷的管理能力,实现第三方存储的各种操作能力与k8s存储系统的结合。

调用第三方存储的接口或命令,从而提供数据卷的创建/删除、attach/detach、mount/umount的具体操作实现,可以认为是第三方存储的代理人。前面分析组件中的对于数据卷的创建/删除、attach/detach、mount/umount操作,全是调用volume plugin来完成。

根据源码所在位置,​​volume plugin​​分为in-tree与out-of-tree

in-tree

在K8S源码内部实现,和K8S一起发布、管理,更新迭代慢、灵活性差。

out-of-tree

代码独立于K8S,由存储厂商实现,有CSI、flexvolume两种实现。

csi plugin

external plugin

external plugin包括了external-provisioner、external-attacher、external-resizer、external-snapshotter等,external plugin辅助csi plugin组件,共同完成了存储相关操作。external plugin负责watch pvc、volumeAttachment等对象,然后调用volume plugin来完成存储的相关操作。如external-provisioner watch pvc对象,然后调用csi plugin来创建存储,最后创建pv对象;external-attacher watch volumeAttachment对象,然后调用csi plugin来做attach/dettach操作;external-resizer watch pvc对象,然后调用csi plugin来做存储的扩容操作等。

4.2 kube-controller-manager

PV controller

负责pv、pvc的绑定与生命周期管理(如创建/删除底层存储,创建/删除pv对象,pv与pvc对象的状态变更)。

创建/删除底层存储、创建/删除pv对象的操作,由PV controller调用volume plugin(in-tree)来完成。

AD controller

AD Cotroller全称Attachment/Detachment 控制器,主要负责创建、删除VolumeAttachment对象,并调用volume plugin来做存储设备的Attach/Detach操作(将数据卷挂载到特定node节点上/从特定node节点上解除挂载),以及更新node.Status.VolumesAttached等。

不同的volume plugin的Attach/Detach操作逻辑有所不同,如通过out-tree volume plugin来使用存储,则的Attach/Detach操作只是修改VolumeAttachment对象的状态,而不会真正的将数据卷挂载到节点/从节点上解除挂载,真正的节点存储挂载/解除挂载操作由kubelet中volume manager调用。

4.3 kubelet

volume manager

主要是管理卷的Attach/Detach(与AD controller作用相同,通过kubelet启动参数控制哪个组件来做该操作)、mount/umount等操作。

5 流程分析

5.1 创建与挂载

5.1.1 in-tree

[1] 用户创建pvc

[2] PV controller watch到PVC的创建,寻找合适的PV与之绑定

[3、4] 当找不到合适的PV时,将调用volume plugin来创建volume,并创建PV对象,之后该PV对象与PVC对象绑定

[5] 用户创建挂载PVC的pod

[6] kube-scheduler watch到pod的创建,为其寻找合适的node调度

[9] volume plugin进行attach操作,将volume挂载到pod所在node节点,成为如​​/dev/vdb​​的设备

[12] volume plugin进行mount操作,将node节点上的第[9]步得到的/dev/vdb设备挂载到指定目录

5.1.2 Out-tree

[1] 用户创建PVC

[2] PV controller watch到PVC的创建,寻找合适的PV与之绑定。当寻找不到合适的PV时,将更新PVC对象,添加​​annotation: volume.beta.kubernetes.io/storage-provisioner​​,让external-provisioner组件开始开始创建存储与PV对象的操作

[3] external-provisioner组件watch到PVC的创建,判断annotation:volume.beta.kubernetes.io/storage-provisioner的值,即判断是否是自己来负责做创建操作,是则调用csi-plugin ControllerServer来创建存储,并创建PV对象

[4] PV controller watch到PVC,寻找合适的PV(上一步中创建)与之绑定

[5] 用户创建挂载PVC的Pod

[6] kube-scheduler watch到Pod的创建,为其寻找合适的node调度

[9] external-attacher组件watch到volumeAttachment对象的新建,调用csi-plugin进行attach操作

[10] csi-plugin ControllerServer进行attach操作,将volume挂载到Pod所在node节点,成为如/dev/vdb的设备

[13] csi-mounter调用csi-plugin NodeServer进行mount操作,将node节点上的第(10)步得到的/dev/vdb设备挂载到指定目录

附录

emptyDir

emptyDir 类型的 volume 创建于 Pod 被调度到某个宿主机上的时候,而同一个 Pod 内的容器都能读写 emptyDir 中的同一个文件。一旦这个 Pod 离开了这个宿主机,emptyDir 中的数据就会被永久删除。

所以目前EmptyDir类型的volume主要用作临时空间,比如:

Web服务器写日志tmp文件需要的临时目录

使用步骤如下:

volumes: - name: nginxdata emptyDir: {}复制代码

然后,才能在容器中挂在这个volume

volumeMounts: # mountPath即volume在容器内的挂载点路径 - mountPath: /var/ name: nginxdata复制代码

测试​​yaml​​:

apiVersion: apps/v1kind: Deploymentmetadata: name: test-dpspec: replicas: 1 selector: matchLabels: app: test-dp template: metadata: labels: app: test-dp spec: containers: - name: nginx image: nginx:1.19.5 volumeMounts: - mountPath: /var/ name: nginxdata volumes: - name: nginxdata emptyDir: {}复制代码

按照以上的配置文件创建了​​Pod​​之后,可以在宿主机上的​​/var/lib/kubelet/pods//volumes/kubernetes.io~empty-dir​​目录下查看到新生成的名为​​nginxdata​​的目录。

如果登录到该Pod创建的容器中,也可以看到名为​​/var/Volume为​​Pod​​挂载宿主机上的目录或文件,使得容器可以使用宿主机的高速文件系统进行存储。

缺点是,在K8S中,Pod都是动态在各node节点上调度。当一个Pod在当前node节点上启动并通过hostPath存储了文件到本地以后,下次调度到另一个节点上启动时,就无法使用在之前节点上存储的文件。

apiVersion: apps/v1kind: Deploymentmetadata: name: test-dpspec: replicas: 1 selector: matchLabels: app: test-dp template: metadata: labels: app: test-dp spec: containers: - name: nginx image: nginx:1.19.5 volumeMounts: - mountPath: /var/ name: nginxdata volumes: - name: nginxdata hostPath: path: /data

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Prometheus监控MySQL
下一篇:DoMarketing-营销智库:三只松鼠抽检超标,这个网红零食品牌怎么了?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~