KubeSphere使用GlusterFS作为持久化存储


提示: k8s中可以使用静态、动态的方式供给glusterfs存储资源,但是两者的配置不相同,如果是静态,那么直接挂盘,创建lvm,创建文件系统,挂载,安装glusterfs集群,创建卷,k8s使用gluster即可。但是动态方式的话,需要结合heketi服务+glusterfs,由heketi服务管理、创建glusterfs集群,k8s中配置存储类指定heketi即可。heketi服务要求glusterfs服务器的磁盘必须是裸盘,不能是格式化的文件系统或lvm,这有点坑。所以这一点需要注意了。

一、 前言

环境:centos7.9 、Kubernetes v1.22.12
glusterfs的官网:https://docs.gluster.org/en/latest
glusterfs于 v1.25 弃用,具体可以查看 k8s存储支持矩阵

1、主机准备

  准备3台虚拟机或物理机,用于安装glusterfs文件系统作为storage服务器,并单独挂载一个磁盘用于存放数据,因为GlusterFS不建议共享根目录。
这里我使用的是3台主机。

192.168.54.52
192.168.54.53
192.168.54.54

配置主机名、关闭防火墙、关闭selinux
略过,太简单了,自己做。

2、准备磁盘

提示:三个存储节点都要挂载一块未经格式化的的硬盘出来。
  如果是虚拟机直接虚一块硬盘出来,我使用的云服务器,直接虚了一块硬盘,注意先不要对这块硬盘做任何操作,虚好之后,执行命令查看下。

sudo lsblk

  可以看到vdb这个盘符
在这里插入图片描述

二、 安装glusterfs服务端

1、配置glusterfs yum源

#配置glusterfs的yum源
cat > /etc/yum.repos.d/glusterfs.repo <<EOF
[glusterfs]
name=glusterfs
baseurl=https://buildlogs.centos.org/centos/7/storage/x86_64/gluster-9/	
enabled=1
gpgcheck=0
EOF

2、安装gluster服务

#安装glusterfs-server
yum install glusterfs-server

3、开启服务,并做开机启动

systemctl start glusterd.service
systemctl enable  glusterd.service
systemctl status  glusterd.service

4、glusterfs的端口

#gluster守护进程端口24007,每创建一个逻辑卷,就会启动一个进程和端口,
进程端口默认是49152,以此类推,第二个卷端口就是49153。
[root@gluster1 /]# netstat  -lntup | grep gluster
tcp        0      0 0.0.0.0:49152           0.0.0.0:*               LISTEN      12946/glusterfsd    
tcp        0      0 0.0.0.0:49153           0.0.0.0:*               LISTEN      15586/glusterfsd    
tcp        0      0 0.0.0.0:24007           0.0.0.0:*               LISTEN      3503/glusterd  

三、 安装Heketi 服务(实现k8s动态供给glusterfs存储需要用到Heketi 服务)

  heketi是为glusterfs集群提供RESTFUL API的,通过restful风格对glusterfs集群进行管理控制。

  在k8s官方文档中写到,要使用glusterfs作为后端动态供给存储,在存储类中要配置heketi的接口,并不是直接配置glusterfs的,所以我们需要安装Heketi 服务。

  Heketi 服务的安装方式分为3种,OpenShift集群安装、Standalone独立单机安装、Kubernetes安装 ,我们采用Standalone独立单机安装方式。

1、Heketi安装

  1. 在线yum安装heketi服务端和客户端工具,heketi 也是在glusterfs源里面的,如果没有glusterfs源,参考上面的配置glusterfs的yum源
yum install  heketi heketi-client
  1. #离线安装
    参考官方网站 添加链接描述,下载heketi二进制包并将服务配置为systemd管理启动即可.

2、 创建heketi用户并配置免密登录

  创建免密登录的用户,因为官网要求heketi主机要能免密登录到glusterfs的主机上,这里我不在创建一个heketi用户,直接使用root用户,如果是非root用户,需要有sudo权限。

