kubernetes里存储概念的解疑

近日在 Kubernetes 使用 Ceph 的问题中,因为在两地,没有面对面的沟通,导致了理解的差异与不解,后来与本地同事详细沟通后,终于弄明白了之前的隔阂和问题所在,这里做下记录。

问题

Kubernetes存储简介

Kubernetes 里存储的使用,可分为两类:

  1. PersistentVolume和PersistentVolumeClaims

    • A PersistentVolume(PV) is a piece of storage in the cluster that has been provisioned by an administrator.
    • A PersistentVolumeClaims(PVC) is a request for storage by a user.
  2. StorageClasses

    • A StorageClass provides a way for administrators to describe the “classes” of storage they offer.

PVs支持两种方式的provision: statically or dynamically.

  • Static

    A cluster administrator creates a number of PVs.

  • Dynamic

    Base StorageClasses, when none of the static PVs the administrator created matches a user’s PersistentVolumeClaim, the cluster may try to dynamically provision a volume specially for the PVC.

从是否支持多客户端同时读写,也可分为三类:

  1. ReadWriteOnce
  2. ReadOnlyMany
  3. ReadWriteMany

Kubernetes存储需求

Kubernetes 对存储的需求,大致可以总结为两类:

  1. 独立使用的PV
  2. 支持多客户端同时读写的PV
  3. 支持多客户端同时读写 + Dynamic provisioning的PV

Ceph支持Kubernetes

使用 Ceph 支持 Kubernetes,是否满足需求?

  1. 独立使用的PV

    Ceph RBD支持即可

  2. 支持多客户端同时读写的PV

    CephFS / RBD + NFS

所以从我的角度理解:Ceph是可以满足Kubernetes对存储的需求的。

但 Kubernetes 的同事却坚持 Ceph 不能满足需求支持多客户端同时读写的PV,要使用 Glusterfs 。Why?

分析

这个事情在后来我与本地熟悉 Kubernetes 的同事详细沟通后,才终于弄明白之前的隔阂和问题所在。

下面从两个人所熟悉的知识领域来分析下问题。

volume概念

存储角度

首先说下在存储领域的volume含义,在存储领域也工作了快十年了,以为之前做过NAS和SAN存储,提起volume,我的印象还是一个卷,一个块设备。

熟悉存储的都知道,块设备是没法做到支持多客户端同时读写的,必须通过分布式文件系统来实现。所以提到volume,我就明确的表示它不会支持多客户端同时读写。

