当前位置: 首页 > news >正文

KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门

转载:KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门

知识点

  • 定级:入门级

  • GlusterFS 和 Heketi 简介

  • GlusterFS 安装部署

  • Heketi 安装部署

  • Kubernetes 命令行对接 GlusterFS

实战服务器配置(架构1:1复刻小规模生产环境,配置略有不同)

主机名IPCPU内存系统盘数据盘用途
ks-master-0192.168.9.912450100KubeSphere/k8s-master
ks-master-1192.168.9.922450100KubeSphere/k8s-master
ks-master-2192.168.9.932450100KubeSphere/k8s-master
ks-worker-0192.168.9.952450100k8s-worker/CI
ks-worker-1192.168.9.962450100k8s-worker
ks-worker-2192.168.9.972450100k8s-worker
storage-0192.168.9.812450100+ElasticSearch/GlusterFS/Ceph/Longhorn/NFS/
storage-1192.168.9.822450100+ElasticSearch/GlusterFS/Ceph/Longhorn
storage-2192.168.9.832450100+ElasticSearch/GlusterFS/Ceph/Longhorn
registry192.168.9.802450200Sonatype Nexus 3
合计1020405001100+

实战环境涉及软件版本信息

  • 操作系统:openEuler 22.03 LTS SP2 x86_64

  • KubeSphere:3.3.2

  • Kubernetes:v1.24.12

  • Containerd:1.6.4

  • KubeKey: v3.0.8

  • GlusterFS:10.0-8

  • Heketi:v10.4.0

1. 简介

上一期实战课程,我们模拟真实的生产环境实战演示了如何使用 KubeKey 将新增 Worker 节点添加到已有的 Kubernetes 集群 。最终我们部署完成了一套 3 Master 和 3 Worker 节点的 Kubernetes 集群。

本期实战课程,我们将实战如何在 openEuler 22.03 LTS SP2 上安装部署 GlusterFS、Hekeiti  以及  Kubernetes 使用 in-tree storage driver 模式对接 GlusterFS 做为集群的后端存储。

1.1 GlusterFS 是什么?

GlusterFS 是一个开源的分布式文件系统,旨在提供可扩展性、高可用性和可靠性的网络文件系统。它通过将多个存储节点组合成一个统一的存储池,为用户提供一个统一的全局文件系统。GlusterFS 具有高扩展性、高可用性、高性能、可横向扩展等特点,并且其没有元数据服务器的设计,让整个服务没有单点故障的隐患。

以下是GlusterFS的主要优点:

  • 可扩展性:GlusterFS 使用横向扩展的方法来增加存储容量和性能。它可以轻松地添加新的存储节点来满足不断增长的存储需求,无需停机或重配置。

  • 高可用性:GlusterFS 利用分布式复制和数据条带化的技术,确保数据的冗余和可用性。如果一个存储节点发生故障,数据仍然可从其他节点访问,保证了高可用性和数据的持续性。

  • 弹性和灵活性:GlusterFS 采用了无元数据服务器的分布式架构,使得存储池可以动态增加或减少。它可以根据需求自动平衡数据和负载,从而提供更好的性能和灵活性。

  • 容错能力:GlusterFS 支持纠删码和存储池快照等高级功能,可以保护数据免受硬件故障和数据损坏的影响。这种容错能力可以提高数据的安全性和可靠性。

1.2 Heketi 是什么?

Kubernetes 使用 GlusterFS 作为后端存储的场景,多数都离不开 Heketi 的身影,那么 Heketi 是什么,充当了什么角色呢?

Heketi 提供了 RESTful 管理接口,能够在 OpenStack,Kubernetes,Openshift 等云平台上实现动态存储资源供应,可用于管理 GlusterFS 卷的生命周期 (动态在 GlusterFS 集群内选择 bricks 构建 volume),支持 GlusterFS 多集群管理。

Heketi 的目标是提供一种在多个存储群集中创建,列出和删除 GlusterFS 卷的简单方法。 Heketi 将智能地管理群集中整个磁盘的分配,创建和删除。

在满足任何请求之前,Heketi 首先需要了解集群的拓扑(topologies )也就是需要配置 topologies.json 文件 。 此 json 文件将数据资源组织为以下内容:群集、节点、设备的归属、以及块的归属。

Heketi-cli 命令行工具向 Heketi 提供需要管理的 GlusterFS 集群的信息。它通过变量 HEKETI_CLI_SERVER 来获取对应的 Heketi 服务端。

Heketi项目目前处于深度维护状态。这意味着项目维护团队只考虑包含关键的错误或安全缺陷。该项目已经在 Jul 7, 2023 被存档。

因此,在 2023 年的今天,选择 Heketi + GlusterFS 的组合不是一个好的选择,请根据需求仔细评估,谨慎选择。

1.3 Kubernets 官方文档对 GlusterFS 的相关说明

先看一组不同版本的官方文档对 GlusterFS 存储的介绍。

  • v1.24

  • v1.25

  • v1.26

  • v1.27

通过上面的图可以看出,Kubernet v1.24、v1.25 还是可以使用 GlusterFS的,到了 v1.26 开始 已经无法使用 in-tree storage driver 的方式使用 GlusterFS 存储。

但是,并不是说 Kubernetes 不再支持 GlusterFS 了,只是将 Driver 换成了 Container Storage Interface (CSI) volume plugins 模式,具体可以参考 gluster-csi-driver 官方文档。

对于 CSI 模式本文不做过多介绍,后期会专门做一期相关的实战课程。

1.4 Kubernetes 使用 GlusterFS 存储的方式

  • 通过 Heketi 管理 GlusterFS,Kubernetes 调用 Heketi 的接口

  • GlusterFS 结合 NFS-Ganesha 提供 NFS 存储,Kubernetes 采用 NFS 的方式挂载

  • Kubernetes 挂载 GlusterFS 提供的数据卷到本地的存储目录,Kubernetes 采用 hostpatch 的方式

  • Container Storage Interface (CSI) volume plugins(更符合标准规范,可能是更好的选择)

1.5 Kubernetes 对接 GlusterFS 架构

2. 存储服务器初始化配置

请注意,以下操作无特殊说明时需在所有存储节点上执行。本文只选取 Storage-0 节点作为演示,并假定其余服务器都已按照相同的方式进行配置和设置。

2.1 配置主机名


hostnamectl hostname ks-storage-0

2.2 配置 hosts 文件

编辑 /etc/hosts 文件,将规划的服务器 IP 和主机名添加到文件中。


192.168.9.81    ks-storage-0
192.168.9.82    ks-storage-1
192.168.9.83    ks-storage-2

2.3 配置 DNS


echo "nameserver 114.114.114.114" > /etc/resolv.conf

2.4 配置服务器时区

配置服务器时区为 Asia/Shanghai


timedatectl set-timezone Asia/Shanghai

验证服务器时区,正确配置如下。


[root@ks-storage-0 ~]# timedatectlLocal time: Mon 2023-07-17 14:52:33 CSTUniversal time: Mon 2023-07-17 06:52:33 UTCRTC time: Mon 2023-07-17 06:52:33Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yesNTP service: activeRTC in local TZ: no

2.5 配置时间同步

安装 chrony 作为时间同步软件。


yum install chrony 

修改配置文件 /etc/chrony.conf,修改 ntp 服务器配置。


vi /etc/chrony.conf# 删除所有的 pool 配置
pool pool.ntp.org iburst# 增加国内的 ntp 服务器,或是指定其他常用的时间服务器
pool cn.pool.ntp.org iburst# 上面的手工操作,也可以使用 sed 自动替换
sed -i 's/^pool pool.*/pool cn.pool.ntp.org iburst/g' /etc/chrony.conf

重启并设置 chrony 服务开机自启动。

systemctl enable chronyd --now

验证 chrony 同步状态。


