您当前的位置:首页 > 网站建设 > 网站维护
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery |

kubernetes存储之GlusterFS集群详解

51自学网 2022-07-22 18:48:56
  网站维护

1、glusterfs概述

1.1、glusterfs简介

glusterfs是一个可扩展,分布式文件系统,集成来自多台服务器上的磁盘存储资源到单一全局命名空间,以提供共享文件存储。

1.2、glusterfs特点

  • 可以扩展到几PB容量
  • 支持处理数千个客户端
  • 兼容POSIX接口
  • 使用通用硬件,普通服务器即可构建
  • 能够使用支持扩展属性的文件系统,例如ext4,XFS
  • 支持工业标准的协议,例如NFS,SMB
  • 提供很多高级功能,例如副本,配额,跨地域复制,快照以及bitrot检测
  • 支持根据不同工作负载进行调优

1.3、glusterfs卷的模式

glusterfs中的volume的模式有很多中,包括以下几种:

  • 分布卷(默认模式):即DHT, 也叫 分布卷: 将文件以hash算法随机分布到 一台服务器节点中存储。
  • 复制模式:即AFR, 创建volume 时带 replica x 数量: 将文件复制到 replica x 个节点中。
  • 条带模式:即Striped, 创建volume 时带 stripe x 数量: 将文件切割成数据块,分别存储到 stripe x 个节点中 ( 类似raid 0 )。
  • 分布式条带模式:最少需要4台服务器才能创建。 创建volume 时 stripe 2 server = 4 个节点: 是DHT 与 Striped 的组合型。
  • 分布式复制模式:最少需要4台服务器才能创建。 创建volume 时 replica 2 server = 4 个节点:是DHT 与 AFR 的组合型。
  • 条带复制卷模式:最少需要4台服务器才能创建。 创建volume 时 stripe 2 replica 2 server = 4 个节点: 是 Striped 与 AFR 的组合型。
  • 三种模式混合: 至少需要8台 服务器才能创建。 stripe 2 replica 2 , 每4个节点 组成一个 组。

2、heketi概述

heketi是一个提供RESTful API管理gfs卷的框架,能够在kubernetes、openshift、openstack等云平台上实现动态的存储资源供应,支持gfs多集群管理,便于管理员对gfs进行操作,在kubernetes集群中,pod将存储的请求发送至heketi,然后heketi控制gfs集群创建对应的存储卷。

heketi动态在集群内选择bricks构建指定的volumes,以确保副本会分散到集群不同的故障域内。

heketi还支持任意数量的glusterfs集群,以保证接入的云服务器不局限于单个glusterfs集群。

3、部署heketi+glusterfs

环境:kubeadm安装的最新k8s 1.16.2版本,由1master+2node组成,网络插件选用的是flannel,默认kubeadm安装的k8s,会给master打上污点,本文为了实现gfs集群功能,先手动去掉了污点。

本文的glusterfs卷模式为复制卷模式。

另外,glusterfs在kubernetes集群中需要以特权运行,需要在kube-apiserver中添加–allow-privileged=true参数以开启此功能,默认此版本的kubeadm已开启。

[root@k8s-master-01 ~]# kubectl describe nodes k8s-master-01 |grep TaintTaints:             node-role.kubernetes.io/master:NoSchedule  [root@k8s-master-01 ~]# kubectl taint node k8s-master-01 node-role.kubernetes.io/master-node/k8s-master-01 untainted[root@k8s-master-01 ~]# kubectl describe nodes k8s-master-01 |grep TaintTaints:             <none>

3.1、准备工作

为了保证pod能够正常使用gfs作为后端存储,需要每台运行pod的节点上提前安装gfs的客户端工具,其他存储方式也类似。

3.1.1、所有节点安装glusterfs客户端

$ yum install -y glusterfs glusterfs-fuse -y

3.1.2、节点打标签

需要安装gfs的kubernetes设置Label,因为gfs是通过kubernetes集群的DaemonSet方式安装的。

DaemonSet安装方式默认会在每个节点上都进行安装,除非安装前设置筛选要安装节点Label,带上此标签的节点才会安装。

安装脚本中设置DaemonSet中设置安装在贴有 storagenode=glusterfs的节点,所以这是事先将节点贴上对应Label。