#建议使用root用户做免密登录
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

3、修改heketi配置文件

vim /etc/heketi/heketi.json
{
    
    
  "_port_comment": "Heketi Server Port Number",
  "port": "7080",      #Heketi服务端口,默认是8080,可以自定义

  "_use_auth": "Enable JWT authorization. Please enable for deployment",
  "use_auth": true,   true,	#是否使用JWT authorization,设置为true

  "_jwt": "Private keys for access",
  "jwt": {
    
    
    "_admin": "Admin has access to all APIs",
    "admin": {
    
    
      "key": "abc.123456"     #配置admin的密码
    },
    "_user": "User only has access to /volumes endpoint",
    "user": {
    
    
      "key": "abc.123456"     #配置普通账号的密码
    }
  },

  "_glusterfs_comment": "GlusterFS Configuration",
  "glusterfs": {
    
    
    "_executor_comment": [
      "Execute plugin. Possible choices: mock, ssh",
      "mock: This setting is used for testing and development.",
      "      It will not send commands to any node.",
      "ssh:  This setting will notify Heketi to ssh to the nodes.",
      "      It will need the values in sshexec to be configured.",
      "kubernetes: Communicate with GlusterFS containers over",
      "            Kubernetes exec api."
    ],
    "executor": "ssh",    #命令执行器配置为ssh

    "_sshexec_comment": "SSH username and private key file information",
    "sshexec": {
    
                  #命令执行器为ssh方式,改下面这段
      "keyfile": "/root/.ssh/id_rsa",      #ssh的密钥
      "user": "root",           #ssh的用户,我使用的是root用户            
      "port": "22",             #ssh的端口     
      "fstab": "/etc/fstab"     #存储挂载点的fstab文件,保持默认即可
    },

    "_kubeexec_comment": "Kubernetes configuration",
    "kubeexec": {
    
             #命令执行器没有用到kubernetes,不用改
      "host" :"https://kubernetes.host:8443",
      "cert" : "/path/to/crt.file",
      "insecure": false,
      "user": "kubernetes username",
      "password": "password for kubernetes user",
      "namespace": "OpenShift project or Kubernetes namespace",
      "fstab": "Optional: Specify fstab file on node.  Default is /etc/fstab"
    },

    "_db_comment": "Database file name",
    "db": "/var/lib/heketi/heketi.db",  #heketi数据库文件,保持默认

    "_loglevel_comment": [
      "Set log level. Choices are:",
      "  none, critical, error, warning, info, debug",
      "Default is warning"
    ],
    "loglevel" : "warning"             #定义日志几级别
  }
}

4、启动heketi服务

  修改运行heketi服务的用户,默认是heketi用户,yum安装的时候默认创建了heketi用户,但是我们使用ssh的是root用户,所以需要修改一下运行heketi服务的用户。

vim /usr/lib/systemd/system/heketi.service
User=root	#改为root

启动

systemctl daemon-reload 
systemctl start  heketi
systemctl enable heketi
systemctl status heketi

测试,看到如下打印,即表示Heketi服务启动正常。

curl http://192.168.54.52:7080/hello
Hello from Heketi

5、配置hekeit-cli客户端工具的环境变量

echo 'export HEKETI_CLI_SERVER=http://192.168.54.52:7080' >> ~/.bash_profile	#永久设置环境变量
echo 'export HEKETI_CLI_USER=admin'  >> ~/.bash_profile							#永久设置环境变量
echo 'export HEKETI_CLI_KEY=abc.123456'  >> ~/.bash_profile						#永久设置环境变量
source  ~/.bash_profile															#立即生效

6、设置hekeit的topology文件

  官网说必须向Heketi提供关于系统拓扑结构的信息。这允许Heketi决定使用哪些节点、磁盘和集群。https://github.com/heketi/heketi/blob/master/docs/admin/topology.md

  可以使用命令行客户端创建一个集群,然后向该集群添加节点,然后向每个节点添加磁盘。如果使用命令行,这个过程可能相当乏味。因此,命令行客户端支持使用拓扑文件将这些信息加载到Heketi,该拓扑文件描述集群、集群节点和每个节点上的磁盘信息。

  编写topology文件,这个拓扑文件是一个JSON格式的文件,描述要添加到Heketi的集群、节点和磁盘 官网示例