# 执行查看命令
chronyc sourcestats -v# 正常的输出结果如下[root@ks-storage-0 ~]# chronyc sourcestats -v.- Number of sample points in measurement set./    .- Number of residual runs with same sign.|    /    .- Length of measurement set (time).|   |    /      .- Est. clock freq error (ppm).|   |   |      /           .- Est. error in freq.|   |   |     |           /         .- Est. offset.|   |   |     |          |          |   On the -.|   |   |     |          |          |   samples. \|   |   |     |          |          |             |
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
time.neu.edu.cn            27  13  139m     -0.281      0.837  -1133us  2519us
time.cloudflare.com        22  12  127m     -0.533      2.392    -10ms  4458us
time.neu.edu.cn            32  17  105m     +0.084      0.865    +94us  2046us
time.cloudflare.com        21  10  155m     -0.035      2.036  -4566us  5600us

2.6 关闭系统防火墙

systemctl stop firewalld && systemctl disable firewalld

2.7 禁用 SELinux

openEuler 22.03 SP2 最小化安装的系统默认启用了 SELinux,为了减少麻烦,我们所有的节点都禁用 SELinux。


# 使用 sed 修改配置文件,实现彻底的禁用
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config# 使用命令,实现临时禁用,这一步其实不做也行,KubeKey 会自动配置
setenforce 0

2.8 安装系统工具包


yum install tar

2.9 配置 SSH 配置文件

所有节点必须要配置,否则,后面 Heketi 创建集群的时候会报错(报错信息详见问题4)!!!


echo PubkeyAcceptedKeyTypes=+ssh-rsa >> /etc/ssh/sshd_config
echo HostKeyAlgorithms=+ssh-rsa >> /etc/ssh/sshd_config
systemctl restart sshd

3. GlusterFS 安装配置

3.1 部署过程概览

安装配置 GlusterFS 服务采用 Ansible 自动化部署,主要包括以下操作步骤

  • 配置 YUM 源

  • 安装 GlusterFS

  • 启动 glusterd 服务

  • 配置可信池

3.2 安装 GlusterFS 服务

  1. 安装 GlusterFS 服务

openEuler 默认软件仓库里已经包含了 GlusterFS 相关软件包,无需额外配置。


# 查询 glusterfs-server 是否存在
yum search glusterfs-server# 安装 glusterfs-server
yum install glusterfs-server

2.启动并设置开机自启动 glusterd 服务

systemctl enable glusterd --now

3.验证 GlusterFS 服务状态

验证服务状态

systemctl status glusterd

验证服务端口状态

ss -ntlup | grep glusterd

任务执行正确的输出结果如下:

# 服务状态
[root@ks-storage-0 ~]# systemctl status glusterd
● glusterd.service - GlusterFS, a clustered file-system serverLoaded: loaded (/usr/lib/systemd/system/glusterd.service; enabled; vendor preset: disabled)Active: active (running) since Mon 2023-07-17 15:22:00 CST; 33s agoDocs: man:glusterd(8)Process: 2585 ExecStart=/usr/sbin/glusterd -p /var/run/glusterd.pid --log-level $LOG_LEVEL $GLU>Main PID: 2586 (glusterd)Tasks: 24 (limit: 21602)Memory: 16.3MCGroup: /system.slice/glusterd.service└─ 2586 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFOJul 17 15:22:00 ks-storage-0 systemd[1]: Starting GlusterFS, a clustered file-system server...
Jul 17 15:22:00 ks-storage-0 systemd[1]: Started GlusterFS, a clustered file-system server.# 服务端口状态[root@ks-storage-0 ~]# ss -ntlup | grep glusterd
tcp   LISTEN 0      1024         0.0.0.0:24007      0.0.0.0:*    users:(("glusterd",pid=2586,fd=13))

3.4 检测 GlusterFS 集群节点之间的连通性

在执行接下来的任务之前,利用 ping 验证 GlusterFS 集群节点之间的连通性。

  • 利用节点 0,ping 测节点 1

$ ping ks-storege-1 -c 2# 正确结果
[root@ks-storage-0 ~]# ping ks-storage-1 -c 2
PING ks-storage-1 (192.168.9.82) 56(84) bytes of data.
64 bytes from ks-storage-1 (192.168.9.82): icmp_seq=1 ttl=64 time=0.276 ms
64 bytes from ks-storage-1 (192.168.9.82): icmp_seq=2 ttl=64 time=0.324 ms--- ks-storage-1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1059ms
rtt min/avg/max/mdev = 0.276/0.300/0.324/0.024 ms
  • 利用节点 0,ping 测节点 2

$ ping ks-storage-2 -c 2# 正确结果
[root@ks-storage-0 ~]# ping ks-storage-2 -c 2
PING ks-storage-2 (192.168.9.83) 56(84) bytes of data.
64 bytes from ks-storage-2 (192.168.9.83): icmp_seq=1 ttl=64 time=0.552 ms
64 bytes from ks-storage-2 (192.168.9.83): icmp_seq=2 ttl=64 time=0.346 ms--- ks-storage-2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.346/0.449/0.552/0.103 mstime 999ms
rtt min/avg/max/mdev = 0.206/0.256/0.307/0.052 ms

3.5 配置可信池 (Configure the trusted pool)

  1. 使用管理命令 gluster 创建可信池子


gluster peer probe ks-storage-1
gluster peer probe ks-storage-2

任务执行正确的输出结果


[root@ks-storage-0 ~]# gluster peer probe ks-storage-1
peer probe: success
[root@ks-storage-0 ~]# gluster peer probe ks-storage-2
peer probe: success

2.检查 Peer 状态


gluster peer status

任务执行正确的输出结果

[root@ks-storage-0 ~]# gluster peer status
Number of Peers: 2Hostname: ks-storage-1
Uuid: 0d1fd33c-d2ef-4f04-a9fe-82287066f56c
State: Peer in Cluster (Connected)Hostname: ks-storage-2
Uuid: 5ea6d93f-6882-4928-9483-33068b05ece4
State: Peer in Cluster (Connected)

4. Heketi 安装配置

在 GlusterFs 服务器中任选一个节点部署 Heketi, 默认选择节点 0,ks-storage-0,也可以将 Heketi 独立部署

4.1 安装 Heketi

由于 openEuler 官方仓库并没有 heketi 的相关软件包,因此,本节选择手工安装 heketi 的方式。

  1. 在 GitHub heketi 发布页面下载最新的二进制发行包


cd /root
wget https://github.com/heketi/heketi/releases/download/v10.4.0/heketi-v10.4.0

2.解压 heketi


tar xvf heketi-v10.4.0-release-10.linux.amd64.tar.gz
cd heketi
cp heketi heketi-cli /usr/bin/

3.创建服务启动用户


useradd -d /var/lib/heketi -s /sbin/nologin heketi

4.创建 heketi 服务配置文件目录


mkdir /etc/heketi

5.创建 hekiti system 服务文件

vi /usr/lib/systemd/system/heketi.service

[Unit]
Description=Heketi Server[Service]
Type=simple
WorkingDirectory=/var/lib/heketi
User=heketi
ExecStart=/usr/bin/heketi --config=/etc/heketi/heketi.json
Restart=on-failure
StandardOutput=syslog
StandardError=syslog[Install]
WantedBy=multi-user.target

4.2 配置 Heketi

1.创建用于管理用的 SSH 密钥

ssh-keygen -N '' -t rsa -q -f /etc/heketi/heketi_key# 设置权限,否则后面会报错
chmod 0600 /etc/heketi/heketi_key.pub
chown heketi.heketi /etc/heketi/heketi_key*

2.分发 pub 密钥到所有节点

ssh-copy-id -i /etc/heketi/heketi_key.pub root@ks-storage-0
ssh-copy-id -i /etc/heketi/heketi_key.pub root@ks-storage-1
ssh-copy-id -i /etc/heketi/heketi_key.pub root@ks-storage-2

3.验证免密登陆

ssh -i /etc/heketi/heketi_key root@ks-storage-0

4.创建 Heketi 服务配置文件

本文使用必要的配置项编写配置文件,更多的配置文件的写法和说明可以参考下载的源码中的示例。

vi /etc/heketi/heketi.json

