Kubernetes CSI简介

栏目: 服务器 · 发布时间: 5年前

内容简介:官方spec文档:术语简称:CSI是

官方spec文档: CSI Spec

术语简称:

  • CSI:Container Storage Interface
  • CO:Container Orchestrator system
  • SP:Storage Provider

CSI是 Container Storage Interface 的简称,旨在能为容器编排引擎和存储系统间建立一套标准的存储调用接口,通过该接口能为容器编排引擎提供存储服务。

在CSI之前,K8S里提供存储服务是通过一种称为 in-tree 的方式来提供,如下图:

Kubernetes CSI简介

这种方式需要将存储提供者的代码逻辑放到K8S的代码库中运行,调用引擎与插件间属于强耦合,这种方式会带来一些问题:

  1. 存储插件需要一同随K8S发布。
  2. K8S社区需要对存储插件的测试、维护负责。
  3. 存储插件的问题有可能会影响K8S部件正常运行。
  4. 存储插件享有K8S部件同等的特权存在安全隐患。
  5. 存储插件开发者必须遵循K8S社区的规则开发代码。

当前已有的 FlexVolume 机制试图通过调用一个可执行的程序包方式去解决这些问题,虽然它已经能够做到让存储提供方进行独立开发,但是有两个问题还没有得到很好解决:

  1. 在部署这些可执行文件时,需要host的root权限,依然存在安全隐患。

  2. 存储插件在执行mount、attach这类操作时,往往需要到host去安装第三方 工具 或者加载一些依赖库,这样host的OS版本往往需要定制,不再是一个简单的 linux 发型版本,这样的情况太多,会使部署变得复杂。

    例如:ceph需要安装rbd,gluster mount需要安装mount.glusterfs等等。

基于这些问题和挑战,CO(Container Orchestrator) 厂商提出 Container Storage Interface 用来定义容器存储标准,它独立于 Kubernetes Storage SIG,由 Kubernetes、Mesos、Cloud Foundry 三家一起推动。个人理解它有如下2个核心目标:

  • 提供统一的 CO 和 SP 都遵循的容器存储接口
  • 基于 CSI 实现了自身的 Volume Driver,即可在所有支持 CSI 的 CO 中平滑迁移

CSI 持久化卷支持是在 Kubernetes v1.9 中引入的,作为一个 alpha 特性,必须由集群管理员明确启用。在kubernetes v1.10中,默认CSI是启用的。

Kubernetes CSI架构

Kubernetes的CSI架构如下,包含三个部分:

  1. Kubernetes Core:Kubernetes核心组件
  2. Kubernetes External Component:Kubernetes支持CSI的扩展组件
  3. External Component:第三方存储厂商开发

Kubernetes CSI简介

Kubernetes External Component

在CSI的框架里,Kubernetes本身需要提供以下三类插件:

- Driver registrar

一个Sidecar Container,向Kubernetes注册CSI Driver,添加Drivers的一些信息。

源码: https://github.com/kubernetes-csi/driver-registrar

- External provisioner

一个Sidecar Container,监控Kubernetes系统里的PVC对象,调用对应CSI的Volume创建、删除等接口。

源码: https://github.com/kubernetes-csi/external-provisioner

- External attacher

一个Sidecar Container,监控Kubernetes系统里的VolumeAttachment对象,调用对应CSI的接口。

源码: https://github.com/kubernetes-csi/external-attacher

K8S CSI扩展组件的镜像下载:

https://quay.io/organization/k8scsi

Storage Vendor external component

在CSI的框架中,存储提供商需要自己实现CSI标准里的存储插件,主要有如下三类:

- CSI Identity

负责认证插件的状态信息,实现如下接口:

service Identity {
  rpc GetPluginInfo(GetPluginInfoRequest)
        returns (GetPluginInfoResponse) {}

  rpc GetPluginCapabilities(GetPluginCapabilitiesRequest)
        returns (GetPluginCapabilitiesResponse) {}

  rpc Probe (ProbeRequest)
        returns (ProbeResponse) {}
}

- CSI Controller

负责实际创建和管理volumes,实现如下接口:

service Controller {
  rpc CreateVolume (CreateVolumeRequest)
        returns (CreateVolumeResponse) {}

  rpc DeleteVolume (DeleteVolumeRequest)
        returns (DeleteVolumeResponse) {}

  rpc ControllerPublishVolume (ControllerPublishVolumeRequest)
        returns (ControllerPublishVolumeResponse) {}

  rpc ControllerUnpublishVolume (ControllerUnpublishVolumeRequest)
        returns (ControllerUnpublishVolumeResponse) {}

  rpc ValidateVolumeCapabilities (ValidateVolumeCapabilitiesRequest)
        returns (ValidateVolumeCapabilitiesResponse) {}

  rpc ListVolumes (ListVolumesRequest)
        returns (ListVolumesResponse) {}

  rpc GetCapacity (GetCapacityRequest)
        returns (GetCapacityResponse) {}

  rpc ControllerGetCapabilities (ControllerGetCapabilitiesRequest)
        returns (ControllerGetCapabilitiesResponse) {}  
}

- CSI Node

