文章目录
- 一、 前言
- 1、主机准备
- 2、准备磁盘
- 二、 安装glusterfs服务端
- 1、配置glusterfs yum源
- 2、安装gluster服务
- 3、开启服务,并做开机启动
- 4、glusterfs的端口
- 三、 安装Heketi 服务(实现k8s动态供给glusterfs存储需要用到Heketi 服务)
- 1、Heketi安装
- 2、 创建heketi用户并配置免密登录
- 3、修改heketi配置文件
- 4、启动heketi服务
- 5、配置hekeit-cli客户端工具的环境变量
- 6、设置hekeit的topology文件
- 7、测试创建存储卷
- 四、kubesphere使用glusterfs作为后端存储(动态供给glusterfs存储)
- 1、创建secret,仅存储密码
- 2、创建存储类
- 五、探究日志数据落盘到哪里了
- 六、总结
提示: 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安装
- 在线yum安装heketi服务端和客户端工具,heketi 也是在glusterfs源里面的,如果没有glusterfs源,参考上面的配置glusterfs的yum源
yum install heketi heketi-client
- #离线安装
参考官方网站 添加链接描述,下载heketi二进制包并将服务配置为systemd管理启动即可.
2、 创建heketi用户并配置免密登录
创建免密登录的用户,因为官网要求heketi主机要能免密登录到glusterfs的主机上,这里我不在创建一个heketi用户,直接使用root用户,如果是非root用户,需要有sudo权限。
#建议使用root用户做免密登录
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.54.52
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.54.53
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.54.54
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),数据依然存在,到此基本已经验证了这套解决方案,完美!
六、总结
- k8s于 v1.25 版本弃用glusterfs,glusterfs是否还受欢迎;
- k8s动态供给glusterfs存储时,heketi要求硬盘必须是裸盘,既然是裸盘,那就不需要我们参加创建文件系统,那文件随机挂载的吗?数据在落盘是背后的glusterfs逻辑是什么?
- heketi要求硬盘必须是裸盘,那一块被格式化过的硬盘就真的没有办法使用了吗,这样岂不是很浪费硬件资源。