kubernetes ceph-csi分析目录导航

概述

下面的分析是k8s通过ceph-csi(csi plugin)接入ceph存储(csi相关组件的分析以rbd为例进行分析),对csi系统结构、所涉及的k8s对象与组件进行了简单的介绍,以及k8s对存储进行相关操作的流程分析,存储相关操作包括了存储创建、存储扩容、存储挂载、解除存储挂载以及存储删除操作。

csi系统结构

这是一张k8s csi的系统架构图,图中所画的组件以及k8s对象,接下来会一一进行分析。

csi简介

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

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

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

涉及k8s对象

1. PersistentVolume

持久存储卷,集群级别资源,代表了存储卷资源,记录了该存储卷资源的相关信息。

回收策略

(1)retain:保留策略,当删除PVC的时候,PV与外部存储资源仍然存在。

(2)delete:删除策略,当与pv绑定的pvc被删除的时候,会从k8s集群中删除PV对象,并执行外部存储资源的删除操作。

(3)resycle(已废弃)

pv状态迁移

available --> bound --> released

2. PersistentVolumeClaim

持久存储卷声明,namespace级别资源,代表了用户对于存储卷的使用需求声明。

示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test
namespace: test
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: csi-cephfs-sc
volumeMode: Filesystem
pvc状态迁移

pending --> bound

3. StorageClass

定义了创建pv的模板信息,集群级别资源,用于动态创建pv。

示例:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
parameters:
clusterID: ceph01
imageFeatures: layering
imageFormat: "2"
mounter: rbd
pool: kubernetes
provisioner: rbd.csi.ceph.com
reclaimPolicy: Delete
volumeBindingMode: Immediate

4. VolumeAttachment

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

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

示例:

apiVersion: storage.k8s.io/v1
kind: VolumeAttachment
metadata:
name: csi-123456
spec:
attacher: cephfs.csi.ceph.com
nodeName: 192.168.1.10
source:
persistentVolumeName: pvc-123456
status:
attached: true

5. CSINode

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

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

示例:

apiVersion: storage.k8s.io/v1
kind: CSINode
metadata:
name: 192.168.1.10
spec:
drivers:
- name: cephfs.csi.ceph.com
nodeID: 192.168.1.10
topologyKeys: null
- name: rbd.csi.ceph.com
nodeID: 192.168.1.10
topologyKeys: null

涉及组件与作用

下面先简单介绍下涉及的组件与作用,后面会有单独详细的介绍各个组件的作用。

1. volume plugin

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

后续对volume plugin的详细分析,以通过ceph-csi操作rbd为例进行分析。

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

in-tree

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

out-of-tree

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

csi plugin

本次的分析为k8s通过ceph-csi来使用ceph存储,ceph-csi属于csi plugin。csi plugin分为ControllerServer与NodeServer,各负责不同的存储操作。

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来做存储的扩容操作等。

Node-Driver-Registrar

Node-Driver-Registrar组件负责实现csi plugin(NodeServer)的注册,让kubelet感知csi plugin的存在。

组件部署方式

csi plugin controllerServer与external plugin作为容器,使用deployment部署,多副本可实现高可用;而csi plugin NodeServer与Node-Driver-Registrar作为容器,使用daemonset部署,即每个node节点都有。

2. kube-controller-manager

PV controller

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

创建/删除底层存储、创建/删除pv对象的操作,由PV controller调用volume plugin(in-tree)来完成。本次分析的是k8s通过ceph-csi来使用ceph存储,volume plugin为ceph-csi,属于out-tree,所以创建/删除底层存储、创建/删除pv对象的操作由external-provisioner来完成。

AD controller

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

不同的volume plugin的Attach/Detach操作逻辑有所不同,如通过ceph-csi(out-tree volume plugin)来使用ceph存储,则的Attach/Detach操作只是修改VolumeAttachment对象的状态,而不会真正的将数据卷挂载到节点/从节点上解除挂载,真正的节点存储挂载/解除挂载操作由kubelet中volume manager调用rc.operationExecutor.MountVolume/rc.operationExecutor.UnmountDevice方法时,调用ceph-csi来完成,后面会有博文详细做介绍。