[root@k8s-master-01 ~]# kubectl get nodesNAME            STATUS   ROLES    AGE     VERSIONk8s-master-01   Ready    master   5d      v1.16.2k8s-node-01     Ready    <none>   4d23h   v1.16.2k8s-node-02     Ready    <none>   4d23h   v1.16.2[root@k8s-master-01 ~]# kubectl label node k8s-master-01 storagenode=glusterfsnode/k8s-master-01 labeled[root@k8s-master-01 ~]# kubectl label node k8s-node-01 storagenode=glusterfs  node/k8s-node-01 labeled[root@k8s-master-01 ~]# kubectl label node k8s-node-02 storagenode=glusterfsnode/k8s-node-02 labeled[root@k8s-master-01 ~]# kubectl get nodes --show-labels NAME            STATUS   ROLES    AGE     VERSION   LABELSk8s-master-01   Ready    master   5d      v1.16.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master-01,kubernetes.io/os=linux,node-role.kubernetes.io/master=,storagenode=glusterfsk8s-node-01     Ready    <none>   4d23h   v1.16.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node-01,kubernetes.io/os=linux,storagenode=glusterfsk8s-node-02     Ready    <none>   4d23h   v1.16.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node-02,kubernetes.io/os=linux,storagenode=glusterfs

3.1.3、所有节点加载对应模块

$ modprobe dm_snapshot$ modprobe dm_mirror$ modprobe dm_thin_pool

查看是否加载

$ lsmod | grep dm_snapshot$ lsmod | grep dm_mirror$ lsmod | grep dm_thin_pool

3.2、创建glusterfs集群

采用容器化方式部署gfs集群,同样也可以使用传统方式部署,在生产环境中,gfs集群最好是独立于集群之外进行部署,之后只需要创建对应的endpoints即可。这里采用Daemonset方式部署,同时保证已经打上标签的节点上都运行一个gfs服务,并且均有提供存储的磁盘。

3.2.1、下载相关安装文件

[root@k8s-master-01 glusterfs]# pwd/root/manifests/glusterfs[root@k8s-master-01 glusterfs]# wget https://github.com/heketi/heketi/releases/download/v7.0.0/heketi-client-v7.0.0.linux.amd64.tar.gz[root@k8s-master-01 glusterfs]# tar xf heketi-client-v7.0.0.linux.amd64.tar.gz[root@k8s-master-01 glusterfs]# cd heketi-client/share/heketi/kubernetes/[root@k8s-master-01 kubernetes]# pwd/root/manifests/glusterfs/heketi-client/share/heketi/kubernetes

在本集群中,下面用到的daemonset控制器及后面用到的deployment控制器的api版本均变为了apps/v1,所以需要手动修改下载的json文件再进行部署,资源编排文件中需要指定selector声明。避免出现以下报错:

[root@k8s-master-01 kubernetes]# kubectl apply -f glusterfs-daemonset.json error: unable to recognize "glusterfs-daemonset.json": no matches for kind "DaemonSet" in version "extensions/v1beta1"

修改api版本

"apiVersion": "extensions/v1beta1"

为apps/v1

"apiVersion": "apps/v1",

指定selector声明

[root@k8s-master-01 kubernetes]# kubectl apply -f glusterfs-daemonset.json error: error validating "glusterfs-daemonset.json": error validating data: ValidationError(DaemonSet.spec): missing required field "selector" in io.k8s.api.apps.v1.DaemonSetSpec; if you choose to ignore these errors, turn validation off with --validate=false

对应后面内容的selector,用matchlabel相关联