{"_port_comment": "Heketi Server Port Number","port": "18080","_use_auth": "Enable JWT authorization. Please enable for deployment","use_auth": true,"_jwt": "Private keys for access","jwt": {"_admin": "Admin has access to all APIs","admin": {"key": "admin@P@88W0rd"},"_user": "User only has access to /volumes endpoint","user": {"key": "user@P@88W0rd"}},"_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","_sshexec_comment": "SSH username and private key file information","sshexec": {"keyfile": "/etc/heketi/heketi_key","user": "root","port": "22","fstab": "/etc/fstab"},"_kubeexec_comment": "Kubernetes configuration","kubeexec": {"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","_loglevel_comment": ["Set log level. Choices are:","  none, critical, error, warning, info, debug","Default is warning"],"loglevel" : "warning"}
}

需要根据实际环境修改的参数说明

  • jwt.admin.key:连接 heketi 时,admin 用户的密码

  • jwt.user.key: 连接 heketi 时,user 用户的密码

  • port: heketi 服务的端口号

  • loglevel:唯一可选配置, log 日志输出的级别,开发环境可以设置为 debug,生产环境建议 warning

4.3 启动 Heketi 服务

  • 启动并设置开机自动启动 heketi 服务

systemctl enable heketi --now
  • 查看 heketi 服务状态

systemctl status heketi -l

服务正常启动结果

[root@ks-storage-0 ~]# systemctl status heketi -l
● heketi.service - Heketi ServerLoaded: loaded (/usr/lib/systemd/system/heketi.service; enabled; vendor preset: disabled)Active: active (running) since Mon 2023-07-17 17:31:40 CST; 18s agoMain PID: 3320 (heketi)Tasks: 7 (limit: 21602)Memory: 7.2MCGroup: /system.slice/heketi.service└─ 3320 /usr/bin/heketi --config=/etc/heketi/heketi.jsonJul 17 17:31:40 ks-storage-0 systemd[1]: Started Heketi Server.
Jul 17 17:31:40 ks-storage-0 heketi[3320]: Heketi v10.4.0-release-10 (using go: go1.15.14)
Jul 17 17:31:40 ks-storage-0 heketi[3320]: 2023/07/17 17:31:40 no SSH_KNOWN_HOSTS specified, skipping ssh host verification
Jul 17 17:31:40 ks-storage-0 heketi[3320]: Listening on port 18080
  • 查看接口状态

curl http://192.168.9.81:18080/hello

注意:192.168.9.81 为安装 heketi 服务的节点 IP,实际使用中注意替换。

接口正常输出结果

[root@ks-storage-0 ~]# curl http://192.168.9.81:18080/hello
Hello from Heketi

4.4 配置存储

  1. 创建存储集群拓扑文件,该文件包含添加到 Heketi 的集群、节点和磁盘的信息。

vi /etc/heketi/topology.json


{"clusters": [{"nodes": [{"node": {"hostnames": {"manage": ["192.168.9.81"],"storage": ["192.168.9.81"]},"zone": 1},"devices": ["/dev/sdb"]},{"node": {"hostnames": {"manage": ["192.168.9.82"],"storage": ["192.168.9.82"]},"zone": 1},"devices": ["/dev/sdb"]},{"node": {"hostnames": {"manage": ["192.168.9.83"],"storage": ["192.168.9.83"]},"zone": 1},"devices": ["/dev/sdb"]}]}]
}

说明:

  • manage 和 storage: 一定要填写对应节点 IP,使用主机名后面会报错。

  • devices:填写磁盘的全路径名称,可以写多个,一定要使用裸盘名不要使用分区名,也不需要给磁盘提前分区

2.根据拓扑文件创建集群

heketi-cli --server http://192.168.9.81:18080 --user admin --secret admin@P@88W0rd topology load --json=/etc/heketi/topology.json

正确的输出结果如下:


[root@ks-storage-0 ~]# heketi-cli --server http://192.168.9.81:18080 --user admin --secret admin@P@88W0rd topology load --json=/etc/heketi/topology.json
Creating cluster ... ID: 9ad37206ce6575b5133179ba7c6e0935Allowing file volumes on cluster.Allowing block volumes on cluster.Creating node 192.168.9.81 ... ID: 0108350a9d13578febbfd0502f8077ffAdding device /dev/sdb ... OKCreating node 192.168.9.82 ... ID: 5e99fe0cd727b8066f200bad5524c544Adding device /dev/sdb ... OKCreating node 192.168.9.83 ... ID: 7bb26eb30c1c61456b5ae8d805c01cf1Adding device /dev/sdb ... OK

3.配置heketi管理用环境变量

为了方便日后的运维管理,将 heketi-cli 的常用参数和命令组合成一条 alias 命令。


echo "alias heketi-cli='heketi-cli --server http://192.168.9.81:18080 --user admin --secret admin@P@88W0rd'" >> ~/.bashrc

验证 Alias 别名是否生效

source ~/.bashrc
heketi-cli cluster list# 返回如下结果,说明配置成功
[root@ks-storage-0 ~]# heketi-cli cluster list
Clusters:
Id:9ad37206ce6575b5133179ba7c6e0935 [file][block]

4.5 功能验证测试

  • 查看集群列表


[root@ks-storage-0 ~]# heketi-cli cluster list
Clusters:
Id:9ad37206ce6575b5133179ba7c6e0935 [file][block]
  • 查看集群详细信息

[root@ks-storage-0 ~]# heketi-cli cluster info 9ad37206ce6575b5133179ba7c6e0935
Cluster id: 9ad37206ce6575b5133179ba7c6e0935
Nodes:
0108350a9d13578febbfd0502f8077ff
5e99fe0cd727b8066f200bad5524c544
7bb26eb30c1c61456b5ae8d805c01cf1
Volumes:Block: trueFile: true
  • 查看集群节点列表


[root@ks-storage-0 ~]# heketi-cli node list
Id:0108350a9d13578febbfd0502f8077ff     Cluster:9ad37206ce6575b5133179ba7c6e0935
Id:5e99fe0cd727b8066f200bad5524c544     Cluster:9ad37206ce6575b5133179ba7c6e0935
Id:7bb26eb30c1c61456b5ae8d805c01cf1     Cluster:9ad37206ce6575b5133179ba7c6e0935
  • 创建卷

# 创建一个2G大小3副本的卷[root@ks-storage-0 ~]# heketi-cli volume create --size=2 --replica=3
Name: vol_2a8574593fc69b25cd6e2f5750655be2
Size: 2
Volume Id: 2a8574593fc69b25cd6e2f5750655be2
Cluster Id: 9ad37206ce6575b5133179ba7c6e0935
Mount: 192.168.9.81:vol_2a8574593fc69b25cd6e2f5750655be2
Mount Options: backup-volfile-servers=192.168.9.82,192.168.9.83
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distribute Count: 1
Replica Count: 3
  • 查看创建的卷

[root@ks-storage-0 ~]# heketi-cli volume list
Id:2a8574593fc69b25cd6e2f5750655be2    Cluster:9ad37206ce6575b5133179ba7c6e0935    Name:vol_2a8574593fc69b25cd6e2f5750655be2
  • 查看服务器挂载点

[root@ks-storage-0 ~]# df -h
Filesystem                                                                              Size  Used Avail Use% Mounted on
devtmpfs                                                                                4.0M     0  4.0M   0% /dev
tmpfs                                                                                   1.7G     0  1.7G   0% /dev/shm
tmpfs                                                                                   682M   17M  666M   3% /run
tmpfs                                                                                   4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mapper/openeuler-root                                                               17G  1.6G   15G  10% /
tmpfs                                                                                   1.7G     0  1.7G   0% /tmp
/dev/sda1                                                                               974M  151M  756M  17% /boot
/dev/mapper/vg_9af38756fe916fced666fcd3de786c19-brick_d5bf4398fc579087ceb11cc5910c5215  2.0G   47M  2.0G   3% /var/lib/heketi/mounts/vg_9af38756fe916fced666fcd3de786c19/brick_d5bf4398fc579087ceb11cc5910c5215
  • 挂载测试-挂载卷


