linux怎么查看本机内存大小
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/
如果登录到该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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~