一、存储分类¶
存储一般分为三类:
- 文件存储:一些数据可能需要被多个节点使用,比如用户的头像、用户上传的文 件等,实现方式:NFS、NAS、FTP、CephFS等。
- 块存储:一些数据只能被一个节点使用,或者是需要将一块裸盘整个挂载使用, 比如数据库、Redis等,实现方式:Ceph、GlusterFS、公有云。
- 对象存储:由程序代码直接实现的一种存储方式,云原生应用无状态化常用的实 现方式,实现方式:一般是符合S3协议的云存储,比如AWS的S3存储、Minio、七 牛云等。
二、使用Ceph块存储¶
块存储一般用于一个 Pod 挂载一块存储使用,相当于一个服务器新挂了一个盘,只给一个应用使用。
2.1 先决条件¶
- 有一个 Rook 集群
- 在 Rook 可以配置存储之前,需要创建StorageClass和CephBlockPool
- 每个 OSD 必须位于不同的节点上,因为 被failureDomain设置为
host且 被replicated.size设置为3
2.2 创建StorageClass和CephBlockPool¶
1.根据自己需要修改storageclass.yaml(下面的文件是去掉注释进行展示)
$ cd /root/rook/deploy/examples/csi/rbd
$ vim storageclass.yaml
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph # namespace:cluster
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
上面参数说明:
- name: 定义了一个名为
replicapool的块池 - namespace: 属于
rook-ceph命名空间 - failureDomain: 使用主机作为故障域(
failureDomain: host) - replicated:3个副本的复制块池
- provisioner: 指定用于创建和管理卷的 CSI(Container Storage Interface)插件的提供者,这里使用 Rook-Ceph RBD CSI 插件来创建和管理与该 StorageClass 关联的持久卷。
- parameters:指定了一些特定于Rook-Ceph的参数
- clusterID: 指定要使用的Ceph集群的名称。在示例中,设置为
rook-ceph表示使用名为rook-ceph的Ceph集群。 - pool: 指定要使用的Ceph块池的名称。在示例中,设置为
replicapool表示使用名为replicapool的Ceph块池 - imageFormat: 指定创建的RBD镜像的格式。在示例中,设置为
2表示使用RBD镜像格式版本2 - imageFeatures: 指定RBD镜像的特性。在示例中,设置为
layering表示启用镜像分层特性 - csi.storage.k8s.io/provisioner-secret-name: 指定CSI插件使用的用于存储Ceph凭据的Kubernetes Secret的名称
- csi.storage.k8s.io/provisioner-secret-namespace: 指定包含上述凭据的Kubernetes Secret所在的命名空间
- csi.storage.k8s.io/controller-expand-secret-name: 指定CSI插件使用的用于扩展卷时的控制器凭据的Kubernetes Secret的名称
- csi.storage.k8s.io/controller-expand-secret-namespace: 指定包含上述控制器凭据的Kubernetes Secret所在的命名空间
- csi.storage.k8s.io/node-stage-secret-name: 指定CSI插件使用的用于节点级别挂载卷时的凭据的Kubernetes Secret的名称
- csi.storage.k8s.io/node-stage-secret-namespace: 指定包含上述节点凭据的Kubernetes Secret所在的命名空间
- csi.storage.k8s.io/fstype: 指定要在挂载卷时使用的文件系统类型。在示例中,设置为
ext4表示使用ext4文件系统 - allowVolumeExpansion: 指定是否允许卷进行扩展。在示例中,设置为
true表示允许扩展卷的大小 - reclaimPolicy: 指定在卷被释放后如何处理底层存储资源。在示例中,设置为
Delete表示删除底层存储资源
说明:我这里没有做修改,可以根据自己的需求进行修改
如果已将 Rook 运算符部署在“rook-ceph”以外的命名空间中,需要更改配置程序中的前缀以匹配目前使用的命名空间。例如,如果 Rook 操作符在名称空间“my-namespace”中运行,则配置程序值应为“my-namespace.rbd.csi.ceph.com”。
provisioner: my-namespace.rbd.csi.ceph.com
2.创建StorageClass和CephBlockPool
$ cd /root/rook/deploy/examples/csi/rbd
$ k create -f storageclass.yaml
3.查看创建的 cephblockpool 和 storageClass
[root@k8s-master01 rbd]# k get cephblockpool -n rook-ceph
NAME PHASE
replicapool Ready
[root@k8s-master01 rbd]# k get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 3m12s
4.登录Ceph的Dashboard查看新创建的 cephblockpool ,观察到已成功创建