[root@ks-storage-0 ~]# mount -t glusterfs 192.168.9.81:vol_2a8574593fc69b25cd6e2f5750655be2 /mnt/# mount 命令中的 192.168.9.82:vol_a2a8574593fc69b25cd6e2f5750655be2 为上方 heketi-cli volum create 时,命令结果返回值 Mount 字段的值。
# 也可以使用 heketi-cli volume info 2a8574593fc69b25cd6e2f5750655be2 获取
  • 查看挂载详情


[root@ks-storage-0 ~]# df -h
Filesystem                                                                              Size  Used Avail Use% Mounted on
devtmpfs                                                                                4.0M     0  4.0M   0% /dev
tmpfs                                                                                   1.7G     0  1.7G   0% /dev/shm
tmpfs                                                                                   682M   17M  666M   3% /run
tmpfs                                                                                   4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mapper/openeuler-root                                                               17G  1.6G   15G  10% /
tmpfs                                                                                   1.7G     0  1.7G   0% /tmp
/dev/sda1                                                                               974M  151M  756M  17% /boot
/dev/mapper/vg_9af38756fe916fced666fcd3de786c19-brick_d5bf4398fc579087ceb11cc5910c5215  2.0G   47M  2.0G   3% /var/lib/heketi/mounts/vg_9af38756fe916fced666fcd3de786c19/brick_d5bf4398fc579087ceb11cc5910c5215
192.168.9.81:vol_2a8574593fc69b25cd6e2f5750655be2
  • 写入文件测试


[root@ks-storage-0 ~]# echo "`date` test write" >> /mnt/test.txt[root@ks-storage-0 ~]# cat /mnt/test.txt
Tue Jul 18 02:47:25 PM CST 2023 test write

4.6 清理测试数据

测试完成后,删除测试卷。

  • 删除测试卷


[root@ks-storage-0 ~]# umount  /mnt/[root@ks-storage-0 ~]# heketi-cli volume delete 2a8574593fc69b25cd6e2f5750655be2
Volume 2a8574593fc69b25cd6e2f5750655be2 deleted
  • 查看测试挂载情况


[root@ks-storage-0 ~]# df -h
Filesystem                  Size  Used Avail Use% Mounted on
devtmpfs                    4.0M     0  4.0M   0% /dev
tmpfs                       1.7G     0  1.7G   0% /dev/shm
tmpfs                       682M   25M  658M   4% /run
tmpfs                       4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mapper/openeuler-root   17G  1.6G   15G  10% /
tmpfs                       1.7G     0  1.7G   0% /tmp
/dev/sda1                   974M  151M  756M  17% /boot

5. K8s 集群对接 GlusterFS

如无特殊说明,所有涉及 k8s 的操作都在 master-0 节点上执行 , 操作根目录为 /srv/opsman/k8s-yaml

主要的操作过程包含:

  • 安装 GlusterFS 客户端

  • 创建 Secret

  • 创建 StorageClass

  • 创建测试 PVC

  • 创建测试 POD

5.1 安装 glusterfs 客户端

所有 k8s 集群中的节点都需要安装

yum install glusterfs-fuse -y

5.2 创建 heketi 使用的 Secret 的认证密码

  • 创建 glusterfs 目录 , 并切换到该目录

mkdir -p /srv/opsman/k8s-yaml/glusterfs
cd /srv/opsman/k8s-yaml/glusterfs
  • 使用 base64 将密码转码生成 Secret key 使用的值 , 这里的密码为 heketi 配置文件中创建的用户密码


[root@ks-k8s-master-0 glusterfs]# echo -n "admin@P@88W0rd" | base64
YWRtaW5AUEA4OFcwcmQ=
  • 创建 Secret 资源清单文件,执行 vi heketi-secret.yaml


apiVersion: v1
kind: Secret
metadata:name: heketi-secretnamespace: kube-system
data:key: YWRtaW5AUEA4OFcwcmQ=
type: kubernetes.io/glusterfs
  • 创建资源


kubectl apply -f heketi-secret.yaml
  • 验证资源


[root@ks-master-0 glusterfs]# kubectl get secrets heketi-secret -n kube-system
NAME            TYPE                      DATA   AGE
heketi-secret   kubernetes.io/glusterfs   1      9s

5.3 创建 StorageClass

  • 创建 StorageClass 资源清单文件,执行 vi heketi-storageclass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: glusterfsnamespace: kube-system
parameters:resturl: "http://192.168.9.81:18080"clusterid: "9ad37206ce6575b5133179ba7c6e0935"restauthenabled: "true" restuser: "admin"secretName: "heketi-secret"secretNamespace: "kube-system"volumetype: "replicate:3" 
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete

参数说明

  • parameters.resturl: heketi 服务的管理地址

  • parameters.clusterid: 在 heketi 节点使用 heketi-cli cluster list 命令返回的集群 id

  • parameters.restuser:  heketi.json 配置文件中创建的用户名,默认 admin

  • parameters.secretName: k8s 中 Secret 资源定义中的 metadata.name

  • parameters.secretNamespace: k8s 中 Secret 资源定义中的 metadata.namespace

  • parameters.volumetype: 创建的卷类型和副本数,这里是 3 副本复制卷

  • 创建资源


kubectl apply -f heketi-storageclass.yaml
  • 验证资源

[root@ks-master-0 glusterfs]# kubectl get sc
NAME              PROVISIONER               RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
glusterfs         kubernetes.io/glusterfs   Delete          Immediate              false                  10s
local (default)   openebs.io/local          Delete          WaitForFirstConsumer   false                  163m

5.4 创建 pvc 测试

  • 创建 pvc 资源清单文件,执行 vi heketi-pvc.yaml


apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: heketi-pvc-testannotations:volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
spec:storageClassName: "glusterfs"accessModes:- ReadWriteOnceresources:requests:storage: 1Gi
  • 创建资源

kubectl apply -f heketi-pvc.yaml 
  • 验证资源


[root@ks-master-0 glusterfs]# kubectl get pvc -o wide
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
heketi-pvc-test   Bound    pvc-ea179e62-a35c-4f60-8038-c80d0832823b   1Gi        RWO            glusterfs      9s    Filesystem

注意:创建的 pvc 的状态,如果是 Pending,说明连接存储有问题


[root@ks-master-0 glusterfs]# kubectl get pvc -o wide
NAME              STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
heketi-pvc-test   Pending                                      glusterfs      9s    Filesystem
  • 查看 SVC


[root@ks-master-0 glusterfs]# kubectl get svc -o wide
NAME                                                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE     SELECTOR
glusterfs-dynamic-ea179e62-a35c-4f60-8038-c80d0832823b   ClusterIP   10.233.50.196   <none>        1/TCP     54s     <none>
kubernetes                                               ClusterIP   10.233.0.1      <none>        443/TCP   3h29m   <none>

5.5 创建测试 Pod 挂载 pvc

  • 创建 Pod 资源清单文件,执行 vi heketi-pod.yaml

kind: Pod
apiVersion: v1
metadata:name: heketi-pod-test
spec:containers:- name: heketi-containerimage: busyboxcommand:- sleep- "3600"volumeMounts:- name: heketi-volumemountPath: "/pv-data"readOnly: falsevolumes:- name: heketi-volumepersistentVolumeClaim:claimName: heketi-pvc-test
  • 创建资源

kubectl apply -f heketi-pod.yaml 
  • 验证资源


[root@ks-master-0 glusterfs]# kubectl get pods -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP             NODE          NOMINATED NODE   READINESS GATES
heketi-pod-test   1/1     Running   0          18s   10.233.118.1   ks-worker-2   <none>           <none>
  • 查看 Pod 中磁盘挂载情况

[root@ks-master-0 glusterfs]# kubectl exec heketi-pod-test -- df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                  16.6G      3.7G     12.0G  23% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                     1.7G         0      1.7G   0% /sys/fs/cgroup
192.168.9.82:vol_308eec3ff24a3684b4f63c67c7d524121006.0M     49.8M    956.2M   5% /pv-data
/dev/mapper/openeuler-root16.6G      3.7G     12.0G  23% /etc/hosts
/dev/mapper/openeuler-root16.6G      3.7G     12.0G  23% /dev/termination-log
/dev/mapper/openeuler-root16.6G      3.7G     12.0G  23% /etc/hostname
/dev/mapper/openeuler-root16.6G      3.7G     12.0G  23% /etc/resolv.conf
shm                      64.0M         0     64.0M   0% /dev/shm
tmpfs                     2.7G     12.0K      2.7G   0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs                     1.7G         0      1.7G   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                     1.7G         0      1.7G   0% /proc/scsi
tmpfs                     1.7G         0      1.7G   0% /sys/firmware
  • 登录 Pod 所在的节点,查看磁盘挂载情况

