rook
云原生存储编排利器Rook详解
1. Rook介绍
1.1 Rook简介
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资源及其控制器的封装。
1.2 Rook架构
1.2.1 整体架构
目前,Rook是基于FlexVolume存储插件机制实现的。Rook整体架构如下图所示:
由图可知,Rook主要由3部分组成:
- Operator。主要是CRD资源的控制器
- Agent。主要通过FlexVolume驱动执行一些存储操作,比如attaching/detaching, mount/unmount
- Discover。用来定期去发现节点上新的存储设备
1.2.2 启动流程
Rook的三个组件都集成在一个rook/ceph镜像中。rook的启动流程如下所示:
- 首先,会使用Deployment启动Operator组件;
- 然后,使用Daemonset在每个容器云的主机上启动一个Agent组件,同时将FlexVolume插件安装在每台主机的volume-plugin-dir目录下;
- 接着,同样使用Daemonset形式在每个主机上启动一个Discover组件;
- 最后,创建了两个自定义资源的控制器Provisioncontroller和clusterController。
Rook的Operator启动后可以看到在rook-ceph-system
这个namespace下创建了与上面相对应的一些pod:
2. Rook对Ceph的管理
Ceph是一个分布式存储系统,支持文件、块、对象存储,在生产环境中被广泛应用。
使用rook部署ceph集群后,在rook-ceph
这个namespace下会启动如下一些pod:
分为以下几种类型:
- mon
- mgr
- osd
- mds
- rgw
mon
即Ceph集群中的mon(monitor)组件,负责监控整个Ceph集群的运行状况。会启动quorum中指定个数的mon,一般集群中会有三个mon以保证集群的高可用。在创建集群时,Rook会:
- 启动特定节点上的mon,确保与quorum中指定的相同
- 之后,定期检查mon的数量,确保与quorum中指定的相同;如果某个mon挂了,并且没有自动重启,Operator会再起一个新的mon,加到quorum中,并从quorum中移除失效的mon
- 有mon挂了后,更新Ceph客户端和Daemons中的mon的IP地址
mgr
即Ceph集群中的mgr(manager)组件,主要负责监控一些非paxos相关的服务(比如pg相关统计信息),这里的mgr是一个无状态服务,提供集群一些非paxos相关的监控指标。Rook除了启动mgr外,还负责配置其它两个mgr插件:
- 收集可供Prometheus抓取的指标
- 启动Ceph dashoard
osd
即Ceph集群的osd组件,集群的核心存储组件。
mds
即Ceph集群的mds组件,是Ceph分布式文件系统的元数据服务器。一或多个mds 协作管理文件系统的命名空间、协调到共享osd集群的访问。当在集群中声明要一个共享文件系统时,Rook会:
- 为CephFS创建metadata和数据池
- 创建文件系统
- 启动指定数量active-standby的mds实例
创建的共享文件系统可以被集群中Pod使用。
rgw
即Ceph集群的rgw组件,为应用提供RESTful类型的对象存储接口。当在集群中声明要一个对象存储时,Rook会:
- 为对象存储创建metadata和数据池
- 启动rgw daemon,如果需要还可以运行多个实例做高可用
- 创建一个service来为rgw daemon提供一个负载均衡访问地址
3. rook安装
3.1 rook集群部署
- 找一块大点的磁盘(至少大于5GB),创建rook数据存储目录:
$ sudo mkdir /APP/dcos/rook
- 到release页面下载rook,我下载的v0.8.3版:
$ wget https://github.com/rook/rook/archive/v0.8.3.zip && unzip v0.8.3.zip
- 配置kubelet,设置启动参数
--volume-plugin-dir
:
这个参数告诉kubelet到哪里去找第三方存储插件,确保这个参数指定的目录有读写权限。不指定的话,默认值是
/usr/libexec/kubernetes/ kubelet-plugins/volume/exec/
。
- 配置operator.yaml,需要和kubelet的
--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"
- 配置cluster.yaml,修改rook数据存储目录:
$ 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)
3.2 ceph集群的访问
3.2.1 通过图形界面
部署一个external的dashboard service,以nodePort的形式对外提供图形界面访问:
$ kubectl apply -f rook-0.8.3/cluster/examples/kubernetes/ceph/dashboard-external.yaml
3.2.2 通过ceph命令行工具访问
官方给出了一个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
...
4. 使用
4.1 块存储
块存储一次只能挂给一个Pod使用。
4.1.1 创建块存储storageclass
修改配置文件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
4.1.2 块存储使用示例
创建两个应用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
4.2 共享文件系统
共享文件系统可以以r/w的权限同时挂给多个Pod使用。目前rook默认只支持创建一个共享文件系统,在ceph中创建多个共享文件系统目前是实验性质的,可以通过修改rook-operator.yaml
中的ROOK_ALLOW_MULTIPLE_FILESYSTEMS
环境变量开启。
4.2.1 创建一个Filesystem资源
创建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
4.2.2 共享文件系统使用示例
使用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
4.3 对象存储
4.3.1 创建对象存储
创建一块对象存储,向存储集群中暴露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
4.3.2 创建用户
创建对象存储用户需要在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"
}
4.3.3 使用对象存储
这一步连接对象存储并从上面上传、下载。方便起见,可以使用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
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
支付宝:微信:
相关阅读
kubernetes 自1.14 之后,Kubernetes 项目本身开始具备了原生的应用管理能力,这其中最重要的一个功能,就是 Kustomize。 Kustomize 允
kubernetes系列之十四:Kubernetes CRD(CustomResourceD
一、前言Kubernetes平台对于分布式服务部署的很多重要的模块都有系统性的支持,借助如下一些平台资源可以满足大多数分布式系统部署
云存储就是将储存资源放到云上供人存取的一种新兴方案,使用者可以在任何时间、任何地方,透过任何可连网的装置连接到云上方便地存取
目录 事务 索引 1.创建索引 2.删除索引 3.查看索引 4.索引准则 视图 触发器 存储过程 1.创建存储过程 2.调用存储过程 3.查看存储
1、精度丢失 作为程序员大家应该都遇到过下面这种情况,用浮点数做运算,发现结果与预期有偏差,比如下面的JAVA代码 public static