2.3 挂载测试¶
这里针对Deployment 和Statefulset分别进行演示。
2.3.1 Deployment无状态部署¶
创建一个示例应用程序来使用 Rook 通过经典的 wordpress 和 mysql 应用程序配置的块存储。这两个应用程序都将利用 Rook 提供的块卷。
1.修改mysql.yaml ,设置请求存储大小为5G,设置镜像为国内镜像,即将mysql:5.6修改为registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.6
$ cd /root/rook/deploy/examples
$ vim mysql.yaml

2.修改mysql.yaml ,设置请求存储大小为5G,设置镜像为国内镜像,即将wordpress:4.6.1-apache修改为registry.cn-hangzhou.aliyuncs.com/abroad_images/wordpress:4.6.1-apache

3.启动 mysql 和 wordpress
$ cd /root/rook/deploy/examples
$ k create -f mysql.yaml -f wordpress.yaml
4.查看PVC
[root@k8s-master01 examples]# k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound pvc-8133aa82-b1a8-48bc-a4e7-8a195f8d72bd 5Gi RWO rook-ceph-block 5m16s
wp-pv-claim Bound pvc-04730a5e-6d78-46fd-aba8-3133f9b1a83e 5Gi RWO rook-ceph-block 5m16s
5.等待这两个Pod完全起来后,获取 wordpress 应用程序的集群 IP
[root@k8s-master01 examples]# kubectl get po
NAME READY STATUS RESTARTS AGE
wordpress-54f687fd7c-ppbwk 1/1 Running 0 8m31s
wordpress-mysql-64c9849bd6-6jqls 1/1 Running 0 8m31s
[root@k8s-master01 examples]# kubectl get svc wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress LoadBalancer 10.0.99.72 <pending> 80:30458/TCP 9m35s
说明:这里因为没有外部IP地址访问wordpress,所以不做验证
2.3.2 Statefulset有状态部署¶
上面的演示类型为deployment,如果是 statefulset,只需要将 volumeTemplateClaim 里面的 Claim 名称改为 StorageClass 名称即可动态创建 Pod。在 StatefulSet 的 YAML 文件中,将 volumeClaimTemplates 的 Claim 名称改为 StorageClass 的名称。
1.定义一个yaml
$ vim sts-sc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # 必须匹配 .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # 默认值是 1
minReadySeconds: 10 # 默认值是 0
template:
metadata:
labels:
app: nginx # 必须匹配 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/zq-demo/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
注意:这里的名称应该与步骤3.2中创建的 StorageClass 的名称保持一致。
2.创建该应用
$ k create -f sts-sc.yaml
3.查看应用创建情况
[root@k8s-master01 ~]# k get po -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 52s
web-1 1/1 Running 0 32s
web-2 1/1 Running 0 11s
[root@k8s-master01 ~]# k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None <none> 80/TCP 103s
2.4 配置清除¶
下面清除上面演示配置
$ cd /root/rook/deploy/examples
$ kubectl delete -f wordpress.yaml
$ kubectl delete -f mysql.yaml
$ kubectl delete -f sts-sc.yaml
$ kubectl delete pvc www-web-0 www-web-1 www-web-2
$ kubectl delete pv pv-hostpath pv-nfs
$ kubectl delete -n rook-ceph cephblockpools.ceph.rook.io replicapool
$ kubectl delete storageclass rook-ceph-block