SSH 登录到节点 ks-worker-2


[root@ks-worker-2 ~]# df -h
Filesystem                                         Size  Used Avail Use% Mounted on
devtmpfs                                           4.0M     0  4.0M   0% /dev
tmpfs                                              1.7G     0  1.7G   0% /dev/shm
tmpfs                                              682M  9.6M  673M   2% /run
tmpfs                                              4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mapper/openeuler-root                          17G  3.7G   13G  24% /
tmpfs                                              1.7G     0  1.7G   0% /tmp
/dev/sda1                                          974M  151M  756M  17% /boot
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/e18f876d9e4de19985cd47e0c07e28b70c8cd65eac17a0d3e9d17da0715dd1fa/shm
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/e18f876d9e4de19985cd47e0c07e28b70c8cd65eac17a0d3e9d17da0715dd1fa/rootfs
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/83c6f14ac6d4ff38cd46499f3b95bb4b4d421badb49b322373eedf1eb906fc1d/rootfs
tmpfs                                              170M   12K  170M   1% /var/lib/kubelet/pods/e10e996f-ef79-4d3a-87a3-fad668070894/volumes/kubernetes.io~projected/kube-api-access-w8pk6
tmpfs                                              2.7G   12K  2.7G   1% /var/lib/kubelet/pods/8ddc8c7c-88ee-41c2-9fb8-8535a02d3e21/volumes/kubernetes.io~projected/kube-api-access-rdrlx
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/c47815a2e729725b1dfb5f80265a2fbf32c6ae1149515cdb02ecce90d609014c/shm
tmpfs                                              600M   12K  600M   1% /var/lib/kubelet/pods/d771e322-79a1-4e40-9347-85db30d864e0/volumes/kubernetes.io~projected/kube-api-access-94wt8
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/c47815a2e729725b1dfb5f80265a2fbf32c6ae1149515cdb02ecce90d609014c/rootfs
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/beb9d1a35c92ee556470bbb8a081aaad84d5b2a1aa476ece85d96efd7a27aa50/shm
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/beb9d1a35c92ee556470bbb8a081aaad84d5b2a1aa476ece85d96efd7a27aa50/rootfs
tmpfs                                              2.7G   12K  2.7G   1% /var/lib/kubelet/pods/efc3ad2a-298f-4b0b-a560-db27d33292ac/volumes/kubernetes.io~projected/kube-api-access-hml7k
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/f8cb26e1641b56c0c80d69bb75266aeaa1ed9cbeaa5b19f5feba97c7953b2d0d/rootfs
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/a09a1428ce0f56562c66f5d47a053171c6a2b262220a02241434da2a2f439c04/shm
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/a09a1428ce0f56562c66f5d47a053171c6a2b262220a02241434da2a2f439c04/rootfs
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/4cfa7ba601638ca8a195a86c265246874d0bf3c5d1c7b1ecd26229f95b223285/shm
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/4cfa7ba601638ca8a195a86c265246874d0bf3c5d1c7b1ecd26229f95b223285/rootfs
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/47b70d46a13b3f63434ace89cbe9ba0fb895d35bef35f53d3b55449e05910562/rootfs
tmpfs                                              2.7G   12K  2.7G   1% /var/lib/kubelet/pods/729df129-5adb-4080-82c3-51f9ff206b65/volumes/kubernetes.io~projected/kube-api-access-4tpsv
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/91a3b0efd570cefcc7609e579af3db7e3491cb5205e8c77236d4cc520b988472/rootfs
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/8d9cb96afc1be06f3214c1887b30bbccbbdd0d73124eaf7ce76e56b731239a5f/rootfs
192.168.9.82:vol_308eec3ff24a3684b4f63c67c7d52412 1006M   50M  957M   5% /var/lib/kubelet/pods/729df129-5adb-4080-82c3-51f9ff206b65/volumes/kubernetes.io~glusterfs/pvc-ea179e62-a35c-4f60-8038-c80d0832823b
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/656b76fdf7d615bd467a1697a741f7933982d69b6520ab0a603bcd74f3a72e5b/rootfs
shm                                                 64M     0   64M   0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/83e3b8baec8fa7f386f0cff2be3c158d5b491848fee942f29f01c44eaa0fe724/shm
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/83e3b8baec8fa7f386f0cff2be3c158d5b491848fee942f29f01c44eaa0fe724/rootfs
overlay                                             17G  3.7G   13G  24% /run/containerd/io.containerd.runtime.v2.task/k8s.io/1c12ffabfb40427232063c51a267cb314e4d1e16a2fe8324f18df407a0f15aa3/rootfs

5.6 登录存储服务器查看底层变化

  • SSH 登录到节点 ks-storage-0


$ ssh ks-storage-0
  • 查看卷的信息

[root@ks-storage-0 ~]# heketi-cli volume list
Id:308eec3ff24a3684b4f63c67c7d52412    Cluster:9ad37206ce6575b5133179ba7c6e0935    Name:vol_308eec3ff24a3684b4f63c67c7d52412[root@ks-storage-0 ~]# heketi-cli volume info 308eec3ff24a3684b4f63c67c7d52412
Name: vol_308eec3ff24a3684b4f63c67c7d52412
Size: 1
Volume Id: 308eec3ff24a3684b4f63c67c7d52412
Cluster Id: 9ad37206ce6575b5133179ba7c6e0935
Mount: 192.168.9.81:vol_308eec3ff24a3684b4f63c67c7d52412
Mount Options: backup-volfile-servers=192.168.9.82,192.168.9.83
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distribute Count: 1
Replica Count: 3
Snapshot Factor: 1.00
  • 查看 VG 信息

[root@ks-storage-0 ~]# vgdisplay--- Volume group ---VG Name               vg_9af38756fe916fced666fcd3de786c19System IDFormat                lvm2Metadata Areas        1Metadata Sequence No  14VG Access             read/writeVG Status             resizableMAX LV                0Cur LV                2Open LV               1Max PV                0Cur PV                1Act PV                1VG Size               99.87 GiBPE Size               4.00 MiBTotal PE              25567Alloc PE / Size       260 / <1.02 GiBFree  PE / Size       25307 / <98.86 GiBVG UUID               jrxfIv-Fnjq-IYF8-aubc-t2y0-zwUp-YxjkDC
  • 查看 LV 信息

[root@ks-storage-0 ~]# lvdisplay--- Logical volume ---LV Name                tp_75a46d674329f9f64bdce45666679172VG Name                vg_9af38756fe916fced666fcd3de786c19LV UUID                D2eUjQ-JMW1-zken-0wGd-OV0C-0Cdf-0fJb33LV Write Access        read/write (activated read only)LV Creation host, time ks-storage-0, 2023-07-18 14:52:04 +0800LV Pool metadata       tp_75a46d674329f9f64bdce45666679172_tmetaLV Pool data           tp_75a46d674329f9f64bdce45666679172_tdataLV Status              available# open                 0LV Size                1.00 GiBAllocated pool data    2.00%Allocated metadata     10.45%Current LE             256Segments               1Allocation             inheritRead ahead sectors     auto- currently set to     8192Block device           253:5--- Logical volume ---LV Path                /dev/vg_9af38756fe916fced666fcd3de786c19/brick_c74a94a24dd04c89cefd8e8c7e5f9aebLV Name                brick_c74a94a24dd04c89cefd8e8c7e5f9aebVG Name                vg_9af38756fe916fced666fcd3de786c19LV UUID                PaQuh1-2LTW-BGBL-QBBb-RZXf-szid-gVsRPzLV Write Access        read/writeLV Creation host, time ks-storage-0, 2023-07-18 14:52:04 +0800LV Pool name           tp_75a46d674329f9f64bdce45666679172LV Status              available# open                 1LV Size                1.00 GiBMapped size            2.00%Current LE             256Segments               1Allocation             inheritRead ahead sectors     auto- currently set to     8192Block device           253:6... 下面是操作系统的 lv 信息,忽略展示

