[从零开始学Kubernetes] 8.Kubernetes存储类型以及持久化存储

在Kubernetes中,使用Volume提供容器的共享存储,但是与Docker设计不同的是,Volume的生命周期与Pod一致,即:Pod在Volume就在,Pod被删除,Volume根据其类型决定删不删数据。

Volume Plugins

插件分类主要用途卷插件数据是否会随Pod删除而删除
临时存储主要用于存储一些临时文件,类似于在操作系统中创建的tempDirEmptyDir
本地存储用于将一些K8s中定义的配置通过Volume映射到容器中使用ConfigMap/DownwardAPI/Secret
本地存储使用宿主机上的存储资源HostPath/Local
自建存储平台自己搭建的存储平台CephFS/Ginder/GlusyerFS/NFS/RBD
云厂商插件云厂商提供的插件awsElasticBlockStore/AzureDisk/AzureFile/GCEersisenDisk
HostPath

HostPath中定义的是宿主机的真实的绝对路径,就会存在同一个节点上多个Pod共用一个HostPath的情况,可能会造成数据混乱,读写异常等等。

例子

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-demo
  namespace: demo
spec:
  containers:
  - image: nginx:1.19.2
    name: container-demo
    volumeMounts:
      - mountPath: /test-pd
        name: hostpath-volume
  volumes:
  - name: hostpath-volume 
    hostPath:
      path: /data  # 对应宿主机上的绝对路径
      type: Directory # 可选字段,默认是 Directory

持久化存储-PV(Persistent Volume)

Kubernetes 中引入了一个专门的对象 Persistent Volume(简称 PV),将计算和存储进行分离,可以使用不同的控制器来分别管理。

通过 PV,可以和 Pod 自身的生命周期进行解耦。一个 PV 可以被几个 Pod 同时使用,即使 Pod 被删除后,PV 这个对象依然存在,其他新的 Pod 依然可以复用

PV创建分为静态和动态,如图
PV的创建方式

静态PV

管理员通过手动的方式在后端存储平台上创建好对应的 Volume,然后通过 PV 定义到 Kubernetes 中去。开发者通过 PVC 来使用。

例子

PV创建

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume # pv 的名字
  labels: # pv 的一些label
    type: local
spec:
  storageClassName: manual
  capacity: # 该 pv 的容量
    storage: 10Gi
  accessModes: # 该 pv 的接入模式
    - ReadWriteOnce
  hostPath: # 该 pv 使用的 hostpath 类型,还支持通过 CSI 接入其他 plugin
    path: "/mnt/data"

这里定义了一个名为task-pv-volume的 PV,PV 是集群的资源,并不属于某个 namespace。其中storageClassName这个字段是某个StorageClass对象的名字。

其中,accessMode可以指定PV的访问挂载方式

  • ReadWriteOnce(RWO)表示该卷只可以以读写方式挂载到一个 Pod 内;
  • ReadOnlyMany( ROX)表示该卷可以挂载到多个节点上,并被多个 Pod 以只读方式挂载;
  • ReadWriteMany(RWX)表示卷可以被多个节点以读写方式挂载供多个 Pod 同时使用。

PVC创建

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
  namespace: demo
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

创建好了以后,Kubernetes 会为 PVC 匹配满足条件的 PV。我们在 PVC 里面指定storageClassName为 manua,这个时候就只会去匹配storageClassName同样为 manual 的 PV。一旦发现合适的 PV 后,就可以绑定到该 PV 上。

PV 一般会有如下五种状态:

  • Pending 表示目前该 PV 在后端存储系统中还没创建完成;

  • Available 即闲置可用状态,这个时候还没有被绑定到任何 PVC 上;

  • Bound 就像上面例子里似的,这个时候已经绑定到某个 PVC 上了;

  • Released 表示已经绑定的 PVC 已经被删掉了,但资源还未被回收掉;

  • Failed 表示回收失败。

同样,对于 PVC 来说,也有如下三种状态:

  • Pending 表示还未绑定任何 PV;

  • Bound 表示已经和某个 PV 进行了绑定;

  • Lost 表示关联的 PV 失联。

在Pod中使用PV

apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
  namespace: demo
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx:1.14.2
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

静态 PV 最大的问题就是使用起来不够方便,都是管理员提前创建好一批指定规格的 PV,无法做到按需创建。使用过程中,经常会遇到由于资源大小不匹配,规格不对等,造成 PVC 无法绑定 PV 的情况。同时还会造成资源浪费,比如一个只需要 1G 空间的 Pod,绑定了 10G 的 PV。

动态PV

例子
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-rbd-sc
  annotation:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/rbd # 必填项,用来指定volume plugin来创建PV的物理资源
parameters: # 一些参数
  monitors: 10.16.153.105:6789
  adminId: kube
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret-user
  userSecretNamespace: default
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"

你可以通过注释storageclass.kubernetes.io/is-default-class来指定默认的 StorageClass。这样新创建出来的 PVC 中的 storageClassName 字段就会自动使用默认的 StorageClass。

首先我们定义了一个 StorageClass。当用户创建好 Pod 以后,指定了 PVC,这个时候 Kubernetes 就会根据 StorageClass 中定义的 Provisioner 来调用对应的 plugin 来创建 PV。PV 创建成功后,跟 PVC 进行绑定,挂载到 Pod 中使用。

StatefulSet 中使用 PV 和 PVC

例子

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

官方文档:

配置Pod以使用PV作为存储

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值