csi简介

Kubernetes1.9版本开始引入容器存储接口Container Storage Interface(CSI)机制,用于在Kubernetes和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务。

csi设计背景

Kubernetes通过PVPVCStorageclass已经提供了一种强大的基于插件的存储管理机制, 但是各种存储插件提供的存储服务都是基于一种被称为in-true(树内)的方式提供的, 这要求存储插件的代码必须被放进Kubernetes的主干代码库中才能被Kubernetes调用, 属于紧耦合的开发模式。这种in-tree方式会带来一些问题:

  • 存储插件的代码需要与Kubernetes的代码放在同一代码库中,并与Kubernetes的二进制文件共同发布
  • 存储插件代码的开发者必须遵循Kubernetes的代码开发规范
  • 存储插件代码的开发者必须遵循Kubernetes的发布流程,包括添加对Kubernetes存储系统的支持和错误修复
  • Kubernetes社区需要对存储插件的代码进行维护,包括审核、测试等工作
  • 存储插件代码中的问题可能会影响Kubernetes组件的运行,并且很难排查问题
  • 存储插件代码与Kubernetes的核心组件(kubelet和kubecontroller-manager)享有相同的系统特权权限,可能存在可靠性和安全性问题。
  • 部署第三方驱动的可执行文件仍然需要宿主机的root权限,存在安全隐患
  • 存储插件在执行mountattach这些操作时,通常需要在宿主机上安装一些第三方工具包和依赖库, 使得部署过程更加复杂,例如部署Ceph时需要安装rbd库,部署GlusterFS时需要安装mount.glusterfs库,等等

基于以上这些问题和考虑,Kubernetes逐步推出与容器对接的存储接口标准,存储提供方只需要基于标准接口进行存储插件的实现,就能使用Kubernetes的原生存储机制为容器提供存储服务。这套标准被称为CSI(容器存储接口)。

CSI成为Kubernetes的存储供应标准之后,存储提供方的代码就能和Kubernetes代码彻底解耦,部署也与Kubernetes核心组件分离,显然,存储插件的开发由提供方自行维护,就能为Kubernetes用户提供更多的存储功能,也更加安全可靠。

基于CSI的存储插件机制也被称为out-of-tree(树外)的服务提供方式,是未来Kubernetes第三方存储插件的标准方案。

csi架构

KubernetesCSI存储插件的关键组件和推荐的容器化部署架构:

CSI Controller

CSI Controller的主要功能是提供存储服务视角对存储资源和存储卷进行管理和操作。 在Kubernetes中建议将其部署为单实例Pod,可以使用StatefulSetDeployment控制器进行部署,设置副本数量为1,保证为一种存储插件只运行一个控制器实例。 在这个Pod内部署两个容器:

  • Master(kube-controller-manager)通信的辅助sidecar容器。在sidecar容器内又可以包含external-attacherexternal-provisioner两个容器,它们的功能分别如下:
    • external-attacher:监控VolumeAttachment资源对象的变更,触发针对CSI端点的ControllerPublishControllerUnpublish操作。
    • external-provisioner:监控PersistentVolumeClaim资源对象的变更,触发针对CSI端点的CreateVolumeDeleteVolume操作。
  • CSI Driver存储驱动容器,由第三方存储提供商提供,需要实现上述接口。

这两个容器通过本地Socket(Unix DomainSocket,UDS),并使用gPRC协议进行通信。 sidecar容器通过Socket调用CSI Driver容器的CSI接口,CSI Driver容器负责具体的存储卷操作。

CSI Node

CSI Node的主要功能是对主机(Node)上的Volume进行管理和操作。在Kubernetes中建议将其部署为DaemonSet,在每个Node上都运行一个Pod。 在这个Pod中部署以下两个容器:

  • kubelet通信的辅助sidecar容器node-driver-registrar,主要功能是将存储驱动注册到kubelet
  • CSI Driver存储驱动容器,由第三方存储提供商提供,主要功能是接收kubelet的调用,需要实现一系列与Node相关的CSI接口,例如NodePublishVolume接口(用于将Volume挂载到容器内的目标路径)、NodeUnpublishVolume接口(用于从容器中卸载Volume),等等。

node-driver-registrar容器与kubelet通过Node主机的一个hostPath目录下的unixsocket进行通信。CSI Driver容器与kubelet通过Node主机的另一个hostPath目录下的unixsocket进行通信,同时需要将kubelet的工作目录(默认为/var/lib/kubelet)挂载给CSIDriver容器,用于为Pod进行Volume的管理操作(包括mount、umount等)。

Copyright © weiliang 2021 all right reserved,powered by Gitbook本书发布时间: 2024-04-22 16:03:41

results matching ""

    No results matching ""