在网上搜索了下volume的定义,有下面几个不同的说法:

  1. storage volume

    A storage volume is an identifiable unit of data storage. It can be a removable hard disk, but it does not have to be a unit that can be physically removed from a computer or storage system.

    参考:http://searchstorage.techtarget.com/definition/volume

  2. LUN与volume的描述

    这个描述,与我理解的volume不一致 :(

    LUN是对存储设备而言的,volume是对主机而言的。
    LUN相对于主机来讲就是一个“物理硬盘”,与C盘D盘所在IDC或SCSI硬盘的性属是相同的。在该“物理硬盘”上创建一个或多个分区,再创建文件系统,才可以得到一个VOLUME。此时VOLUME相对于主机是一个逻辑设备。
    http://blog.csdn.net/liukuan73/article/details/45506441

    ==我不赞同上述文章里的说法!后面介绍的才是正确的==

    可以参考这里的介绍,更加可靠些:

    A volume normally refers to a “disk” created via a “volume manager” such as Veritas or a volume created by an operating system such as Windows NT.
    A LUN refers to a “logical unit number” presented to a host as ==a SCSI ID==. (i.e., LUN number 1 specifies SCSI ID 1 on that port. Therefore, the term volume can be considered software based and LUN considered hardware based.
    http://searchstorage.techtarget.com/answer/The-difference-between-volume-and-a-LUN

    在另一篇文章里也图形化描述了LUN和volume的区别:
    difference of volume and lun

    参考:https://jmetz.com/2016/11/whats-the-difference-between-a-lun-and-a-volume/

  3. Glusterfs volume

    Glusterfs里对volume的说明

    A volume is a logical collection of bricks where each brick is an export directory on a server in the trusted storage pool.

  4. 其他

    在LVM和openstack里,volume的概念则与SAN中的一致,都是块设备。

==所以,以后提到volume还是要看具体的应用场景!!!==

Kubernetes角度

在 Kubernetes 的官网上有这么一段话:

At its core, a volume is just a directory, possibly with some data in it, which is accessible to the containers in a pod. How that directory comes to be, the medium that backs it, and the contents of it are determined by the particular volume type used.

参考: https://kubernetes.io/docs/concepts/storage/volumes/#background

所以从上面可知,这里的volume是指后端存储提供的一个目录。

若volume指一个后端存储提供的目录,那是否支持多客户端同时读写,就看后端提供该目录的实现了。

provisioning概念

存储角度

存储里有storage provisioning概念,storage provisioning指的是分配空间的处理过程,通常这种空间是服务器磁盘空间,通过存储自动配置可以优化存储局域网(SAN)的性能,分为fat-provisioningthin-provisioning两种。

  1. fat-provisioning

    预先分配,底层存储会预留出对应请求的存储空间。

  2. thin-provisioning

    实时分配(也称为精简分配),底层存储会根据实时需求动态分配存储空间,而不预先预留出存储空间。

    有这么一段介绍:

    Thin provisioning (TP) is a method of optimizing the efficiency with which the available space is utilized in storage area networks (SAN).

所以存储角度说的provisioning,是SAN系统相关的,不是文件系统相关的。

Kubernetes角度

在 Kubernetes 里,提出Dynamic Provisioning的概念,是在Storageclass里提到的,介绍如下:

Dynamic

When none of the static PVs the administrator created matches a user’s PersistentVolumeClaim, the cluster may try to dynamically provision a volume specially for the PVC. This provisioning is based on StorageClasses: the PVC must request a class and the administrator must have created and configured that class in order for dynamic provisioning to occur. Claims that request the class “” effectively disable dynamic provisioning for themselves.

大致就是用户不用配置很多个PV了,只需要配置好Storageclass,在PVC里指定Storageclass即可,这样 Kubernetes 会自动的从Storageclass里配置好的存储里动态分配出一个指定size的PV,把PVC绑定到PV上。

参考: http://blog.kubernetes.io/2016/10/dynamic-provisioning-and-storage-in-kubernetes.html

所以 Kubernetes 角度说的provisioning,其实是PV的动态分配,跟存储里的provisioning不一样。

同事当时说成fs provisioning,弄的我很困惑,存储里没有fs provisioning这一说

明确需求

经过上面的分析,我明确了同事对 Kubernetes 存储的需求是要支持:Storageclass的Dynamic Provisioning + ReadWriteMany

查看Kubernetes官方文档,各个后端存储的支持情况为:

PV

Volume Plugin ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStore - -
AzureFile
AzureDisk - -
==CephFS==
Cinder - -
FC -
FlexVolume -
Flocker - -
GCEPersistentDisk -
==Glusterfs==
HostPath - -
iSCSI -
PhotonPersistentDisk - -
Quobyte
NFS
==RBD== -
VsphereVolume - -
PortworxVolume -
ScaleIO -
StorageOS - -

StorageClasses

Volume Plugin Internal Provisioner
AWSElasticBlockStore
AzureFile
AzureDisk
==CephFS== -
Cinder
FC -
FlexVolume -
Flocker
GCEPersistentDisk
==Glusterfs==
iSCSI -
PhotonPersistentDisk
Quobyte
NFS -
==RBD==
VsphereVolume
PortworxVolume
ScaleIO

对比上面可以得知,Ceph提供的RBD和CephFS都不能满足 Kubernetes 的Storageclass的Dynamic Provisioning + ReadWriteMany的需求,而Glusterfs则可以。

CephFS的Quota现在只有Ceph FUSE客户端支持,kernel client还不支持,这也许就是Storageclass还没支持CephFS的原因吧

支持原创