"spec": {    "selector": {        "matchLabels": {            "glusterfs-node": "daemonset"        }    },

3.2.2、创建集群

[root@k8s-master-01 kubernetes]# kubectl apply -f glusterfs-daemonset.json daemonset.apps/glusterfs created

注意:

  • 这里使用的是默认的挂载方式,可使用其他磁盘作为gfs的工作目录
  • 此处创建的namespace为default,可手动指定为其他namespace

3.2.3、查看gfs pods

[root@k8s-master-01 kubernetes]# kubectl get pods NAME              READY   STATUS    RESTARTS   AGEglusterfs-9tttf   1/1     Running   0          1m10sglusterfs-gnrnr   1/1     Running   0          1m10sglusterfs-v92j5   1/1     Running   0          1m10s

3.3、创建heketi服务

3.3.1、创建heketi的service account对象

[root@k8s-master-01 kubernetes]# cat heketi-service-account.json {  "apiVersion": "v1",  "kind": "ServiceAccount",  "metadata": {    "name": "heketi-service-account"  }}[root@k8s-master-01 kubernetes]# kubectl apply -f heketi-service-account.json serviceaccount/heketi-service-account created[root@k8s-master-01 kubernetes]# kubectl get saNAME                     SECRETS   AGEdefault                  1         71mheketi-service-account   1         5s

3.3.2、创建heketi对应的权限和secret

[root@k8s-master-01 kubernetes]# kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=dafault:heketi-service-accountclusterrolebinding.rbac.authorization.k8s.io/heketi-gluster-admin created[root@k8s-master-01 kubernetes]# kubectl create secret generic heketi-config-secret --from-file=./heketi.json secret/heketi-config-secret created

3.3.3、初始化部署heketi

同样的,需要修改api版本以及增加selector声明部分。

[root@k8s-master-01 kubernetes]# vim heketi-bootstrap.json ...      "kind": "Deployment",      "apiVersion": "apps/v1"...      "spec": {        "selector": {          "matchLabels": {            "name": "deploy-heketi"           }        },...[root@k8s-master-01 kubernetes]# kubectl create -f heketi-bootstrap.json service/deploy-heketi createddeployment.apps/deploy-heketi created[root@k8s-master-01 kubernetes]# vim heketi-deployment.json...      "kind": "Deployment",      "apiVersion": "apps/v1",...      "spec": {        "selector": {          "matchLabels": {            "name": "heketi"          }        },        "replicas": 1,...[root@k8s-master-01 kubernetes]# kubectl apply -f heketi-deployment.jsonsecret/heketi-db-backup createdservice/heketi createddeployment.apps/heketi created[root@k8s-master-01 kubernetes]# kubectl get pods NAME                             READY   STATUS    RESTARTS   AGEdeploy-heketi-6c687b4b84-p7mcr   1/1     Running   0          72sheketi-68795ccd8-9726s           0/1     ContainerCreating   0          50sglusterfs-9tttf                  1/1     Running   0          48mglusterfs-gnrnr                  1/1     Running   0          48mglusterfs-v92j5                  1/1     Running   0          48m

3.4、创建gfs集群

3.4.1、复制二进制文件

复制heketi-cli到/usr/local/bin目录下

[root@k8s-master-01 heketi-client]# pwd/root/manifests/glusterfs/heketi-client[root@k8s-master-01 heketi-client]# cp bin/heketi-cli /usr/local/bin/[root@k8s-master-01 heketi-client]# heketi-cli -vheketi-cli v7.0.0

3.4.2、配置topology-sample

修改topology-sample,manage为gfs管理服务的节点Node主机名,storage为节点的ip地址,device为节点上的裸设备,也就是用于提供存储的磁盘最好使用裸设备,不进行分区。
因此,需要预先在每个gfs的节点上准备好新的磁盘,这里分别在三个节点都新添加了一块/dev/sdb磁盘设备,大小均为10G。

[root@k8s-master-01 ~]# lsblkNAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTsda               8:0    0   50G  0 disk ├─sda1            8:1    0    2G  0 part /boot└─sda2            8:2    0   48G  0 part   ├─centos-root 253:0    0   44G  0 lvm  /  └─centos-swap 253:1    0    4G  0 lvm  sdb               8:16   0   10G  0 disk sr0              11:0    1 1024M  0 rom[root@k8s-node-01 ~]# lsblkNAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTsda               8:0    0   50G  0 disk ├─sda1            8:1    0    2G  0 part /boot└─sda2            8:2    0   48G  0 part   ├─centos-root 253:0    0   44G  0 lvm  /  └─centos-swap 253:1    0    4G  0 lvm  sdb               8:16   0   10G  0 disk sr0              11:0    1 1024M  0 rom[root@k8s-node-02 ~]# lsblkNAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTsda               8:0    0   50G  0 disk ├─sda1            8:1    0    2G  0 part /boot└─sda2            8:2    0   48G  0 part   ├─centos-root 253:0    0   44G  0 lvm  /  └─centos-swap 253:1    0    4G  0 lvm  sdb               8:16   0   10G  0 disk sr0              11:0    1 1024M  0 rom 

配置topology-sample

{    "clusters": [        {            "nodes": [                {                    "node": {                        "hostnames": {                            "manage": [                                "k8s-master-01"                            ],                            "storage": [                                "192.168.2.10"                            ]                        },                        "zone": 1                    },                    "devices": [                        {                            "name": "/dev/sdb",                            "destroydata": false                        }                    ]                },                {                    "node": {                        "hostnames": {                            "manage": [                                "k8s-node-01"                            ],                            "storage": [                                "192.168.2.11"                            ]                        },                        "zone": 1                    },                    "devices": [                        {                            "name": "/dev/sdb",                            "destroydata": false                        }                    ]                },                {                    "node": {                        "hostnames": {                            "manage": [                                "k8s-node-02"                            ],                            "storage": [                                "192.168.2.12"                            ]                        },                        "zone": 1                    },                    "devices": [                        {                            "name": "/dev/sdb",                            "destroydata": false                        }                    ]                }            ]        }    ]}

3.4.3、获取当前heketi的ClusterIP

查看当前heketi的ClusterIP,并通过环境变量声明

[root@k8s-master-01 kubernetes]# kubectl get svc|grep heketideploy-heketi   ClusterIP   10.1.241.99   <none>        8080/TCP   3m18s[root@k8s-master-01 kubernetes]# curl http://10.1.241.99:8080/helloHello from Heketi[root@k8s-master-01 kubernetes]# export HEKETI_CLI_SERVER=http://10.1.241.99:8080[root@k8s-master-01 kubernetes]# echo $HEKETI_CLI_SERVERhttp://10.1.185.215:8080

3.4.4、使用heketi创建gfs集群

执行如下命令创建gfs集群会提示Invalid JWT token: Token missing iss claim

[root@k8s-master-01 kubernetes]# heketi-cli topology load --json=topology-sample.json Error: Unable to get topology information: Invalid JWT token: Token missing iss claim

这是因为新版本的heketi在创建gfs集群时需要带上参数,声明用户名及密码,相应值在heketi.json文件中配置,即:

[root@k8s-master-01 kubernetes]# heketi-cli -s $HEKETI_CLI_SERVER --user admin --secret 'My Secret' topology load --json=topology-sample.jsonCreating cluster ... ID: 1c5ffbd86847e5fc1562ef70c033292e        Allowing file volumes on cluster.        Allowing block volumes on cluster.        Creating node k8s-master-01 ... ID: b6100a5af9b47d8c1f19be0b2b4d8276                Adding device /dev/sdb ... OK        Creating node k8s-node-01 ... ID: 04740cac8d42f56e354c94bdbb7b8e34                Adding device /dev/sdb ... OK        Creating node k8s-node-02 ... ID: 1b33ad0dba20eaf23b5e3a4845e7cdb4                Adding device /dev/sdb ... OK

执行了heketi-cli topology load之后,Heketi在服务器做的大致操作如下:

  • 进入任意glusterfs Pod内,执行gluster peer status 发现都已把对端加入到了可信存储池(TSP)中。
  • 在运行了gluster Pod的节点上,自动创建了一个VG,此VG正是由topology-sample.json 文件中的磁盘裸设备创建而来。
  • 一块磁盘设备创建出一个VG,以后创建的PVC,即从此VG里划分的LV。
  • heketi-cli topology info 查看拓扑结构,显示出每个磁盘设备的ID,对应VG的ID,总空间、已用空间、空余空间等信息。
    通过部分日志查看
[root@k8s-master-01 manifests]# kubectl logs -f deploy-heketi-6c687b4b84-l5b6j...[kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/log/commandlog.go:46:log.(*CommandLogger).Success: Ran command [pvs -o pv_name,pv_uuid,vg_name --reportformat=json /dev/sdb] on [pod:glusterfs-lrdz7 c:glusterfs ns:default (from host:k8s-node-01 selector:glusterfs-node)]: Stdout [  {      "report": [          {              "pv": [                  {"pv_name":"/dev/sdb", "pv_uuid":"1UkSIV-RYt1-QBNw-KyAR-Drm5-T9NG-UmO313", "vg_name":"vg_398329cc70361dfd4baa011d811de94a"}              ]          }      ]  }]: Stderr [  WARNING: Device /dev/sdb not initialized in udev database even after waiting 10000000 microseconds.  WARNING: Device /dev/centos/root not initialized in udev database even after waiting 10000000 microseconds.  WARNING: Device /dev/sda1 not initialized in udev database even after waiting 10000000 microseconds.  WARNING: Device /dev/centos/swap not initialized in udev database even after waiting 10000000 microseconds.  WARNING: Device /dev/sda2 not initialized in udev database even after waiting 10000000 microseconds.  WARNING: Device /dev/sdb not initialized in udev database even after waiting 10000000 microseconds.][kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/log/commandlog.go:34:log.(*CommandLogger).Before: Will run command [udevadm info --query=symlink --name=/dev/sdb] on [pod:glusterfs-lrdz7 c:glusterfs ns:default (from host:k8s-node-01 selector:glusterfs-node)][kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/kube/exec.go:72:kube.ExecCommands: Current kube connection count: 0[kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/log/commandlog.go:46:log.(*CommandLogger).Success: Ran command [udevadm info --query=symlink --name=/dev/sdb] on [pod:glusterfs-lrdz7 c:glusterfs ns:default (from host:k8s-node-01 selector:glusterfs-node)]: Stdout []: Stderr [][kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/log/commandlog.go:34:log.(*CommandLogger).Before: Will run command [vgdisplay -c vg_398329cc70361dfd4baa011d811de94a] on [pod:glusterfs-lrdz7 c:glusterfs ns:default (from host:k8s-node-01 selector:glusterfs-node)][kubeexec] DEBUG 2019/10/23 02:17:44 heketi/pkg/remoteexec/kube/exec.go:72:kube.ExecCommands: Current kube connection count: 0[negroni] 2019-10-23T02:17:44Z | 200 |   93.868
下载地址:
startup.bat启动Tomcat闪退问题原因及解决
CentOS7安装GlusterFS集群的全过程
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1