{
    
    
    "clusters": [
        {
    
    
            "nodes": [
                {
    
    
                    "node": {
    
    
                        "hostnames": {
    
    
                            "manage": [
                                "192.168.54.52"
                            ],
                            "storage": [
                                "192.168.54.52"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
    
    
                            "name": "/dev/vdb",
                            "destroydata": true
                        }
                    ]
                },
                {
    
    
                    "node": {
    
    
                        "hostnames": {
    
    
                            "manage": [
                                "192.168.54.53"
                            ],
                            "storage": [
                                "192.168.54.53"
                            ]
                        },
                        "zone": 2
                    },
                    "devices": [
                        {
    
    
                            "name": "/dev/vdb",
                            "destroydata": true
                        }
                    ]
                },
                {
    
    
                    "node": {
    
    
                        "hostnames": {
    
    
                            "manage": [
                                "192.168.54.54"
                            ],
                            "storage": [
                                "192.168.54.54"
                            ]
                        },
                        "zone": 2
                    },
                    "devices": [
                        {
    
    
                            "name": "/dev/vdb",
                            "destroydata": true
                        }
                    ]
                }
            ]
        }
    ]
}

通过拓扑文件加载glusterfs节点到Heketi

[root@gluster1]# heketi-cli topology load --json=/etc/heketi/topology.json --server=http://192.168.54.52:7080--user=admin --secret=abc.123456
	Found node 192.168.54.52 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Adding device /dev/vdb ... OK
	Found node 192.168.54.53 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Adding device /dev/vdb ... OK
	Found node 192.168.54.54 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Found device /dev/vdb

  查看信息,因为前面在/root/.bash_profile文件加了heketi-cli 客户端工具的环境变量,所以这里不用在写–server等参数

heketi-cli topology info

7、测试创建存储卷

heketi-cli volume create --size=2 --replica=3

输出

Name: vol_aa8a1280b5133a36b32cf552ec9dd3f3
Size: 2
Volume Id: aa8a1280b5133a36b32cf552ec9dd3f3
Cluster Id: b89a07c2c6e8c533322591bf2a4aa613
Mount: 192.168.54.52:vol_aa8a1280b5133a36b32cf552ec9dd3f3
Mount Options: backup-volfile-servers=192.168.54.52,192.168.54.53
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distribute Count: 1
Replica Count: 3

四、kubesphere使用glusterfs作为后端存储(动态供给glusterfs存储)

kubesphere安装请自行安装 Kubesphere官网教程
提示:经过反复测试,使用kubesphere界面进行gluster存储配置,存储卷声明(PVC)始终处于pending的状态,无法成功挂载,这里使用K8s命令直接进行存储类的创建,然后使用kubesphere界面进行存储卷声明配置,可以成功挂载并持久化gluster集群中。 这个或许是我的方式有问题,后续测试成功之后再进行更新,本文先按照实验的步骤进行记录,避免更多coder踩坑。

步骤如下

  • 1、创建一个srecrt,用户保存heketi服务的用户的密码,仅密码而已(可以使用kubesphere,也可以使用yaml文件);
  • 2、创建存储类(使用yaml文件);
  • 3、一个制备器(Provisioner),k8s内置了glusterfs类型的Provisioner驱动,所以这里不用自己单独创建了(无需创建);
  • 4、创建pvc(使用kubesphere);
  • 5、创建deployment,pod使用pvc进行数据持久化(使用kubesphere);

1、创建secret,仅存储密码

推荐一个base64密码转换的网站 Base64在线验证

vim heketi-secret.yaml			#创建secret,主要用于保存heketi服务的admin用户密码
apiVersion: v1
kind: Secret
metadata:
  name: heketi-secret
  namespace: kube-system
data:
  # base64 encoded password. E.g.: echo -n "abc.123456" | base64
  key: YWJjLjEyMzQ1Ng==		#这个是heketi服务的admin用户密码abc.123456,仅密码而已
type: kubernetes.io/glusterfs
#创建成功
kubectl apply -f heketi-secret.yaml	

2、创建存储类

参考 官网参考文档

vim glusterfs-storageclass.yaml	
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: glusterfs-storageclass						#存储名称
provisioner: kubernetes.io/glusterfs				#指定存储类的provisioner,这个provisioner是k8s内置的驱动程序
reclaimPolicy: Retain								#pvc删除,pv采用何种方式处理,这里是保留
volumeBindingMode: Immediate						#卷的绑定模式,表示创建pvc立即绑定pv
allowVolumeExpansion: true							#是否运行卷的扩容,配置为true才能实现扩容pvc
parameters:											#glusterfs的配置参数
  resturl: "http://192.168.54.52:7080"			    #heketi服务的地址和端口
  clusterid: "0cb591249e2542d0a73c6a9c8351baa2"		#集群id,在heketi服务其上执行heketi-cli cluster list能看到
  restauthenabled: "true"							#Gluster REST服务身份验证布尔值,用于启用对 REST 服务器的身份验证
  restuser: "admin"									#heketi的用户admin
  secretNamespace: "kube-system"						#secret所属的密码空间
  secretName: "heketi-secret"						#secret,使用secret存储了heketi的用户admin的登陆密码
  volumetype: "replicate:3"                         #挂载类型,三个副本,生产常用
#创建成功
kubectl apply -f glusterfs-storageclass.yaml

查看存储类型,可以使用如下命令进行查看,如果显示创建成功,在kubesphere界面也能看到相应的存储类型。

[root@master /]# kubectl  get sc
NAME                          PROVISIONER               RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
glusterfs (default)           kubernetes.io/glusterfs   Delete          Immediate              true                   5h27m
glusterfs-storageclass        kubernetes.io/glusterfs   Retain          Immediate              true                   4h21m
glusterfs-test-storageclass   kubernetes.io/glusterfs   Retain          Immediate              true                   3h44m
local (default)               openebs.io/local          Delete          WaitForFirstConsumer   false                  20d

在这里插入图片描述
接下来,就可以通过kubesphere界面定义存储声明(PVC)
在这里插入图片描述

创建工作负载,选择之前创建的存储声明。

在这里插入图片描述

五、探究日志数据落盘到哪里了

在任意一个节点执行lsblk我们发现如下情况:

[root@gluster1 /]# cat /etc/fstab

已经自动挂载了
在这里插入图片描述

[root@gluster1 /]# lsblk

多了很多分区
在这里插入图片描述
/dev/vdb原本是一个没有格式化过的裸盘,现在却出现了挂载点,进入挂载点查看,发现文件已经持久化进glusterfs文件系统,并且其他几个节点,也同样有了数据。
在这里插入图片描述
重新部署负载,使用相同的存储声明(PVC),数据依然存在,到此基本已经验证了这套解决方案,完美!

六、总结

  1. k8s于 v1.25 版本弃用glusterfs,glusterfs是否还受欢迎;
  2. k8s动态供给glusterfs存储时,heketi要求硬盘必须是裸盘,既然是裸盘,那就不需要我们参加创建文件系统,那文件随机挂载的吗?数据在落盘是背后的glusterfs逻辑是什么?
  3. heketi要求硬盘必须是裸盘,那一块被格式化过的硬盘就真的没有办法使用了吗,这样岂不是很浪费硬件资源。

参考文章,特别感谢
https://zhuanlan.zhihu.com/p/495108133
https://www.likecs.com/show-306086916.html
https://blog.csdn.net/MssGuo/article/details/128409865

猜你喜欢

转载自blog.csdn.net/bacawa/article/details/130319878