5.7 KubeSphere 管理控制台查验

接下来我们看几张图,看一下在底层创建的存储资源在 KubeSphere 管理控制台中能展示哪些,又是如何展示的?

  • 存储类

  • 持久卷声明

  • 服务

5.8 清理测试资源

  • 清理测试的 Pod、pvc


kubectl delete -f heketi-pod.yaml -f heketi-pvc.yaml 

至此,我们完成了 GlusterFS 安装配置、初始化,Heketi 安装配置、集群创建,实现了 Kubernetes 集群和 GlusterFS 存储的对接,并验证测试了存储卷的创建和使用。

6. 常见问题

问题 1

  • 报错信息


[root@ks-storage-0 heketi]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@ks-storeage-0
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/etc/heketi/heketi_key.pub"
mktemp: failed to create directory via template ‘/root/.ssh/ssh-copy-id.XXXXXXXXXX’: No such file or directory
/usr/bin/ssh-copy-id: ERROR: failed to create required temporary directory under ~/.ssh
  • 解决方案


# 在 /root/.ssh/ 生成一套密钥对
ssh-keygen -t ed25519

问题 2

报错信息


[root@ks-storage-0 heketi]# ssh -i /etc/heketi/heketi_key.pub root@ks-storage-0Authorized users only. All activities may be monitored and reported.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/etc/heketi/heketi_key.pub' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/etc/heketi/heketi_key.pub": bad permissions
root@ks-storage-0's password:
  • 解决方案


# 设置 pub 密钥权限
chmod 0600 /etc/heketi/heketi_key.pub

问题 3

  • 报错信息


[root@ks-storage-0 ~]# systemctl status heketi -l
× heketi.service - Heketi ServerLoaded: loaded (/usr/lib/systemd/system/heketi.service; enabled; vendor preset: disabled)Active: failed (Result: exit-code) since Mon 2023-07-17 17:29:01 CST; 38s agoProcess: 3297 ExecStart=/usr/bin/heketi --config=/etc/heketi/heketi.json (code=exited, status=1/FAILURE)Main PID: 3297 (code=exited, status=1/FAILURE)Jul 17 17:29:00 ks-storage-0 systemd[1]: heketi.service: Main process exited, code=exited, status=1/FAILURE
Jul 17 17:29:00 ks-storage-0 systemd[1]: heketi.service: Failed with result 'exit-code'.
Jul 17 17:29:01 ks-storage-0 systemd[1]: heketi.service: Scheduled restart job, restart counter is at 5.
Jul 17 17:29:01 ks-storage-0 systemd[1]: Stopped Heketi Server.
Jul 17 17:29:01 ks-storage-0 systemd[1]: heketi.service: Start request repeated too quickly.
Jul 17 17:29:01 ks-storage-0 systemd[1]: heketi.service: Failed with result 'exit-code'.
Jul 17 17:29:01 ks-storage-0 systemd[1]: Failed to start Heketi Server.
[root@ks-storage-0 ~]# tail /var/log/messages
Jul 17 17:29:00 MiWiFi-RA67-srv heketi[3297]: [cmdexec] ERROR 2023/07/17 17:29:00 heketi/executors/sshexec/sshexec.go:137:sshexec.NewSshExecutor: Unable to read private key file
Jul 17 17:29:00 MiWiFi-RA67-srv heketi[3297]: [heketi] ERROR 2023/07/17 17:29:00 heketi/apps/glusterfs/app.go:158:glusterfs.(*App).setup: Unable to read private key file
Jul 17 17:29:00 MiWiFi-RA67-srv heketi[3297]: ERROR: Unable to start application: Unable to read private key file
Jul 17 17:29:00 MiWiFi-RA67-srv systemd[1]: heketi.service: Main process exited, code=exited, status=1/FAILURE
Jul 17 17:29:00 MiWiFi-RA67-srv systemd[1]: heketi.service: Failed with result 'exit-code'.
Jul 17 17:29:01 MiWiFi-RA67-srv systemd[1]: heketi.service: Scheduled restart job, restart counter is at 5.
Jul 17 17:29:01 MiWiFi-RA67-srv systemd[1]: Stopped Heketi Server.
Jul 17 17:29:01 MiWiFi-RA67-srv systemd[1]: heketi.service: Start request repeated too quickly.
Jul 17 17:29:01 MiWiFi-RA67-srv systemd[1]: heketi.service: Failed with result 'exit-code'.
Jul 17 17:29:01 MiWiFi-RA67-srv systemd[1]: Failed to start Heketi Server.
  • 解决方案


# 将 heketi 专用的密钥对的权限属主改为 heketi
chown heketi.heketi /etc/heketi/heketi_key*

问题 4

  • 报错信息


[root@ks-storage-0 ~]# heketi-cli --server http://192.168.9.81:18080 --user admin --secret admin@P@88W0rd topology load --json=/etc/heketi/topology.json
Creating cluster ... ID: bd753ae13ba74771436f3598da4ec3adAllowing file volumes on cluster.Allowing block volumes on cluster.Creating node 192.168.9.81 ... Unable to create node: New Node doesn't have glusterd runningCreating node 192.168.9.82 ... Unable to create node: New Node doesn't have glusterd runningCreating node 192.168.9.83 ... Unable to create node: New Node doesn't have glusterd running[root@ks-storage-0 ~]# tail /var/log/messages        
Jul 18 08:30:15 ks-storage-0 heketi[768]: [cmdexec] INFO 2023/07/18 08:30:15 Check Glusterd service status in node ks-storage-0
Jul 18 08:30:15 ks-storage-0 sshd[1548]: Connection from 192.168.9.81 port 60910 on 192.168.9.81 port 22 rdomain ""
Jul 18 08:30:15 ks-storage-0 sshd[1548]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Jul 18 08:30:15 ks-storage-0 heketi[768]: [cmdexec] WARNING 2023/07/18 08:30:15 Failed to create SSH connection to ks-storage-0:22: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
Jul 18 08:30:15 ks-storage-0 heketi[768]: [cmdexec] ERROR 2023/07/18 08:30:15 heketi/executors/cmdexec/peer.go:80:cmdexec.(*CmdExecutor).GlusterdCheck: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
Jul 18 08:30:15 ks-storage-0 heketi[768]: [heketi] ERROR 2023/07/18 08:30:15 heketi/apps/glusterfs/app_node.go:107:glusterfs.(*App).NodeAdd: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
Jul 18 08:30:15 ks-storage-0 heketi[768]: [heketi] ERROR 2023/07/18 08:30:15 heketi/apps/glusterfs/app_node.go:108:glusterfs.(*App).NodeAdd: New Node doesn't have glusterd running
Jul 18 08:30:15 ks-storage-0 heketi[768]: [negroni] 2023-07-18T08:30:15+08:00 | 400 | #011 44.521205ms | 192.168.9.81:18080 | POST /nodes
Jul 18 08:30:15 ks-storage-0 sshd[1548]: Connection closed by authenticating user root 192.168.9.81 port 60910 [preauth]
  • 解决方案

echo PubkeyAcceptedKeyTypes=+ssh-rsa >> /etc/ssh/sshd_config
echo HostKeyAlgorithms=+ssh-rsa >> /etc/ssh/sshd_config

问题 5

  • 报错信息

  Warning  ProvisioningFailed  15s (x9 over 2m3s)  persistentvolume-controller  no volume plugin matched name: kubernetes.io/glusterfs

  • 解决方案

Kubernetes 从 v1.26 开始已经不再支持 GlusterFS


# 参考官方文档说明 https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumeglusterfs (removed)
Kubernetes 1.27 does not include a glusterfs volume type.The GlusterFS in-tree storage driver was deprecated in the Kubernetes v1.25 release and then removed entirely in the v1.26 release.
问题 6

