基于Kubernetes搭建GlusterFS分布式存储

在《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集群就搭建完成了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353