kubernetes
  • Introduction
  • 安装
    • 组件端口
    • 二进制安装
    • Kubeadm
      • 安装单Master集群
      • 安装高可用集群(手动分发证书)
      • 安装高可用集群(自动上传证书)
      • 安装ETCD集群
      • 安装高可用集群(外部ETCD)
    • 启动参数解析
      • ETCD相关参数
  • 负载均衡
    • Service
    • Ingress
    • 安装MetalLB
    • Nginx-ingress-controller
      • 转发TCP与UDP服务
      • 启动参数
      • 自定义Nginx模板
  • 存储
    • Volume
    • PV与PVC
    • StorageClass
    • Local-PV
      • Static-Provisioner
    • 实践
      • Ceph-RBD
      • NFS
  • 有状态服务
    • Mysql实践
    • Operator
      • Etcd
      • Zookeeper
      • Mysql
  • 认证与授权
    • 认证
      • 实践
    • 授权
  • Helm
    • 安装
    • Chart
      • 依赖
    • Helm命令
    • Repository
  • 日志
  • 监控
    • Prometheus体系
      • Prometheus
        • 内置函数
        • 配置
          • 规则文件
        • PromQL
      • Exporter
        • Metrics
      • Grafana
        • 配置
      • AlertManager
        • 配置
    • 容器监控
      • Cadvisor的指标
      • k8s中部署Prom与Cadvisor
  • Istio
  • 资源预留
    • imagefs与nodefs
    • 总结
  • 集群联邦
    • 联邦DNS原理
    • 联邦DNS安装
    • 安装federation-v1
  • Other
    • ImagePullSecret
    • QOS
    • Apiserver的代理
    • 资源配额
Powered by GitBook
On this page
  • Volume
  • PV与PVC
  • StorageClass与PV的动态供给
  • 本文小结

Was this helpful?

存储

在k8s中有Volume、PV、PVC、StorageClass等众多与存储有关的概念,那么这些都是用来做什么的呢?为什么需要这么多的概念呢?本文将一一介绍它们。

Volume

Pod里面的数据是不持久的,当Pod被删掉后,Pod里面的数据也就不复存在,所以我们使用Volume来持久化Pod里面的数据。

常用的Volume的类型有HostPath、EmptyDir、NFS、RBD等等。以RBD为例,我们可以先在Ceph中创建一个RBD块:

$ rbd create kube/image1 --size 1024 --image-format 2 --image-feature layering

然后在Pod中就可以使用这个RBD块,这样,即使Pod被删或者Pod所在的主机挂掉,保存在RBD中的数据也不会丢,可以用它立马起一个新的容器。

PV与PVC

在上面《Volume》中,我们可以先在ceph集群中创建一个RBD块,然后在Pod直接使用这个块。但是直接使用Volume会有一些问题,我们考虑如下一个场景:

当一个k8s集群有多个租户,每个租户以命名空间相互隔离,每个租户想创建一个Mysql服务,并且想让数据持久化;如果使用Volume,那么此时k8s管理员先要在Ceph中创建若干RBD块,然后再告诉每个租户,你应该使用哪个Volume。

这种方式第一个问题就是,租户都知道了ceph集群的连接信息,要是删除了其他租户的RBD块怎么办?甚至删了ceph的所有数据怎么办?

假设租户都很好,不会做坏事,那按照这种方式,如果有一百个或一千个租户,管理员要创建一千个volume,然后分配下去,管理员还得记住哪一个volume分配给了哪一个租户,显然,这一种方法落地太难。

所以,k8s提出了PV与PVC的概念。对于上面的场景,k8s集群管理员可以先批量在ceph集群中建好RBD块(假设RBD块命名为image-1 to image-N),然后在k8s集群中批量创建PV,每个PV对应Ceph中的一个RBD块,如下:

由于PV是集群级别的资源(无命名空间),所以k8s集群管理员可以配置权限让租户无法看到这些PV,那么租户也就无法知道Ceph集群的信息。

如果租户A要持久化数据,首先需要创建如下一个PVC:

该PVC“说”自已需要一个存储为1Gi的PV,当创建好该PVC后,kube-controller-manager就会为该PVC寻找一个满足它的PV进行绑定(所谓绑定就是把PVC的spec.volumeName设置为PV的名字,把PV的spec.claimRef设置为PVC的相关内容)。当一个PV被某个PVC绑定后,便不能再被其他的PVC绑定。

然后,租户就可以在Pod中使用这个PVC:

通过PV与PVC,满足了租户持久化数据的需求,也防止了租户看到后端存储的敏感信息。

StorageClass与PV的动态供给

在上面的《PV与PVC》中,我们讲到kubernetes的管理员需要提前批量创建PV,使用者在使用时就只需要创建PVC,然后由kubernetes去匹配一个PV。这个操作还是有些复杂,kubernetes提供了一种PV的动态供给机制:StorageClass

StorageClass的核心功能就是:当使用者创建一个PVC时,kubernetes自动为该PVC创建一个PV并进行绑定。

接下来,我们给一个具体的例子,来介绍StorageClass,这里以RBD为例。(实践的全过程见下一节《RBD实践》)

首先,准备好一个Ceph集群然后在kubernetes集群中创建provisioner为rbd的StorageClass:

然后我们创建一个storageClassName为rbd的PVC

创建好该PVC之后,kubernetes便会自动创建一个PV与该PVC进行绑定

$ kubectl get pvc pvc-rbd
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-rbd   Bound    pvc-5d26aba6-7169-11e9-98c4-000c29483500   1Gi        RWO            rbd            9s

本文小结

至此,我们已经介绍完了为什么k8s中要引入Volume、PV与PVC、StorageClass这么多的概念。关于它们更为详细的介绍,请继续阅读后面的文章。

Previous自定义Nginx模板NextVolume

Last updated 5 years ago

Was this helpful?