问题 6

  • 报错信息

[root@ks-master-0 glusterfs]# kubectl get pvc -o wide
NAME              STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
heketi-pvc-test   Pending                                      glusterfs      9s    Filesystem[root@ks-master-0 glusterfs]# kubectl describe pvc heketi-pvc-test
Name:          heketi-pvc-test
Namespace:     default
StorageClass:  glusterfs
Status:        Pending
Volume:
Labels:        <none>
Annotations:   volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfsvolume.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode:    Filesystem
Used By:       <none>
Events:Type     Reason              Age   From                         Message----     ------              ----  ----                         -------Warning  ProvisioningFailed  12s   persistentvolume-controller  Failed to provision volume with StorageClass "glusterfs": failed to create volume: failed to get cluster nodes for volume Name: vol_fe3dbcb8154016cb66df102b9b7bc6e6
Size: 1
Volume Id: fe3dbcb8154016cb66df102b9b7bc6e6
Cluster Id: 33da3c174f3ff5c6229e3ed7724689c5
Mount: ks-storage-2:vol_fe3dbcb8154016cb66df102b9b7bc6e6
Mount Options: backup-volfile-servers=ks-storage-1,ks-storage-0
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distributed+Replica: 3
Snapshot Factor: 1.00
: glusterfs server node ip address ks-storage-2 must be a valid IP address, (e.g. 10.9.8.7)Warning  ProvisioningFailed  5s  persistentvolume-controller  Failed to provision volume with StorageClass "glusterfs": failed to create volume: failed to get cluster nodes for volume Name: vol_458d384e96350924d62565f6bdde801f
Size: 1
Volume Id: 458d384e96350924d62565f6bdde801f
Cluster Id: 33da3c174f3ff5c6229e3ed7724689c5
Mount: ks-storage-2:vol_458d384e96350924d62565f6bdde801f
Mount Options: backup-volfile-servers=ks-storage-1,ks-storage-0
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distributed+Replica: 3
Snapshot Factor: 1.00
: glusterfs server node ip address ks-storage-2 must be a valid IP address, (e.g. 10.9.8.7)
  • 解决方案

在利用 Heketi 创建 topology 集群的时候,node.hostnames 的配置使用 IP 地址的形式,不要使用主机名。

注意:这个解决方案只是我在实战的时候遇到并解决的经验,不具有唯一性,可能有其他更好的解决方案。

结束语

本文主要实战演示了在 openEuler 22.03 LTS SP2 安装配置 GlusterFS、Heketi 的详细过程,同时,也详细讲解了 Kubernetes 使用 in-tree storage driver 的模式对接 GlusterFS 的流程、方法、相关技术细节以及常见问题。

本文的操作虽然是基于 openEuler 22.03 LTS SP2,但是整个操作流程同样适用于其他操作系统。

至此,我们搭建完成了 3 Master 和 3 Worker 的 Kubernetes集群,同时,对接了 GlusterFS 作为集群的后端存储。

相关文章:

KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门

转载&#xff1a;KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门 知识点 定级&#xff1a;入门级 GlusterFS 和 Heketi 简介 GlusterFS 安装部署 Heketi 安装部署 Kubernetes 命令行对接 GlusterFS 实战服务器配置(架构1:1复刻小规模生产环境&#xff0c;…...

elasticsearch源码分析-08Serch查询流程

Serch查询流程 查询请求Rest路由注册也是在actionModule中 //查询操作 registerHandler.accept(new RestSearchAction());Override public List<Route> routes() {return unmodifiableList(asList(new Route(GET, "/_search"),new Route(POST, "/_searc…...

【协作提效 Go - gin ! swagger】

什么是swagger Swagger 是一个用于设计、构建、记录和使用 RESTful Web 服务的工具集。它的主要作用包括&#xff1a; API 文档生成&#xff1a;Swagger 可以自动生成详细的 API 文档&#xff0c;包括每个端点的请求和响应格式、参数、状态码等。这使得开发者和用户可以轻松理…...

栈和队列——3.滑动窗口最大值

力扣题目链接 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。 示例&#xff1a; 输入&#xff1a;nums[1,3,-1,-3,5,3,6,7],k 3 …...

嵌入式智能手表开发系列文章之开篇

不好意思&#xff0c;朋友们&#xff0c;我回来了。想想已经断更了好久了。在这段断更的日子里。开拓了个新领域&#xff0c;不搞android 产品&#xff0c;而是去搞嵌入式智能手表啦。 接下来我会用几篇文章来介绍下我对这个领域的看法体会&#xff0c;以及我自己所负责领域的…...

24.8.2数据结构|双链表

双链表 1、定义结构&#xff1a;2个指针域、数据域 2、初始化&#xff1a;创建一个含有N个结点的带头结点双链表head &#xff08;双链表头结点的前驱与和尾节点的后继与置为空&#xff09; 3、求表长&#xff1a;返回双链表head的长度 4、取元素&#xff1a;取出双链表head中…...

RabbitMQ高级特性 - 事务消息

文章目录 RabbitMQ 事务消息概述实现原理代码实现不采用事务采用事务 RabbitMQ 事务消息 概述 RabbitMQ 的 AMQP 协议实现了事务机制&#xff0c;允许开发者保证消息的发送和接收时原子性的&#xff0c;也就是说&#xff0c;要么消息全都发送成功&#xff0c;要么全都发送失败…...

leetcode:心算挑战

题目&#xff1a; 心算项目的挑战比赛中&#xff0c;要求选手从N张卡牌中选出cnt张卡牌&#xff0c;若这cnt张卡牌数字总和为偶数&#xff0c;则选手成绩「有效」且得分为cnt张卡牌数字总和。给定数组cards和cnt&#xff0c;其中cards[i]表示第i张卡牌上的数字。 请帮参赛选手计…...

docker部署java项目(war包方式)

场景描述:java项目war包,在开发开电脑上使用dockerfile构建镜像,上传镜像到客户服务器中使用docker加载docker镜像,然后部署。 目录 一、本地环境安装 docker git 二、服务器环境安装 docker 三、构建docker镜像(win系统) 四、注意事项 (1)系统架构 (2)使…...

jsp 自定义taglib

一、简介 我们在javaWeb开发中&#xff0c;经常会用到jsp的taglib标签&#xff0c;有时候并不能满足我们的实际需要&#xff0c;这就需要我们自定义taglib标签&#xff0c; 二、开发步骤 1、编写control方法&#xff0c;继承BodyTagSupport 2、定义zdytaglib.tld标签文件 3、…...

从一到无穷大 #32 TimeCloth,云上的快速 Point-in-Time Recovery

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言解决方案FAST FINE-GRAINED PITRLog FilterInter-Record Dependency ResolutionL…...

时间序列论文1——Forecasting at Scale

目录 0. AI总结0.1 文章概述0.2 研究背景0.3 研究思路0.4 研究结论与讨论1. Introduction2 Features of Business Time Series3 The Prophet Forecasting Model3.1 The Trend Model3.2 Seasonality3.3 Holidays and Events3.4 Model Fitting3.5 Analyst-in-the-Loop Modeling4 …...

HDFS常用命令

HDFS常用命令 1.HDFS命令介绍1.1基本语法格式1.2常用命令 1.HDFS命令介绍 HDFS 提供了一组命令行工具&#xff0c;用于管理和操作 HDFS 文件系统。 1.1基本语法格式 hdfs dfs -<命令> [选项] <参数>1.2常用命令 1.显示<path>指定的文件的详细信息。 had…...

请问如何做好软件测试工作呢?

一、明确测试目标和范围 理解测试目的&#xff1a;在开始测试之前&#xff0c;首先要明确测试的目标和范围&#xff0c;确保测试计划 与需求相匹配。这有助于测试人员聚焦在关键功能上&#xff0c;避免浪费时间和资源。制定详细的测试计划&#xff1a;根据项目需求&#xff0…...

单片机开发与Linux开发的区别