负责在Kubernetes Node上volume相关的功能,实现如下接口:

service Node {
  rpc NodeStageVolume (NodeStageVolumeRequest)
        returns (NodeStageVolumeResponse) {}

  rpc NodeUnstageVolume (NodeUnstageVolumeRequest)
        returns (NodeUnstageVolumeResponse) {}

  rpc NodePublishVolume (NodePublishVolumeRequest)
        returns (NodePublishVolumeResponse) {}

  rpc NodeUnpublishVolume (NodeUnpublishVolumeRequest)
        returns (NodeUnpublishVolumeResponse) {}

  rpc NodeGetId (NodeGetIdRequest)
        returns (NodeGetIdResponse) {}

  rpc NodeGetCapabilities (NodeGetCapabilitiesRequest)
        returns (NodeGetCapabilitiesResponse) {}
}

CSI Drivers

当前已经有好多可以在Kubernetes中使用的CSI Drivers,参考:

https://kubernetes-csi.github.io/docs/Drivers.html

开发CSI Driver

SP要开发一个CSI Driver,要遵循以下三条:

  • 实现CSI接口的功能
  • 实现CSI接口的幂等性
  • 符合CSI返回值规范

SP实现CSI Driver

实现的CSI Driver组件有三个:

  • Identity Plugin
  • Controller Plugin
  • Node Plugin

结合这三个组件的功能,开发者有两种选择:

1、两个执行文件:Controller + Identity,Node + Identity

Kubernetes CSI简介

2、一个执行文件:Controller + Node + Identity

Kubernetes CSI简介

从调研结果看,官方推荐使用第二种:Controller + Node + Identity

优点:一个可执行文件,方便维护和部署

部署CSI组件

如上介绍,Controller负责volumes的创建删除等操作,整个集群只需要部署一个;Node负责volume的attach、detach等操作,需要在每个节点部署一个,则Kubernetes的推荐部署方式为:

  1. Controller plugin:StatefulSet,replicas设为1
  2. Node plugin:DaemonSet

Kubernetes CSI简介

部署Kubernetes扩展组件

单纯的开发完CSI Driver后,还需要CO提供对应的扩展插件来支持CSI,这样CO系统才能正常的使用CSI的方式调用存储。

在Kubernetes系统里,扩容插件和CSI的部署可以按照如下方式:

Kubernetes CSI简介

Ceph SP Example

Ceph提供了RBD和CephFS两种CSI接口的存储。

源码: https://github.com/ceph/ceph-csi

Ceph CSI部署

Controller Plugin在哪里?

在各个组件的plugin里!(rbdplugin/cephfsplugin)

疑问:PVName与RBD Image名字是否一致?

问题: https://github.com/kubernetes/kubernetes/issues/69324

在之前的external-storage的代码里,Ceph RBD Image名字与PVName完全无关联,带来了不必要的查询麻烦,那新的CSI框架下,这两个名字是否一致呢?

ceph-csi的实现

文件:pkg/rbd/controllerserver.go

func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
    ...
	// Generating Volume Name and Volume ID, as according to CSI spec they MUST be different
	volName := req.GetName()
	uniqueID := uuid.NewUUID().String()
	if len(volName) == 0 {
		volName = rbdVol.Pool + "-dynamic-pvc-" + uniqueID
	}
	rbdVol.VolName = volName
    ...
}

从ceph-csi的rbd实现看,volName是否是随机UUID跟CreateVolume传入的参数相关。

Kubernetes扩展组件实现

文件:pkg/controller/controller.go

func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) {
    ...
 	pvName, err := makeVolumeName(p.volumeNamePrefix, fmt.Sprintf("%s", options.PVC.ObjectMeta.UID), p.volumeNameUUIDLength)
    ...
}

文件:cmd/csi-provisioner/csi-provisioner.go

var (
    ...
    volumeNamePrefix     = flag.String("volume-name-prefix", "pvc", "Prefix to apply to the name of a created volume.")
    volumeNameUUIDLength = flag.Int("volume-name-uuid-length", -1, "Truncates generated UUID of a created volume to this length. Defaults behavior is to NOT truncate.")
    ...
)

从这里可以看出,Kubernetes的Controller组件实现里,支持启动时候指定:

pvc
-1

所以在CSI的框架下,默认Kubernetes的Controller组件会传入Volume Name,底层Ceph RBD CSI实现中也会检查这个Name,如果设置的话就会依据它来创建RBD Image。


以上所述就是小编给大家介绍的《Kubernetes CSI简介》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程人生(上卷)

编程人生(上卷)

[美] Peter Seibel / 图灵社区 / 人民邮电出版社 / 2014-12 / 39.00元

这是一本访谈笔录,记录了当今最具个人魅力的15 位软件先驱的编程生涯。包括Donald Knuth、Jamie Zawinski、Joshua Bloch、Ken Thompson等在内的业界传奇人物,为我们讲述了他们是怎么学习编程的,在编程过程中发现了什么以及他们对未来的看法,并对诸如应该如何设计软件等长久以来一直困扰很多程序员的问题谈了自己的观点。中文版分为上下卷,上卷介绍8位大师。一起来看看 《编程人生(上卷)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器