文章目录
六、Kubernetes Storage (Kubernetes 存储)
临时存储:emptydir
半持久化存储:hostpath
持久化存储:pvc,pv,nfs
分布式存储: glusterfs,rbd,cephfs,云存储(EBS,等)
查看K8s支持多少种存储: kubectl explain pods.spec.volumes
K8S的存储系统从基础到高级又大致分为三个层次:普通Volume,Persistent Volume 和动态存储供应。
1.Volume
K8s中的卷寿命与封装它的pod相同。卷比pod中所有容器的生命周期都要长,当这个容器重启时数据仍然可以保存。Pod不存在,卷也不复存在
-
容器中的Volume
容器的 Volume,其实就是将一个宿主机上的目录,跟一个容器里的目录绑定挂载在了一起。
-
持久化 Volume
宿主机上的目录,具备“持久性”。即:这个目录里面的内容,既不会因为容器的删除而被清理掉,也不会跟当前的宿主机绑定。这样,当容器被重启或者在其他节点上重建出来之后,它仍然能够通过挂载这个 Volume,访问到这些内容。
卷类型
empityDir
hostPath
local
nfs
iscsi
persistentVolume
PersistentVolumeClain
projectd
rbd
secret
vsphereVolume
2.PV(Persistent Volume)
PV 描述的是持久化存储卷,主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。
通常由运维人员创建
- 例子1
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.217.149
path: "/"
2.1 PV访问模式
PV可以以资源提供者支持的方式挂载到主机上。供应商具有不同的功能,每个PV访问模式都将被设置为该卷支持的特定模式。例如NFS可以支持多个读写客户端,但特定的NFS PV可能以只读方式导出到服务器上,每个PV都有一套自己的用来描述特定功能的访问模式。
- ReadwriteOnce(RWO) 该卷可以被单个节点以读写模式挂载
- ReadOnlyMany(ROX) 该卷可以被多个节点以只读模式挂载
- ReadWriteMany(ROX) 该卷可以被多个节点以读写模式挂载
2.2 PVC(Persistent Volume Claim)
PVC是用户存储的请求。描述的则是Pod所希望使用的持久化存储的属性。比如Volume存储的大小、可读写权限等等。
通常由开发人员创建
- 例子2
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
2.3 绑定
用户根据所需存储空间大小和访问模式创建(或在动态部署中已创建)一个PVC。Kubernetes的Master节点循环监控新产生的PVC,找到与之匹配的PV(如果有的话),并把他们绑定在一起。动态配置时,循环会一直将PV与这个PVC绑定,直到PV完全匹配PVC。避免PVC请求和得到的PV不一致。绑定一旦形成,PersistentVolumeClaim绑定就是独有的,不管是使用何种模式绑定的。
如果找不到匹配的volume,用户请求会一直保持未绑定状态。在匹配的volume可用之后,用户请求将会被绑定。
Volume Controller:管理多个控制循环,将PV与PVC进行绑定(PV名称写入PVC对象的spec.volumeName)
-
第一个条件,当然是 PV 和 PVC 的 spec 字段。比如,PV 的存储(storage)大小,就必须满足 PVC 的要求。
-
第二个条件,则是 PV 和 PVC 的 storageClassName 字段必须一样。
-
例子3
apiVersion: v1
kind: Pod
metadata:
name: nginx-nfs
labels:
role: web-frontend
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
2.4 处理PV流程
2.4.1 两阶段
1)第一阶段Attach
- 当一个 Pod 调度到一个节点上之后,kubelet 就要负责为这个 Pod 创建它的 Volume 目录。默认情况下,kubelet 为 Volume 创建的目录是如下所示的一个宿主机上的路径
/var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>
- 接下来,kubelet 要做的操作就取决于你的 Volume 类型了
gcloud compute instances attach-disk <虚拟机名字> --disk <远程磁盘名字>
2)第二阶段Mount
Attach 阶段完成后,为了能够使用这个远程磁盘,kubelet 还要进行第二个操作,即:格式化这个磁盘设备,然后将它挂载到宿主机指定的挂载点上。
- 通过lsblk命令获取磁盘设备ID
- 格式化成ext4格式:sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard
- 挂载到挂载点:sudo mkdir -p /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>
将宿主机目录与pod定义VolumeMount目录关联
docker run -v /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>
2.5 PV生命周期
一个PV创建完后状态会变成Available,等待被PVC绑定。一旦被PVC邦定,PV的状态会变成Bound,就可以被定义了相应PVC的Pod使用。Pod使用完后会释放PV,PV的状态变成Released。变成Released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略,Retain、Delete 和 Recycle。Retain就是保留现场,K8S什么也不做,等待用户手动去处理PV里的数据,处理完后,再手动删除PV。Delete 策略,K8S会自动删除该PV及里面的数据。Recycle方式,K8S会将PV里的数据删除,然后把PV的状态变成Available,又可以被新的PVC绑定使用。
Provisioning ——-> Binding ——–>Using——>Releasing——>Reclaiming
2.5.1 Provisioning
这里有两种PV的提供方式:静态或者动态
Static
集群管理员创建多个PV。 它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可用于消费。
Dynamic
当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses:PVC必须请求一个类,