引言 单片机&#xff08;MCU&#xff09;和Linux开发是嵌入式系统领域的两大主要方向。它们在硬件平台、开发环境、应用场景和开发难度上存在显著区别。本文将系统性地比较单片机开发和Linux开发&#xff0c;探讨它们的主要区别及各自的应用场景和难度体系。 一、基本概念 1…...

【机器学习】回归类算法-相关性分析

一、前言 前面的几篇博客我们学习了分类算法&#xff0c;今天我们来了解一下回归类的算法吧。首先我们来谈谈两者有什么区别&#xff0c;首先是我们在之前的分类算法&#xff0c;这类算法可以将让我们学会如何将不同的数据划分到不同的类里面&#xff0c;输出的是一些离散的值。…...

java基础 之 集合与栈的使用(三)

文章目录 Map接口&#xff08;一&#xff09;实现类&#xff1a;HashMap特点HashMap集合的一些方法 &#xff08;二&#xff09;实现类&#xff1a; TreeMap特点【自然排序】代码【定制排序】代码TreeMap集合的一些方法 HashMap 和 TreeMap的区别 前文回顾&#xff1a; 戳这里 …...

JDK-java.nio包详解

JDK-java.nio包详解 概述 一直以来Java三件套&#xff08;集合、io、多线程&#xff09;都是最热门的Java基础技术点&#xff0c;我们要深入掌握好这三件套才能在日常开发中得心应手&#xff0c;之前有编写集合相关的文章&#xff0c;这里出一篇文章来梳理一下io相关的知识点。…...

虚拟机与服务器的区别是什么?虚拟机与服务器的区别和联系

服务器和虚拟机是两个不同的概念&#xff0c;它们在计算机领域有着不同的含义和作用。今天飞飞就和你分享虚拟机和服务器的区别和联系&#xff0c;希望可以帮助到你~ 1、物理形态 a)服务器是实实在在的物理设备&#xff0c;拥有独立的硬件架构。如CPU、硬盘、内存等 b)虚拟机…...

Linux CentOS stream9 命令

初学linux,对字符界面的命令并不陌生。问到什么是linux命令直接答cd、pwd、ls是linux命令。对于命令的定义并熟悉,也不太关心命令的底层执行逻辑,更关心录入命令,马上获取需要的结果。 本文就命令的定义、分类或执行优先级作一简单介绍。 一、定义 搜索网上对linux命令的…...

JavaScript基础——JavaScript变量声明

变量是存储数据的容器&#xff0c;可以变的量&#xff0c;值可以改变&#xff0c;在JavaScript中&#xff0c;变量声明的关键字有var、let&#xff0c;其中&#xff0c;var是ES5的语法&#xff0c;let是ES6的语法&#xff0c;变量需要先声明&#xff0c;在使用。 声明一个age变…...

ModuleNotFoundError: No Module Named openai

题意&#xff1a;Python 无法在环境中找到名为 openai 的模块 问题背景&#xff1a; import requests from bs4 import BeautifulSoup import openai #write each line of nuclear.txt to a list with open(nuclear.txt, r) as f:lines f.readlines()#remove the newline cha…...

基于SpringBoot+Vue的校园便利平台(带1w+文档)

基于SpringBootVue的校园便利平台(带1w文档) 基于SpringBootVue的校园便利平台(带1w文档) 本平台采用B/S架构、采用的数据库是MySQL&#xff0c;使用JAVA技术开发。该平台的开发方式无论在国内还是国外都比较常见&#xff0c;而且开发完成后使用普遍&#xff0c;可以给平台用户…...

串口应用编程-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

串口应用编程 串口应用编程介绍 介绍 串口定义:串行接口,数据按顺序传输 串口特点:通信线路简单,距离远,速度较低 应用领域:常用工业接口 Linux系统中的作用 作为标准输入输出设备 系统打印信息输出 用户与系统交互 串口与终端:在Linux系统中,串口被视为一种终端&#…...

Canvas实现截图

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>canvas实现截图功能</title><style>.ca…...

Python高性能计算:进程、线程、协程、并发、并行、同步、异步

这里写目录标题 进程、线程、协程并发、并行同步、异步I/O密集型任务、CPU密集型任务 进程、线程、协程 进程、线程和协程是计算机程序执行的三种不同方式&#xff0c;它们在资源管理、执行模型和调度机制上有显著的区别。以下是对它们的详细解释和比较&#xff1a; 进程&…...

kafka基本操作

Kafka详解 一、Kafka概述 Kafka是一个开源的分布式事件流平台&#xff0c;它主要用于高性能数据管道、流分析、数据集成和关键任务应用。Kafka最初被设计为一个分布式的基于发布/订阅模式的消息队列&#xff0c;但随着时间的推移&#xff0c;它已发展成为一个功能强大的流处理…...

JavaFX布局-Accordion

JavaFX布局-Accordion 一个可扩展的面板&#xff0c;包括标题、内容与TitledPane配合一起使用 public static Accordion demo1() {// 创建AccordionAccordion accordion new Accordion();// 内边距accordion.setPadding(new Insets(10, 10, 10, 10));for (int i 1; i < 1…...

【轨物方案】评估光伏组件发电性能一致性方案

光伏电站建设后运行周期长达二十多年&#xff0c;对于电站运营者来说&#xff0c;基础设施的稳定、安全、高效的运行是至关重要的。然而从近些年光伏的发展过程中看到&#xff0c;在电站规划到后期运维整个过程中可能存在着诸多问题&#xff0c;如设备选型不当、施工建设质量差…...

安全基础学习-keil调试汇编代码

初始目的是为了通过汇编编写CRC功能。 但是基础为0,所以目前从搭建工程开始记录。 大佬绕路。 (一)创建项目 1. 新建项目 打开 Keil uVision。选择 Project -> New uVision Project 创建一个新项目。选择你的目标设备(如 ARM Cortex-M 系列处理器),我这里一开始选择…...

建设企业网站公司在哪里/免费服务器

新建vc程序文件方法/步骤: 1&#xff0c;打开VC—新建------工程名称-----Win32 Console Application—确定-------一个空工程----完成-------确定。 2&#xff0c;打开VC—新建----文件名-----csource file----确定。 3&#xff0c;输入代码----组建----点击编译-----点击组…...

什么是网站的栏目和板块/互联网营销推广渠道

写在前边的话&#xff1a;你的支持是我写作的动力&#xff0c;有帮助到你的话麻烦点赞加收藏呦。感激不尽&#xff01;如有错误也请留言指正。 考研数据结构练习&#xff0c;欢迎订阅我的专辑《考研数据结构题型分类讲解练习》...

服饰东莞网站建设/站长seo综合查询

建立Socket连接至少需要一对套接字&#xff0c;其中一个运行于客户端&#xff0c;称为ClientSocket &#xff0c;另一个运行于服务器端&#xff0c;称为ServerSocket 。套接字之间的连接过程分为三个步骤&#xff1a;服务器监听&#xff0c;客户端请求&#xff0c;连接确认。1、…...

wordpress 充值记录/电子商务营销策划方案

这两天一直在搞重定向&#xff0c;问题是一直看不明白&#xff0c;自己弄来弄去&#xff0c;都不成&#xff0c;我的想法是把 http:\\webmail 转到https:\\server\exchange&#xff0c;就是用户输入 http:\\webmail &#xff0c;就可以直接访问 https:\\server\exchange, 但是…...

北京网站开发怎么做/免费建站网站网页

Broadlink智能插座的配置和使用都是这么的方便&#xff0c;配置完成后&#xff0c;无论身在那里只要手机能连上网络就能够控制插座&#xff0c;甚至手机无需连上Wi-Fi只要3G网络就可以控制。 在控制智能插座开关状态时可以听到“滴答”的声音&#xff0c;猜测开关的控制是通过继…...

沈阳的网站制作公司/优化教程网下载

微课的核心是微型教学视频片段(微视频)&#xff0c;视频时长一般为5-8分钟左右&#xff0c;作为一种视频资源&#xff0c;虽然可以借助移动终端观看和学习&#xff0c;但其主流的传播媒体毕竟还是计算机。以下是学习啦小编为大家精心准备的&#xff1a;微课学习心得体会范文3篇…...