Rook是一个运行在Kubernetes集群中的开源云原生存储服务编排工具,为各种存储方案提供平台、框架和支持,将存储软件转变为自我管理、自我扩展和自我修复的存储服务,以便与云原生环境集成。Rook基于底层容器管理平台实现自动部署、启动、配置、分配(provisioning)、扩缩容、升级、迁移、灾难恢复、监控,以及资源管理等功能。
Rook初期专注于Kubernetes+Ceph。在0.8版本中,Rook已经变成Beta版。Rook目前支持Ceph、NFS、Minio Object Store和CockroachDB。
Rook出现前,在kubernetes中搭建并维护Ceph集群的非常复杂,Rook就是为此而生,使用Kubernetes分布式平台简化大量针对Ceph存储的操作和维护工作。
Rook是通过Operator实现这些。Kubernetes中的Operator其实就是对一个自定义的CRD资源及其控制器的封装。
目前,Rook是基于FlexVolume存储插件机制实现的。Rook整体架构如下图所示:
由图可知,Rook主要由3部分组成:
Rook的三个组件都集成在一个rook/ceph镜像中。rook的启动流程如下所示:
Rook的Operator启动后可以看到在rook-ceph-system
这个namespace下创建了与上面相对应的一些pod:
Ceph是一个分布式存储系统,支持文件、块、对象存储,在生产环境中被广泛应用。
使用rook部署ceph集群后,在rook-ceph
这个namespace下会启动如下一些pod:
分为以下几种类型:
即Ceph集群中的mon(monitor)组件,负责监控整个Ceph集群的运行状况。会启动quorum中指定个数的mon,一般集群中会有三个mon以保证集群的高可用。在创建集群时,Rook会:
即Ceph集群中的mgr(manager)组件,主要负责监控一些非paxos相关的服务(比如pg相关统计信息),这里的mgr是一个无状态服务,提供集群一些非paxos相关的监控指标。Rook除了启动mgr外,还负责配置其它两个mgr插件:
即Ceph集群的osd组件,集群的核心存储组件。
即Ceph集群的mds组件,是Ceph分布式文件系统的元数据服务器。一或多个mds 协作管理文件系统的命名空间、协调到共享osd集群的访问。当在集群中声明要一个共享文件系统时,Rook会:
创建的共享文件系统可以被集群中Pod使用。
即Ceph集群的rgw组件,为应用提供RESTful类型的对象存储接口。当在集群中声明要一个对象存储时,Rook会:
$ sudo mkdir /app/dcos/rook
$ wget https://github.com/rook/rook/archive/v0.8.3.zip && unzip v0.8.3.zip
--volume-plugin-dir
:这个参数告诉kubelet到哪里去找第三方存储插件,确保这个参数指定的目录有读写权限。不指定的话,默认值是
/usr/libexec/kubernetes/ kubelet-plugins/volume/exec/
。
--volume-plugin-dir
参数中的保持一致:$ cd rook-0.8.3/cluster/examples/kubernetes/ceph
$ vim operator.yaml
- name: FLEXVOLUME_DIR_PATH
value: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec"
$ vim rook-0.8.3/cluster/examples/kubernetes/ceph/cluster.yaml
dataDirHostPath: /app/dcos/rook/data
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/operator.yaml
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/cluster.yaml
cluster.yaml部署好后,一个ceph集群就创建好了。
1.operator.yaml中主要是一些自定义资源对象的定义(CRD),有:Cluster、Filesystem、ObjectStore、Pool、Volume;还创建了rook的三种组件Operator、Agent、Discover。
2.cluster.yaml中主要创建了一个Cluster(ceph集群)自定义资源对象(CR)
部署一个external的dashboard service,以nodePort的形式对外提供图形界面访问:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/dashboard-external.yaml
官方给出了一个toolbox容器,里面包含各种ceph的客户端程序,可以在这个容器中对ceph进行操作。
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/toolbox.yaml
进入pod中可以执行各种ceph命令:
$ kubectl -n rook-ceph exec -it rook-ceph-tools bash
ceph status
ceph osd status
ceph df
rados df
...
块存储一次只能挂给一个Pod使用。
修改配置文件rook-0.8.3/cluster/examples/kubernetes/ceph/storageclass.yaml,根据ceph数据盘的文件系统类型修改fstype参数:
fstype: xfs
创建块存储的storageclass:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/storageclass.yaml
创建两个应用mysql和wordpress,spec.volumes.persistentVolumeClaim.claimName
指定块存储的storageclass:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/mysql.yaml
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/wordpress.yaml
效果:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound pvc-3fe82814-f37f-11e8-a569-286ed488cbd8 20Gi RWO rook-ceph-block 5h51m
wp-pv-claim Bound pvc-ddb04927-f382-11e8-a569-286ed488cbd8 20Gi RWO rook-ceph-block 5h25m
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-3fe82814-f37f-11e8-a569-286ed488cbd8 20Gi RWO Delete Bound default/mysql-pv-claim rook-ceph-block 5h51m
pvc-ddb04927-f382-11e8-a569-286ed488cbd8 20Gi RWO Delete Bound default/wp-pv-claim rook-ceph-block 5h26m
共享文件系统可以以r/w的权限同时挂给多个Pod使用。目前rook默认只支持创建一个共享文件系统,在ceph中创建多个共享文件系统目前是实验性质的,可以通过修改rook-operator.yaml
中的ROOK_ALLOW_MULTIPLE_FILESYSTEMS
环境变量开启。
创建Filesystem资源:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/filesystem.yaml
可以看到创建了一个名为myfs的Filesystem:
$ kubectl get Filesystem -n rook-ceph
NAME AGE
myfs 6h
进入toolbox查看mds数据,还可以看到生成了一个standby-replay模式的mds实例:
$ kubectl -n rook-ceph exec -it rook-ceph-tools bash
...
services:
mds: myfs-1/1/1 up {0=myfs-7bd69578d7-q7nch=up:active}, 1 up:standby-replay
使用kube-registry.yaml文件创建一个应用指定使用刚才创建的名为myfs的filesystem:
volumes:
- name: image-store
flexVolume:
driver: ceph.rook.io/rook
fsType: ceph
options:
fsName: myfs # name of the filesystem specified in the filesystem CRD.
clusterName: rook-ceph # namespace where the Rook cluster is deployed
创建一块对象存储,向存储集群中暴露S3的API给应用使用。
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/object.yaml
对象存储创建后,rook operator会创建所有需要的pool和其他所需资源来启动服务。
等一段时间后,可以看到启动了一个rgw pod(rgw daemon):
$ kubectl -n rook-ceph get pod -l app=rook-ceph-rgw
NAME READY STATUS RESTARTS AGE
rook-ceph-rgw-my-store-84487c4898-z25zq 1/1 Running 0 6h44m
部署一个external的service,使得rgw也可以通过nodePort提供给集群外部使用:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/rgw-external.yaml
创建对象存储用户需要在toolbox容器中运行radosgw-admin
命令:
$ kubectl -n rook-ceph exec -it rook-ceph-tools bash
[root@rook-ceph-tools /]# radosgw-admin user create --uid rook-user --display-name "A rook rgw User" --rgw-realm=my-store --rgw-zonegroup=my-store
{
"user_id": "rook-user",
"display_name": "A rook rgw User",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [],
"keys": [
{
"user": "rook-user",
"access_key": "87EY7VY90ZTJE4TTHHM5",
"secret_key": "rGsUCKXphtYYHEnV4op3AX2GQiENVHfzVPZrdqZe"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw"
}
现在使用认证过的rook-user
用户就可以访问对象存储了,记下上面打印出来的access_key
和secret_key
,后面会用到:
{
"user": "rook-user",
"access_key": "87EY7VY90ZTJE4TTHHM5",
"secret_key": "rGsUCKXphtYYHEnV4op3AX2GQiENVHfzVPZrdqZe"
}
这一步连接对象存储并从上面上传、下载。方便起见,可以使用toolbox中的s3cmd
命令。进入到toolbox容器中执行以下命令:
1.使用S3对应的client在对象存储中创建bucket
设置连接的环境变量:
[root@rook-ceph-tools /]# export AWS_HOST=rook-ceph-rgw-my-store.rook-ceph
[root@rook-ceph-tools /]# export AWS_ENDPOINT=10.233.40.208:80
[root@rook-ceph-tools /]# export AWS_ACCESS_KEY_ID=EXS3PTFWTUQ7C8JO1LBE
[root@rook-ceph-tools /]# export AWS_SECRET_ACCESS_KEY=7DoGlb2YkV8lIsLhvkl4iKdvQfKICwzby7uPmJpu
其中:
- Host: rgw服务在k8s集群中的dns主机名,假如用的是默认的rook-ceph集群,是rook-ceph-rgw-my-store.rook-ceph
- Endpoint: rgw服务在k8s集群中监听的地址,即通过kubectl -n rook-ceph get svc rook-ceph-rgw-my-store命令获取的clusterIP+port
- Access key: 上面打印出的用户access_key
- Secret key: 上面打印出的用户secret_key
2.创建bucket
在对象存储中创建一个bucket:
[root@rook-ceph-tools /]# s3cmd mb --no-ssl --host=${AWS_HOST} --host-bucket= s3://rookbucket
Bucket 's3://rookbucket/' created
查看创建的bucket:
[root@rook-ceph-tools /]# s3cmd ls --no-ssl --host=${AWS_HOST}
2018-11-29 06:23 s3://rookbucket
3.PUT 或 GET 一个对象
Upload a file to the newly created bucket
上传一个文件到刚才创建的bucket中:
[root@rook-ceph-tools /]# echo "Hello Rook" > /tmp/rookObj
[root@rook-ceph-tools /]# s3cmd put /tmp/rookObj --no-ssl --host=${AWS_HOST} --host-bucket= s3://rookbucket
upload: '/tmp/rookObj' -> 's3://rookbucket/rookObj' [1 of 1]
11 of 11 100% in 0s 228.95 B/s done
从bucket中下载并验证这个文件:
[root@rook-ceph-tools /]# s3cmd get s3://rookbucket/rookObj /tmp/rookObj-download --no-ssl --host=${AWS_HOST} --host-bucket=
download: 's3://rookbucket/rookObj' -> '/tmp/rookObj-download' [1 of 1]
11 of 11 100% in 0s 250.92 B/s done
[root@rook-ceph-tools /]# cat /tmp/rookObj-download
Hello Rook
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!