什么是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/keyringk8s就会为刚创建的PVC对象绑定这个PV。PVC和PV的设计类似与接口和实现的思想。
开发人员关注的是“接口”,而运维人员负责给“接口”绑定具体的实现。
这样就避免了向开发者暴露过多的存储系统细节而带来的隐患。也使得出现事故时可以更加容易定位问题和明确责任。