目录
所有的中间层都是为了解耦
中间件(英语:Middleware),又译中间件、中介层,是提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。在现代信息技术应用框架如 Web 服务、面向服务的体系结构等项目中应用比较广泛。如数据库、Apache 的 Tomcat ,IBM 公司的 WebSphere ,BEA 公司的 WebLogic 应用服务器,东方通公司的 Tong 系列中间件,以及 Kingdee 公司的等都属于中间件。
PV,PVC简介
1.1 介绍
管理存储是管理计算的一个明显问题。该PersistentVolume子系统为用户和管理员提供了一个API,用于抽象如何根据消费方式提供存储的详细信息。为此,我们引入了两个新的API资源:PersistentVolume和PersistentVolumeClaim
PersistentVolume(PV)是集群中由管理员配置的一段网络存储。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统。
PersistentVolumeClaim(PVC)是由用户进行存储的请求。 它类似于pod。 Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)。
虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是PersistentVolumes对于不同的问题,用户通常需要具有不同属性(例如性能)。群集管理员需要能够提供各种PersistentVolumes不同的方式,而不仅仅是大小和访问模式,而不会让用户了解这些卷的实现方式。对于这些需求,有StorageClass 资源。
StorageClass为管理员提供了一种描述他们提供的存储的“类”的方法。 不同的类可能映射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。 Kubernetes本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为“配置文件”。
PVC和PV是一一对应的。
1.2 生命周期
PV是群集中的资源。PVC是对这些资源的请求,并且还充当对资源的检查。PV和PVC之间的相互作用遵循以下生命周期:
Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling
- 供应准备Provisioning---通过集群外的存储系统或者云平台来提供存储持久化支持。
- - 静态提供Static:集群管理员创建多个PV。 它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可用于消费
- - 动态提供Dynamic:当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses:PVC必须请求一个类,并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有效地为自己禁用动态配置。
- 绑定Binding---用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态。
- 使用Using---用户可在pod中像volume一样使用pvc。
- 释放Releasing---用户删除pvc来回收存储资源,pv将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他pvc使用。
- 回收Recycling---pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。
- - 保留策略:允许人工处理保留的数据。
- - 删除策略:将删除pv和外部关联的存储资源,需要插件支持。
- - 回收策略:将执行清除操作,之后可以被新的pvc使用,需要插件支持。
注:目前只有NFS和HostPath类型卷支持回收策略,AWS EBS,GCE PD,Azure Disk和Cinder支持删除(Delete)策略。
挂载磁盘分两步:
Attach,为虚拟机挂载远程磁盘的操作。kubelet 为 Volume 创建目录,并绑定远程存储。
Mount,磁盘设备格式化并挂载到 Volume 宿主机目录的操作
如果你的 Volume 类型是远程文件存储(比如 NFS)的话,kubelet跳过“第一阶段”(Attach)的操作
1.4 PV卷阶段状态
- Available – 资源尚未被claim使用
- Bound – 卷已经被绑定到claim了
- Released – claim被删除,卷处于释放状态,但未被集群回收。
- Failed – 卷自动回收失败
静态PV,PVC创建和使用
1. 创建pv存储,实际的存储资源
[root@m3 test]# vim pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
storageClassName: nfs1
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.70.94
path: "/data/nfs/v1"
[root@m3 test]# kubectl apply -f pv-nfs.yaml
persistentvolume/pv-nfs created
[root@m3 test]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 1Gi RWX Retain Available nfs1 41s
2. PVC 描述的,则是 Pod 所希望使用的持久化存储的属性。
[root@m3 test]# vim pvc-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100M
storageClassName: nfs1
[root@m3 test]# kubectl apply -f pvc-nfs.yaml
persistentvolumeclaim/pvc-nfs created
Volume Controller:专门处理持久化存储的控制器
PersistentVolumeController :处理pv和pvc
PersistentVolumeController 会不断地查看当前每一个 PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与这个“单身”的 PVC 进行绑定。这样,Kubernetes 就可以保证用户提交的每一个 PVC,只要有合适的 PV 出现,它就能够很快进入绑定状态
PVC和PV绑定条件:
- storageClassName 字段一致
- PV 满足 PVC 的 spec 字段
[root@m3 test]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pvc-nfs 1Gi RWX nfs1 2m34s
[root@m3 test]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 1Gi RWX Retain Bound default/pvc-nfs nfs1 6m26s
3.pvc资源的使用
[root@m3 test]# vim pvc-nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pvc-nfs-pod
spec:
containers:
- name: web
image: nginx:1.7.9
volumeMounts:
storageClassName- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs1
[root@m3 test]# kubectl apply -f pvc-nfs-pod.yaml
pod/pvc-nfs-pod created
访问nginx进行验证
[root@m3 test]# kubectl get pod -o wide | grep pvc-nfs-pod
pvc-nfs-pod 1/1 Running 0 3m13s 10.100.130.101 s3 <none> <none>
[root@m3 test]# curl http://10.100.130.101
hello nfs
动态持久化存储StorageClass
我们学习了 PV 和 PVC 的使用方法,但是前面的 PV 都是静态的,什么意思?就是我要使用的一个 PVC 的话就必须手动去创建一个 PV,我们也说过这种方式在很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于 StatefulSet 类型的应用简单的来使用静态的 PV 就很不合适了,这种情况下我们就需要用到动态 PV,也就是我们今天要讲解的 StorageClass。
而 StorageClass 对象的作用,其实就是创建 PV 的模板。具体地说,StorageClass 对象会定义如下两个部分内容:
第一,PV 的属性。比如,存储类型、Volume 的大小等等。
第二,创建这种 PV 需要用到的存储插件。比如,Ceph 等等。
nfs创建pv并自动绑定pvc
1.创建ServiceAccount账号
创建账号,nfs-client-provisioner服务启动时需要以此账号的权限启动和运行
[root@m3 nfs]# cat nfs-client-provisioner.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: eip-nfs-client-provisioner
namespace: kube-system
[root@m3 nfs]# kubectl apply -f nfs-client-provisioner.yaml
serviceaccount/nfs-client-provisioner created
2.创建集群role角色
[root@m3 nfs]# cat nfs-client-provisioner-runner.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-runner
namespace: kube-system
rules:
- apiGroups:
- ''
resources:
- persistentvolumes
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ''
resources:
- persistentvolumeclaims
verbs: [ get, list, watch, update ]
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs: [ get, list, watch ]
- apiGroups:
- ''
resources:
- events
verbs: [ create, update, patch ]
[root@m3 nfs]# kubectl apply -f nfs-client-provisioner-runner.yaml
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
3.使role角色和ServiceAccount账号绑定
[root@m3 nfs]# cat run-nfs-client-provisioner.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: run-nfs-client-provisioner
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nfs-client-provisioner-runner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
[root@m3 nfs]# kubectl apply -f run-nfs-client-provisioner.yaml
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
4.创建role角色,赋予权限
[root@m3 ~]# cat leader-locking-nfs-client-provisioner.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
rules:
- apiGroups:
- ''
resources:
- endpoints
verbs:
- get
- list
- watch
- create
- update
- patch
[root@m3 ~]# kubectl apply -f leader-locking-nfs-client-provisioner.yaml
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
5. 将role角色和ServiceAccount绑定
[root@m3 ~]# cat leader-locking-nfs-client-provisioner-bind.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: leader-locking-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
[root@m3 ~]# kubectl apply -f leader-locking-nfs-client-provisioner-bind.yaml
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
6.创建nfs 工作端
[root@m3 ~]# vim nfs-nfs3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nfs-nfs3
name: nfs-nfs3
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: nfs-nfs3
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-nfs3
spec:
containers:
- env:
- name: PROVISIONER_NAME
value: nfs-nfs3
- name: NFS_SERVER
value: 192.168.70.120
- name: NFS_PATH
value: /data/nfs/v3
image: 'quay.io/external_storage/nfs-client-provisioner:v3.1.0-k8s1.11'
name: nfs-client-provisioner
volumeMounts:
- mountPath: /persistentvolumes
name: nfs-client-root
serviceAccountName: eip-nfs-client-provisioner
volumes:
- name: nfs-client-root
nfs:
path: /data/nfs/v3
server: 192.168.70.120
[root@m3 ~]# kubectl apply -f nfs-nfs3.yaml
deployment.apps/nfs-nfs3 created
7. 创建nfs StorageClass
[root@m3 nfs]# vim nfs-StorageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
k8s.eip.work/storageType: nfs_client_provisioner
name: nfs3
parameters:
archiveOnDelete: 'false'
provisioner: nfs-nfs3
reclaimPolicy: Delete
volumeBindingMode: Immediate
[root@m3 nfs]# kubectl apply -f nfs-StorageClass.yaml
storageclass.storage.k8s.io/nfs3 created
[root@m3 nfs]# kubectl get pod -n kube-system | grep nfs3
nfs-nfs3-66f4c9bcd5-5fd2x 1/1 Running 0 3m21s
reclaimPolicy回收策略: Delete立刻删除 Retain pvc删除后保留磁盘
volumeBindingMode绑定策略: Immediate立即绑定,WaitForFirstConsumer第一次使用时绑定
8.进行nfs测试
[root@m3 nfs]# cat nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2M
storageClassName: nfs3
[root@m3 nfs]# kubectl apply -f nfs-pvc.yaml
persistentvolumeclaim/pvc-nfs created
[root@m3 ~]# kubectl get pvc | grep pvc-nfs
pvc-nfs Bound pvc-4773b235-aa7c-4c8e-bf81-85c97e0e28f6 2M RWX nfs3 78s
[root@m3 ~]# kubectl get pv | grep pvc-nfs
pvc-4773b235-aa7c-4c8e-bf81-85c97e0e28f6 2M RWX Delete Bound default/pvc-nfs nfs3 88s