kubernetes云原生纪元:共享存储-PV&&PVC(上)

之前我们学习的都是无状态的服务,如果有状态的服务就非常麻烦,比如有的服务会把自己文件存放到自己服务器的目录上,如果直接嵌入到docker 上那个这个目录每次都会清空,没有创建一个容器磁盘空间都是全新的,可能有人会说用目录挂载,把目录挂载到宿主机上,设置好节点的亲和性就可以每次部署都部署到同一台服务器上不就行了吗?没错这样是可以的,但是缺点比较大,首先你绑定了一台机器,一旦这台机器挂了,应用处于不可用状态了,还有就是数据备份问题,但是上面的kubernetes都想到了,我们开始学习共享存储。

概念

PV

PVpersistentVolume的简写 ,persistentVolume是描述的是持久化数据卷。由管理员提供的网络存储的一部分。就像集群中的节点一样,PV也是集群中的一种资源。它也像Volume一样,是一种volume插件,但是它的生命周期却是和使用它的Pod相互独立的。PV这个API对象,捕获了诸如NFS、ISCSI、或其他云存储系统的实现细节。

小例子

远程共享存储

storage: 10Gi存储容量10g,

accessModes: accessModes:访问模式是ReadWriteOnce 意思是只有一个pod 使用这个pv,权限是读写,如果多个pod使用这个地方设置为ReadWriteMany

访问模式包括:
   ▷ ReadWriteOnce —— 该volume只能被单个节点以读写的方式映射
   ▷ ReadOnlyMany —— 该volume可以被多个节点以只读方式映射
   ▷ ReadWriteMany —— 该volume只能被多个节点以读写的方式映射

nfs:# kubernetes 提供的存储方式,

nfs远程目录地址 path: "/tmp" server: 172.22.1.2

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 10Gi  #存储容量10g
  accessModes: #  访问模式是ReadWriteOnce 意思是只有一个pod
    - ReadWriteOnce
  nfs: # kubernetes 提供的存储方式,
    path: "/tmp"
    server: 172.22.1.2

PVC

PVCPersistentVolumeClaim的简写,PersistentVolumeClaim是描述的一个pod所希望使用的持久化存储的需求,比如多少磁盘,内存大小,读写权限。

PVC必须和使用它的pod在同一个命名空间,集群发现pod命名空间的PVC,根据PVC得到其后端的PV,然后PV被映射到host中,再提供给pod

下面定义的是一个具有读写权限的并且只能由我独占ReadWriteOnce的一个有10g 空间大小的这样一个存储。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes: # 
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

这是一个pod对共享存储的需求和期望

PV && PVC 的绑定

PV和PVC都创建好了,这时候需要建立他们之间的绑定 ,PV要满足PVC的要求:

权重大小,读写权限,

PV和PVC stroageclass 的name 必须一致

满足这些PersistentVolumeConroller会发现匹配的PV和PVC,自动建立绑定关系,本质上是在 PVC的描述对象里把p V名字填进去

image-20200201145035924

绑定好就可以直接使用了,通过volume挂载persistentVolumeClaim指定PVC的名字

apiVersion: v1
kind: Pod
metadata:
  name: web-dev
spec:
  containers:
    - name: web-dev
      image: web:v1
      ports:
        - containerPort: 8080
      volumeMounts:
        - name: nfs
          mountPath: "/files"
  volumes:
    - name: nfs 
      persistentVolumeClaim: # 指定PVC的名字
        claimName: nfs

具体原理:

Pod里面声明一个PVC的名字,PVC里面描述了pod的需求权限,空间…并且PVC绑定了一个PV,PV描述具体存储的后端服务的地址,如何访问,都有哪些参数。

关于后端具体的存储服务和PV 的配置一般由集群管理员事先给我们配置好,剩下又kubernetes自己解决,包括运维定义的PVPVC建立绑定关系,把Pod 调度起来,把Pod 的volume 设置好 都是由kubernetes搞定的

设置volume首先是volume对应本地具体的目录,对于共享存储就不是一个目录,每种不同的共享存储服务,有不同处理过程,像nfs kubelt 会把这个目录挂载远程PV指定的位置,相当于执行mount命令,把主机的目录挂载nfs server 上,之后对于docker 来说并没有什么区别,还是用 -v参数把这个目录映射到容器里面,最终实现了这个共享存储。

image-20200201151431020

StorageClass

这个时候有很多POD需要共享存储,每次建立一个就需要让运维同学给我们配置一个PV,不用还得通知他得回收,这个代价太大了,kubernetes提供自动管理PV的机制叫做StorageClass。它的本质就是PV的模版。StorageClass自动创建PV

provisioner: kubernetes.io/aws-ebs #kubernetes内置存储插件的名字

parameters:#具体创建PV用到的参数

type: io1,zone: us-east-1d,iopsPerDB: "10“aws-ebs创建PV所用到的。如果换成其他存储插件,这些参数有所区别。每种插件都有自己所需要的参数。

例子

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: stroage-class-demo
provisioner: kubernetes.io/aws-ebs #kubernetes内置存储插件的名字
parameters: #具体创建PV用到的参数
  type: io1
  zone: us-east-1d
  iopsPerDB: "10“

有了StorageClass后PVC的配置

storageClassName: 指定StorageClass的名字,这样我使用kubeContro 去创建PVC的时候 kub ernetes会根据这个名字 找我刚才定义的StorageClass根据它自动创建一个大小10G的PV,然后建立起绑定关系。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: storage-class-demo 
  resources:
    requests:
      storage: 10Gi

StorageClass的设计要点

  • 每个PV和PVC都有StorageClass

    没有设置就会有一个默认空的StorageClass,手动创建PV也是可以指定StorageClass,PVC中指定相同名字的StorageClass ,kubernetes会自动建立绑定关系,并不在意StorageClass不需要真实存在,只要名字一样就可以。

  • StorageClass不需要真实存在

一张图概括:

存储插件:ceph…

PV :可以说集群管理员创建的也可以是同storageClass自动创建的PV,
storageClass必定只能对应一种类型的后端存储

image-20200201154011438

对应关系:一个POD可以使用多个PVC,一个PVC也可以同时给多个POD提供服务,一个PVC只能绑定一个PV,一个PV只能对应一种后端存储。

实践

我们这里用 GlusterFs做存储插件,使用GitHub gluster-kubernetes 这个项目,相关重要组件还有heketi

当然对我们基础环境也有一定的要求:

  • 三个**GlusterFS**的节点,每份数据有三个节点
  • 每个节点有个裸磁盘,没有经过分区的磁盘,**GlusterFS**基本要求,他会完全接管这块磁盘,实现更高效的管理数据

image-20200201155244215

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