在《Kubernetes共享存储详解》一节中我们已经对PersistentVolume(PV)
、PersistentVolumeClaim(PVC)
和StorageClass
三个对象有了一定的了解,今天我们就动手搭建一套基于Kubernetes搭建GlusterFS分布式存储系统。
1、GlustrerFS 介绍
(1)、GlusterFS 简介
GlusterFS 是一个可扩展,分布式文件系统,集成来自多台服务器上的磁盘存储资源到单一全局命名空间,已提供共享文件存储。
(2)、Gluster 优势
可以扩展到几PB容量
支持处理数千个客户端
兼容POSIX接口
使用通用硬件,普通服务器即可构建
能够使用支持扩展属性的文件系统,例如ext4,XFS
支持工业标准的协议,例如NFS,SMB
提供很多高级功能,例如副本,配额,跨地域复制,快照以及bitrot检测
支持根据不同工作负载进行调优
2、Heketi 介绍
(1)、Heketi 简介
提供基于RESTful接口管理 GlusterFS 的功能,可以方便的创建集群管理 GlusterFS 的 node,device,volume 与 Kubernetes 结合可以创建动态的 PV,扩展 GlusterFS 存储的动态管理功能。
Heketi动态在集群内选择bricks构建指定的volumes,以确保副本会分散到集群不同的故障域内。
Heketi还支持任意数量的ClusterFS集群,以保证接入的云服务器不局限于单个GlusterFS集群。
3、准备
(1)至少三个节点
正在运行的Kubernetes集群,至少有三个Kubernetes工作节点。
hostname | ip |
---|---|
k8s-master | 10.120.51.1 |
k8s-node-1 | 10.120.51.2 |
k8s-node-1 | 10.120.51.3 |
k8s-node-1 | 10.120.51.4 |
(2)开放端口
每个节点必须为 GlusterFS 通信打开以下端口:
- 2222 - GlusterFS pod的sshd
- 24007 - GlusterFS守护程序
- 24008 - GlusterFS管理
用于运行GlusterFS Pod的三个Kubernetes节点必须为GlusterFS通信打开相应的端口(如果开启了防火墙的情况下,没开防火墙就不需要这些操作)。在每个节点上运行以下命令。
iptables -N heketi
iptables -A heketi -p tcp -m state --state NEW -m tcp --dport 24007 -j ACCEPT
iptables -A heketi -p tcp -m state --state NEW -m tcp --dport 24008 -j ACCEPT
iptables -A heketi -p tcp -m state --state NEW -m tcp --dport 2222 -j ACCEPT
iptables -A heketi -p tcp -m state --state NEW -m multiport --dports 49152:49251 -j ACCEPT
service iptables save
(3)、裸设备
每个节点必须至少连接一个裸设备(如空的本地磁盘)供 heketi 使用。这些设备上不得有任何数据,因为它们将由 heketi 格式化和分区。简单意思就是需要一个没有数据的空的本地硬盘。
(4)、安装 glusterfs-fuse 工具
每个节点都要求该mount.glusterfs命令可用。在所有基于Red Hat的操作系统下,该命令由 glusterfs-fuse 包提供,所以需要安装 glusterfs-fuse 工具。安装命令如下:
# Cent OS
yum install glusterfs glusterfs-fuse
# Ubuntu
apt-get install glusterfs glusterfs-fuse
(5)、加载内核
必须加载以下内核模块:
modprobe dm_snapshot
modprobe dm_mirror
modprobe dm_thin_pool
(6)、kube-apiserver 开启 privileged
GlusterFS 在 Kubernetes 集群中需要以特权运行,需要在 kube-apiserver 中添加“–allow-privileged=true”参数以开启此功能。
(7)、给机器打标签
给要部署的 GlusterFS 管理服务的节点打上 “storagenode=glusterfs
” 的标签,是为了将 GlusterFS 容器定向部署到安装了 GlusterFS 的 Node:
kubectl lable node k8s-node-1 storagenode=glusterfs
kubectl lable node k8s-node-2 storagenode=glusterfs
kubectl lable node k8s-node-3 storagenode=glusterfs
4、Heketi 客户端安装
在 k8s-master 上从 https://github.com/heketi/heketi/tags 下载所需的压缩包(本次实验使用的是 v8.0.0 版本),解压到 /home/heketi-client 目录,然后创建文件软连接,方便在主机的任意目录使用 heketi-cli 命令:
ln -s /home/heketi-client/bin/heketi-cli /usr/local/bin/heketi-cli
然后执行heketi-cli -v
看到如下输出,表示安装成功:
$ heketi-cli -v
heketi-cli v8.0.0
5、在Kubernetes集群中部署Glusterfs和Heketi Server
这个安装过程参考《使用Heketi作为kubernetes的持久存储GlusterFS的external provisioner(Kubernetes集成GlusterFS集群和Heketi)》
需要注意的是,在执行 heketi-cli 命令是可能会提示 Error: Invalid JWT token: Token missing iss claim
,这是因为缺少用户名和密码(用户名和密码在 heketi-client/share/heketi/kubernetes/heketi.json 中),需要添加 --user
和 --secret
参数即可。如下所示:
heketi-cli --user admin --secret 'My Secret' setup-openshift-heketi-storage
在生成 heketi-storage.json 文件后,并不能直接执行 kubectl create -f heketi-storage.json
,因为其中的一些配置是错误的(如glusterFS服务端口),需要作出如下修改:
{
"apiVersion": "v1",
"kind": "List",
"items": [
{
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "heketi-storage-secret",
"creationTimestamp": null,
"labels": {
"deploy-heketi": "support"
}
},
"data": {
"heketi.db": "xxx"
}
},
{
"kind": "Endpoints",
"apiVersion": "v1",
"metadata": {
"name": "heketi-storage-endpoints",
"creationTimestamp": null
},
"subsets": [
{
"addresses": [
{
"ip": "10.120.51.2"
}
],
"ports": [
{
"port": 24007 # 端口修改成 24007
}
]
},
{
"addresses": [
{
"ip": "10.120.51.3"
}
],
"ports": [
{
"port": 24007 # 端口修改成 24007
}
]
},
{
"addresses": [
{
"ip": "10.120.51.4"
}
],
"ports": [
{
"port": 24007 # 端口修改成 24007
}
]
}
]
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "heketi-storage-endpoints",
"creationTimestamp": null
},
"spec": {
"ports": [
{
"port": 24007, # 端口修改成 24007
"targetPort": 24007 # 端口修改成 24007
}
]
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Job",
"apiVersion": "batch/v1",
"metadata": {
"name": "heketi-storage-copy-job",
"creationTimestamp": null,
"labels": {
"deploy-heketi": "support"
}
},
"spec": {
"parallelism": 1,
"completions": 1,
"template": {
"metadata": {
"name": "heketi-storage-copy-job",
"creationTimestamp": null
},
"spec": {
"volumes": [
{
"name": "heketi-storage",
"glusterfs": {
"endpoints": "heketi-storage-endpoints",
"path": "heketidbstorage"
}
},
{
"name": "heketi-storage-secret",
"secret": {
"secretName": "heketi-storage-secret"
}
}
],
"containers": [
{
"name": "heketi",
"image": "heketi/heketi:dev",
"command": [
"cp",
"/db/heketi.db",
"/heketi"
],
"resources": {},
"volumeMounts": [
{
"name": "heketi-storage",
"mountPath": "/heketi"
},
{
"name": "heketi-storage-secret",
"mountPath": "/db"
}
]
}
],
"restartPolicy": "Never",
"nodeSelector": { # 指定运行在包含下面标签的机器上,否则无法正常运行
"storagenode": "glusterfs"
}
}
}
},
"status": {}
}
]
}
至此,GlusterFS集群就搭建完成了。