3. kubelet

volume manager

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

本次的分析为k8s通过ceph-csi来使用ceph存储。本次分析中,volume manager的Attach/Detach操作只创建/删除VolumeAttachment对象,而不会真正的将数据卷挂载到节点/从节点上解除挂载;csi-attacer组件也不会做挂载/解除挂载操作,只是更新VolumeAttachment对象,真正的节点挂载/解除挂载操作由kubelet中volume manager调用rc.operationExecutor.MountVolume/rc.operationExecutor.UnmountDevice方法时,调用ceph-csi来完成,后面会有博文详细做介绍。

kubernetes创建与挂载volume(in-tree volume plugin)

先来看下kubernetes通过in-tree volume plugin来创建与挂载volume的流程

(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调度。

(7)(8)pod调度完成后,AD controller/volume manager watch到pod声明的volume没有进行attach操作,将调用volume plugin来做attach操作。

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

(10)(11)attach操作完成后,volume manager watch到pod声明的volume没有进行mount操作,将调用volume plugin来做mount操作。

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

kubernetes创建与挂载volume(out-of-tree volume plugin)

再来看下kubernetes通过out-of-tree volume plugin来创建与挂载volume的流程,以csi-plugin为例。

(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调度。

(7)(8)pod调度完成后,AD controller/volume manager watch到pod声明的volume没有进行attach操作,将调用csi-attacher来做attach操作(实际上只是创建volumeAttachement对象)。

(9)external-attacher组件watch到volumeAttachment对象的新建,调用csi-plugin进行attach操作(如果volume plugin是ceph-csi,external-attacher组件watch到volumeAttachment对象的新建后,只是修改该对象的状态属性,不会做attach操作,真正的attach操作由kubelet中的volume manager调用volume plugin ceph-csi来完成)。

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

(11)(12)attach操作完成后,volume manager watch到pod声明的volume没有进行mount操作,将调用csi-mounter来做mount操作。

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

kubernetes存储相关操作流程具体分析(out-of-tree volume plugin,以ceph-csi为例)

下面来看下kubernetes通过out-of-tree volume plugin来创建/删除、挂载/解除挂载volume的流程。

下面先对每个操作的整体流程进行分析,后面会对涉及的每个组件进行源码分析。

1. 存储创建

流程图

流程分析

(1)用户创建pvc对象;

(2)pv controller监听pvc对象,寻找现存的合适的pv对象,与pvc对象绑定。当找不到现存合适的pv对象时,将更新pvc对象,添加annotation:volume.beta.kubernetes.io/storage-provisioner,让external-provisioner组件开始开始创建存储与pv对象的操作;当找到时,将pvc与pv绑定,结束操作。

(3)external-provisioner组件监听到pvc的新增事件,判断pvc的annotation:volume.beta.kubernetes.io/storage-provisioner的值,即判断是否是自己来负责做创建操作,是则调用ceph-csi组件进行存储的创建;

(4)ceph-csi组件调用ceph创建底层存储;

(5)底层存储创建完成后,external-provisioner根据存储信息,拼接pv对象,创建pv对象;

(6)pv controller监听pvc对象,寻找合适的pv对象,与pvc对象绑定。

2. 存储扩容

流程图

流程分析

(1)修改pvc对象,修改申请存储大小(pvc.spec.resources.requests.storage);

(2)修改成功后,external-resizer监听到该pvc的update事件,发现pvc.Spec.Resources.Requests.storgage比pvc.Status.Capacity.storgage大,于是调ceph-csi组件进行 controller端扩容;

(3)ceph-csi组件调用ceph存储,进行底层存储扩容;

(4)底层存储扩容完成后,ceph-csi组件更新pv对象的.Spec.Capacity.storgage的值为扩容后的存储大小;

(5)kubelet的volume manager在reconcile()调谐过程中发现pv.Spec.Capacity.storage大于pvc.Status.Capacity.storage,于是调ceph-csi组件进行 node端扩容;

(6)ceph-csi组件对dnode上存储对应的文件系统扩容;

(7)扩容完成后,kubelet更新pvc.Status.Capacity.storage的值为扩容后的存储大小。

3. 存储挂载

流程图

kubelet启动参数--enable-controller-attach-detach,该启动参数设置为 true 表示启用 Attach/Detach controller进行Attach/Detach 操作,同时禁用 kubelet 执行 Attach/Detach 操作(默认值为 true)。实际上Attach/Detach 操作就是创建/删除VolumeAttachment对象。

(1)kubelet启动参数--enable-controller-attach-detach=true,Attach/Detach controller进行Attach/Detach 操作

(2)kubelet启动参数--enable-controller-attach-detach=false,kubelet端volume manager进行Attach/Detach 操作

流程分析

(1)用户创建一个挂载了pvc的pod;

(2)AD controller或volume manager中的reconcile()发现有volume未执行attach操作,于是进行attach操作,即创建VolumeAttachment对象;

(3)external-attacher组件list/watch VolumeAttachement对象,更新VolumeAttachment.status.attached=true;

(4)AD controller更新node对象的.Status.VolumesAttached属性值,将该volume记为attached;

(5)kubelet中的volume manager获取node.Status.VolumesAttached属性值,发现volume已被标记为attached;

(6)于是volume manager中的reconcile()调用ceph-csi组件的NodeStageVolume与NodePublishVolume完成挂载。

4. 解除存储挂载

流程图

(1)AD controller

(2)volume manager

流程分析

(1)用户删除声明了pvc的pod;

(2)AD controller或volume manager中的reconcile()发现有volume未执行dettach操作,于是进行dettach操作,即删除VolumeAttachment对象;

(3)AD controller或volume manager等待VolumeAttachment对象删除成功;

(4)AD controller更新新node对象的.Status.VolumesAttached属性值,将标记为attached的该volume从属性值中去除;

(5)kubelet中的volume manager获取node.Status.VolumesAttached属性值,找不到相关的volume信息;

(6)于是volume manager中的reconcile()调用ceph-csi组件的NodeUnpublishVolume与NodeUnstageVolume完成解除挂载。

5. 删除存储

流程图

流程分析

(1)用户删除pvc对象;

(2)pv controller发现与pv绑定的pvc对象被删除,于是更新pv的状态为released;

(3)external-provisioner watch到pv更新事件,并检查pv的状态是否为released,以及回收策略是否为delete;

(4)接下来external-provisioner组件会调用ceph-csi的DeleteVolume来删除存储;

(5)ceph-csi组件的DeleteVolume方法,调用ceph集群命令,删除底层存储;

(6)external-provisioner组件删除pv对象。

k8s通过ceph-csi接入存储的概要分析的更多相关文章

  1. k8s使用ceph作为后端存储挂载

    一.在ceph集群上操作: 1.创建池(主要使用存储类来进行持久卷的挂载,其他的挂载方式不好使也太麻烦):ceph osd pool create k8s 64 二.在k8s上操作: 1.安装客户端( ...

  2. K8S学习笔记之k8s使用ceph实现动态持久化存储

    0x00 概述 本文章介绍如何使用ceph为k8s提供动态申请pv的功能.ceph提供底层存储功能,cephfs方式支持k8s的pv的3种访问模式ReadWriteOnce,ReadOnlyMany ...

  3. k8s使用ceph的rbd作后端存储

    k8s使用rbd作后端存储 k8s里的存储方式主要有三种.分别是volume.persistent volumes和dynamic volume provisioning. volume: 就是直接挂 ...

  4. k8s client-go源码分析 informer源码分析(1)-概要分析

    k8s informer概述 我们都知道可以使用k8s的Clientset来获取所有的原生资源对象,那么怎么能持续的获取集群的所有资源对象,或监听集群的资源对象数据的变化呢?这里不需要轮询去不断执行L ...

  5. Ceph RBD CephFS 存储

    Ceph RBD  CephFS 存储 环境准备: (这里只做基础测试, ceph-manager , ceph-mon, ceph-osd 一共三台) 10.6.0.140 = ceph-manag ...

  6. Ceph之对象存储网关RADOS Gateway(RGW)

    一.Ceph整体架构及RGW在Ceph中的位置 1.Ceph的整体架构 Ceph是一个统一的.分布式的的存储系统,具有优秀的性能.可靠性和可扩展性.Ceph支持对象存储(RADOSGW).块存储(RB ...

  7. CEPH-4:ceph RadowGW对象存储功能详解

    ceph RadosGW对象存储使用详解 一个完整的ceph集群,可以提供块存储.文件系统和对象存储. 本节主要介绍对象存储RadosGw功能如何灵活的使用,集群背景: $ ceph -s clust ...

  8. 自建存储与使用微软Azure、七牛等第三方云存储综合考察分析

    http://www.cnblogs.com/sennly/p/4136734.html 各种云服务这两年炒的火热,加之可以降低成本,公司想先在部分业务上尝试使用下,刚好最近有个项目有大量小文件需要存 ...

  9. MySQL存储写入速度慢分析

    问题背景描述: 在MySQL中执行SQL语句,比如insert,贼慢,明明可能也就只是一行数据的插入,数据量很小,但是耗费的时间却很多,为什么? 一.存储结构分析 MySQL存储结构图: 解析: 1. ...

随机推荐

  1. Go - 开箱即用,WEB 界面一键安装,没有项目经验,可以拿这个练手

    安装界面 启动程序之后,会在浏览器中自动打开安装界面. 因为程序会使用到 Redis 和 MySQL,所以安装前请输入 Redis.MySQL 配置信息,点击初始化按钮,会将用到的数据表和默认数据进行 ...

  2. [bug] VMvare 虚拟机磁盘空间耗尽

    问题 VMvare虚拟机文件默认创建在C盘,装大程序的时,空间用尽就会报错,此时补救的办法是把虚拟机文件复制到空间足够的盘,再重新打开 最好一开始就选再有足够空间的盘里创建虚拟机 参考 https:/ ...

  3. 还可以使用 -c 参数来显示全部内容,并标出不同之处 diff -c test2.txt test1.txt

    二.实例 在test目录下存放了两个文本文件,test1.txt  test2.txt . 比较这两个文件的异同. diff  test1.txt   test2.txt     "5c5& ...

  4. 016.Python闭包函数以及locals和globals

    一 闭包函数 内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数 1.1 闭包函数语法 def outer(): a = 5 def inner(): pr ...

  5. 解决Windows路径太长的目录以及文件名超长删除的问题

    因Windows文件夹有长度限制,在路径太深,长度达到600多个字符时,删除文件时出现报错"源文件名长度大于文件系统支持的长度.请尝试将其移动到具有较短路径名称的位置,或者在执行此操作前尝试 ...

  6. 8.12-14 df 、mkswap、swapon、swapoff、sync

    8.12 df:报告文件系统磁盘空间的使用情况   -a    显示所有文件系统 -h    以容易理解的格式显示磁盘的使用情况端 -i    显示文件系统的inode信息迷 -t    显示指定类型 ...

  7. IDEA 创建 Vue 文件(Day_41)

    IDEA 创建 Vue 文件 1. 在setting-->plugins里安装vue插件,安装成功之后重启IDEA 如图 2. 在setting-->Editor-->File Ty ...

  8. Python - random 库的详细使用

    前言 为啥突然写这个?因为用到就写呗,感觉对生成数据很有用,之前都是百度别人的,今天来对着官方文档写,超级标准! 这边只讲常用的,看了下文档还有什么数学方法,太高级好像用不上 返回整数 random. ...

  9. 解决Caused by: org.apache.ibatis.exceptions.PersistenceException:

    在mybatis-config核心配置文件中注册了xml以后出现了新的异常错误 Caused by: java.io.IOException: Could not find resource cn.d ...

  10. 工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染

    Activiti中的表单 Activiti提供了一种方便而且灵活的方式在业务流程中以手工方式添加表单 对表单的支持有2种方式: 通过表单属性对内置表单进行渲染 通过表单属性对外置表单进行渲染 表单属性 ...