什么是PVC

在一个Pod中使用Volume,只要加上spec.volumes字段就可以了。但是作为一个应用开发者,并不了解持久化项目是如何在k8s集群中搭建的,也不了解如何编写它们的volume定义文件。

关于 Volume 的管理和远程持久化存储的知识,不仅超越了开发者的知识储备,还会有暴露公司基础设施秘密的风险。

例如,一个声明了 Ceph RBD 类型 Volume 的 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: rbd
spec:
  containers:
    - image: kubernetes/pause
      name: rbd-rw
      volumeMounts:
      - name: rbdpd
        mountPath: /mnt/rbd
  volumes:
    - name: rbdpd
      rbd:
        monitors:
        - '10.16.154.78:6789'
        - '10.16.154.82:6789'
        - '10.16.154.83:6789'
        pool: kube
        image: foo
        fsType: ext4
        readOnly: true
        user: admin
        keyring: /etc/ceph/keyring
        imageformat: "2"
        imagefeatures: "layering"

不仅volumes字段对于非相关的人员不懂,还将存储服务器的地址、用户名、授权文件的位置都暴露给了所有的开发人员

k8s就引入了一组叫做Persistent Volume Claim(PVC)和Persistent Volume(PV)的API对象,大大降低用户使用和声明持久化Volume的门槛

PVC使用

PVC的使用非常简单,两步就可以完成。

第一步,定义一个PVC,声明想要的Volume的属性。

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pv-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

这里只有对PVC的描述,没有任何关于Volume的细节。因为对于开发人员来说,它关注的也就是这些属性,并不关系Volume的底层细节

第二步:在应用的Pod中,声明使用这个PVC:

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

这里只声明了使用的Volume的类型是PVC,指定其名字即可。完全不必关心Volume本身的定义。

工作原理

只要创建了PVC对象,k8s就会自动为它绑定一个符合提交的Volume,那么这些符合条件的Volume又是从哪里来的。

其实就是来自于运维人员维护的PV(Persistent Volume)对象。一个常见的PV对象的YAML文件:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv-volume
  labels:
    type: local
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  rbd:
    monitors:
    # 使用 kubectl get pods -n rook-ceph 查看 rook-ceph-mon- 开头的 POD IP 即可得下面的列表
    - '10.16.154.78:6789'
    - '10.16.154.82:6789'
    - '10.16.154.83:6789'
    pool: kube
    image: foo
    fsType: ext4
    readOnly: true
    user: admin
    keyring: /etc/ceph/keyring

k8s就会为刚创建的PVC对象绑定这个PV。PVC和PV的设计类似与接口和实现的思想

开发人员关注的是“接口”,而运维人员负责给“接口”绑定具体的实现。

这样就避免了向开发者暴露过多的存储系统细节而带来的隐患。也使得出现事故时可以更加容易定位问题和明确责任。


tags: 容器持久化存储 k8s