2. 了解StorageClass
StorageClass(存储类)是用于定义在Kubernetes集群中创建持久卷(Persistent Volume)的类型和行为的对象。在Kubernetes中,持久卷是一种抽象层,用于将存储资源(例如磁盘)与容器解耦,从而实现数据的持久性和可靠性。
StorageClass定义了不同类型的存储提供商、存储卷的属性和行为,以及如何将这些存储卷绑定到动态分配的持久卷请求。通过使用StorageClass,Kubernetes管理员可以为不同的应用程序或工作负载配置不同的存储策略。
每个 StorageClass 都包含 provisioner
、parameters
和 reclaimPolicy
字段, 这些字段会在 StorageClass 需要动态制备 PersistentVolume 时会使用到。
StorageClass可以定义以下属性:
- volumeBindingMode:指定持久卷绑定模式
- "Immediate"表示持久卷将立即绑定到声明的请求
- "WaitForFirstConsumer"表示持久卷将等待第一个消费者使用它之前才进行绑定
- provisioner:指定用于创建持久卷的存储提供商,不同的存储提供商可能具有不同的实现和配置要求。
- reclaimPolicy:指定在释放持久卷时应如何处理底层存储资源
- Retain(保留)
- Delete(删除)
- Recycle(回收)
- AllowVolumeExpansion:是否允许对PV进行扩容,需要后端存储支持,一般不推荐进行缩容。
Tips:还有其余参数可以看看Rook文档!
注意:StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。
3. StorageClass解决什么
使用PV、PVC能屏蔽一些存储使用的细节,简化存储使用的复杂度。但k8s集群很多时,技术人员管理不过来,对于PV的创建也是一个很耗时、耗力的工作。规模大了,过多的PV难维护。
所以设计StorageClass(无命名空间隔离性)来进行自动管理PV的生命周期,比如创建、删除、自动扩容等。这样k8s管理员就无须浪费大量的时间在PV的管理中。
在Kubernetes中,管理员可以只创建StorageClass“链接”到后端不同的存储,比如Ceph、GlusterFS、OpenStack的Cinder、其他公有云提供的存储等。
之后有存储需求的技术人员,创建一个PVC指向对应的StorageClass即可,StorageClass会自动创建PV供Pod使用,也可以使用StatefulSet的volumeClaimTemplate自动分别为每个Pod申请一个PVC。
4. StorageClass实现方式
StorageClass的实现方式取决于Kubernetes集群所使用的存储插件和存储提供商。不同的存储插件和提供商可能有不同的实现细节和配置要求。
针对不同厂商的存储管理,k8s编写相应的代码。而不同厂商为了适配k8s,都会提供一个驱动(CSI或者Fiex Volume)安装到k8s集群中,然后StorageClass只需要配置该驱动即可,驱动器会代替StorageClass管理存储。
每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。
5. 使用ceph块存储
书写一个申请存储块的yaml文件
[root@k8s-master01 rook]# cat create-pv-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pv #pvc名称
spec:
storageClassName: rook-ceph-block #之前创建的StorageClass的名称
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
进行创建,然后查看pv、pvc,自动形成映射关系。流程就是创建 pvc 只需要指定 storageClassName,pvc 会连接刚才创建的 storageClass,然后动态创建 pv,然后连接到 ceph 创建对应的存储。
kubectl create -f create-pv-pvc.yaml
查看ceph就能看到一个新增的块存储,通过pv的yaml资源清单就能看出是对应关系。
创建一个Deployment挂载刚才创建的块存储进行使用
[root@k8s-master01 rook]# cat nginx-ceph.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-ceph
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-ceph
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html/ #挂载目录
volumes:
- name: storage #内部定义名称
persistentVolumeClaim:
claimName: nginx-pv #pvc名称
创建Deployment,进行curl,发现报错!这是因为我们挂载的目录上去。
进入到这个Pod中,创建测试文件并curl,没问题。
模拟Pod出现问题重新建了,访问没问题!
模拟删除Deployment,观察pv和pvc。重新创建Deployment,yaml中还是指的这个pvc名称,内容照样访问。
Tips:实验完删除Deployment和PV、PVC。
StatefulSet使用动态存储
按照下面格式进行创建即可。
[root@k8s-master01 rook]# cat sts-sc.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "rook-ceph-block"
resources:
requests:
storage: 1Gi
创建好StatefulSet,查看pv、pvc情况。
6. 创建共享文件系统存储
通过在 CRD 中指定元数据池、数据池和元数据服务器的所需设置来创建文件系统CephFilesystem,这里创建具有三个复制的元数据池和具有三个复制的单个数据池。
[root@k8s-master01 ceph]# pwd
/root/rook/cluster/examples/kubernetes/ceph
[root@k8s-master01 ceph]#
[root@k8s-master01 ceph]# kubectl create -f filesystem.yaml
查看创建情况,观察到已经成功创建。登录Ceph界面进行查看,其中myfs-data0用于存储数据,myfs-metadata代表元数据。
创建StorageClass
[root@k8s-master01 ceph]# cat /yaml/fs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-cephfs
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
clusterID: rook-ceph # 指定 Rook Ceph 集群的名称,也就是namespace:cluster
fsName: myfs #指定Rook CephFS文件系统的名称
pool: myfs-data0 #指定Rook CephFS文件系统所使用的存储池的名称
csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph # namespace:cluster
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph # namespace:cluster
csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph # namespace:cluster
reclaimPolicy: Delete #定义了 PVC 删除后对应 PV 的回收策略,这里设置为 Delete,表示删除 PVC 时同时删除对应的 PV。
allowVolumeExpansion: true #定义了是否允许对卷进行扩展
mountOptions:
创建并查看 storageClass
书写一个申请文件共享存储的yaml文件
[root@k8s-master01 rook]# cat create-pv-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-fs-pvc
spec:
storageClassName: rook-cephfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
进行创建,然后查看pv、pvc,自动形成映射关系。流程就是创建 pvc 只需要指定 storageClassName,pvc 会连接刚才创建的 storageClass,然后动态创建 pv,然后连接到 ceph 创建对应的存储。
kubectl create -f create-pv-pvc.yaml
创建一个Deployment进行挂载该存储到网站目录
[root@k8s-master01 rook]# cat nginx-ceph.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-ceph
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-ceph
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html/
volumes:
- name: storage
persistentVolumeClaim:
claimName: nginx-fs-pvc
创建并进入Pod,写一个测试文件。
kubectl create -f nginx-ceph.yaml
访问各Pod,测试!