前言

知识点

  • 定级:入门级
  • GlusterFS 和 Heketi 简介
  • GlusterFS 安装部署
  • Heketi 安装部署
  • Kubernetes 命令行对接 GlusterFS

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

主机名 IP CPU 内存 系统盘 数据盘 用途
ks-master-0 192.168.9.91 2 4 50 100 KubeSphere/k8s-master
ks-master-1 192.168.9.92 2 4 50 100 KubeSphere/k8s-master
ks-master-2 192.168.9.93 2 4 50 100 KubeSphere/k8s-master
ks-worker-0 192.168.9.95 2 4 50 100 k8s-worker/CI
ks-worker-1 192.168.9.96 2 4 50 100 k8s-worker
ks-worker-2 192.168.9.97 2 4 50 100 k8s-worker
storage-0 192.168.9.81 2 4 50 100+ ElasticSearch/GlusterFS/Ceph/Longhorn/NFS/
storage-1 192.168.9.82 2 4 50 100+ ElasticSearch/GlusterFS/Ceph/Longhorn
storage-2 192.168.9.83 2 4 50 100+ ElasticSearch/GlusterFS/Ceph/Longhorn
registry 192.168.9.80 2 4 50 200 Sonatype Nexus 3
合计 10 20 40 500 1100+

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

  • 操作系统: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

简介

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

GlusterFS 是什么?

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

以下是 GlusterFS 的主要优点:

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

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

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

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

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 的组合不是一个好的选择,请根据需求仔细评估,谨慎选择。

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 模式本文不做过多介绍,后期会专门做一期相关的实战课程。

Kubernetes 使用 GlusterFS 存储的方式

  • 通过 Heketi 管理 GlusterFS,Kubernetes 调用 Heketi 的接口
  • GlusterFS 结合 NFS-Ganesha 提供 NFS 存储,Kubernetes 采用 NFS 的方式挂载
  • Kubernetes 挂载 GlusterFS 提供的数据卷到本地的存储目录,Kubernetes 采用 hostpath 的方式
  • Container Storage Interface (CSI) volume plugins(更符合标准规范,可能是更好的选择)

Kubernetes 对接 GlusterFS 架构

存储服务器初始化配置

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

配置主机名

hostnamectl hostname ks-storage-0

配置 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

配置 DNS

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

配置服务器时区

配置服务器时区为 Asia/Shanghai

timedatectl set-timezone Asia/Shanghai

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

[root@ks-storage-0 ~]# timedatectl
Local time: Mon 2023-07-17 14:52:33 CST
Universal time: Mon 2023-07-17 06:52:33 UTC
RTC time: Mon 2023-07-17 06:52:33
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

配置时间同步

安装 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

关闭系统防火墙

systemctl stop firewalld && systemctl disable firewalld

禁用 SELinux

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

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

安装系统工具包

yum install tar

配置 SSH 配置文件

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

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

GlusterFS 安装配置

部署过程概览

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

  • 配置 YUM 源
  • 安装 GlusterFS
  • 启动 glusterd 服务
  • 配置可信池

安装 GlusterFS 服务

  1. 安装 GlusterFS 服务

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

# 查询 glusterfs-server 是否存在
yum search glusterfs-server # 安装 glusterfs-server
yum install glusterfs-server
  1. 启动并设置开机自启动 glusterd 服务
systemctl enable glusterd --now
  1. 验证 GlusterFS 服务状态

验证服务状态

systemctl status glusterd

验证服务端口状态

ss -ntlup | grep glusterd

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

# 服务状态
[root@ks-storage-0 ~]# systemctl status glusterd
● glusterd.service - GlusterFS, a clustered file-system server
Loaded: loaded (/usr/lib/systemd/system/glusterd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2023-07-17 15:22:00 CST; 33s ago
Docs: 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.3M
CGroup: /system.slice/glusterd.service
└─ 2586 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO Jul 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))

检测 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

配置可信池 (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
  1. 检查 Peer 状态
gluster peer status

任务执行正确的输出结果。

[root@ks-storage-0 ~]# gluster peer status
Number of Peers: 2 Hostname: 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)

Heketi 安装配置

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

安装 Heketi

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

  1. 在 GitHub Heketi 发布页面下载最新的二进制发行包
cd /root
wget https://github.com/heketi/heketi/releases/download/v10.4.0/heketi-v10.4.0-release-10.linux.amd64.tar.gz
  1. 解压 Heketi
tar xvf heketi-v10.4.0-release-10.linux.amd64.tar.gz
cd heketi
cp heketi heketi-cli /usr/bin/
  1. 创建服务启动用户
useradd -d /var/lib/heketi -s /sbin/nologin heketi
  1. 创建 Heketi 服务配置文件目录
mkdir /etc/heketi
  1. 创建 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

配置 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*
  1. 分发 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
  1. 验证免密登陆
ssh -i /etc/heketi/heketi_key root@ks-storage-0
  1. 创建 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

启动 Heketi 服务

  • 启动并设置开机自动启动 Heketi 服务
 systemctl enable heketi --now
  • 查看 Heketi 服务状态
systemctl status heketi -l

服务正常启动结果

[root@ks-storage-0 ~]# systemctl status heketi -l
● heketi.service - Heketi Server
Loaded: loaded (/usr/lib/systemd/system/heketi.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2023-07-17 17:31:40 CST; 18s ago
Main PID: 3320 (heketi)
Tasks: 7 (limit: 21602)
Memory: 7.2M
CGroup: /system.slice/heketi.service
└─ 3320 /usr/bin/heketi --config=/etc/heketi/heketi.json Jul 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

配置存储

  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:填写磁盘的全路径名称,可以写多个,一定要使用裸盘名不要使用分区名,也不需要给磁盘提前分区
  1. 根据拓扑文件创建集群
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: 9ad37206ce6575b5133179ba7c6e0935
Allowing file volumes on cluster.
Allowing block volumes on cluster.
Creating node 192.168.9.81 ... ID: 0108350a9d13578febbfd0502f8077ff
Adding device /dev/sdb ... OK
Creating node 192.168.9.82 ... ID: 5e99fe0cd727b8066f200bad5524c544
Adding device /dev/sdb ... OK
Creating node 192.168.9.83 ... ID: 7bb26eb30c1c61456b5ae8d805c01cf1
Adding device /dev/sdb ... OK
  1. 配置 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]

功能验证测试

  • 查看集群列表
[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: true File: 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

清理测试数据

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

  • 删除测试卷
[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

K8s 集群对接 GlusterFS

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

主要的操作过程包含:

  • 安装 GlusterFS 客户端

  • 创建 Secret

  • 创建 StorageClass

  • 创建测试 PVC

  • 创建测试 POD

安装 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-secret
namespace: 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

创建 StorageClass

  • 创建 StorageClass 资源清单文件,执行 vi heketi-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: glusterfs
namespace: 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

创建 pvc 测试

  • 创建 pvc 资源清单文件,执行 vi heketi-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: heketi-pvc-test
annotations:
volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
spec:
storageClassName: "glusterfs"
accessModes:
- ReadWriteOnce
resources:
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>

创建测试 Pod 挂载 pvc

  • 创建 Pod 资源清单文件,执行 vi heketi-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: heketi-pod-test
spec:
containers:
- name: heketi-container
image: busybox
command:
- sleep
- "3600"
volumeMounts:
- name: heketi-volume
mountPath: "/pv-data"
readOnly: false
volumes:
- name: heketi-volume
persistentVolumeClaim:
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_308eec3ff24a3684b4f63c67c7d52412
1006.0M 49.8M 956.2M 5% /pv-data
/dev/mapper/openeuler-root
16.6G 3.7G 12.0G 23% /etc/hosts
/dev/mapper/openeuler-root
16.6G 3.7G 12.0G 23% /dev/termination-log
/dev/mapper/openeuler-root
16.6G 3.7G 12.0G 23% /etc/hostname
/dev/mapper/openeuler-root
16.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

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

  • 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_9af38756fe916fced666fcd3de786c19
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 14
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size 99.87 GiB
PE Size 4.00 MiB
Total PE 25567
Alloc PE / Size 260 / <1.02 GiB
Free PE / Size 25307 / <98.86 GiB
VG UUID jrxfIv-Fnjq-IYF8-aubc-t2y0-zwUp-YxjkDC
  • 查看 LV 信息
[root@ks-storage-0 ~]# lvdisplay
--- Logical volume ---
LV Name tp_75a46d674329f9f64bdce45666679172
VG Name vg_9af38756fe916fced666fcd3de786c19
LV UUID D2eUjQ-JMW1-zken-0wGd-OV0C-0Cdf-0fJb33
LV Write Access read/write (activated read only)
LV Creation host, time ks-storage-0, 2023-07-18 14:52:04 +0800
LV Pool metadata tp_75a46d674329f9f64bdce45666679172_tmeta
LV Pool data tp_75a46d674329f9f64bdce45666679172_tdata
LV Status available
# open 0
LV Size 1.00 GiB
Allocated pool data 2.00%
Allocated metadata 10.45%
Current LE 256
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:5 --- Logical volume ---
LV Path /dev/vg_9af38756fe916fced666fcd3de786c19/brick_c74a94a24dd04c89cefd8e8c7e5f9aeb
LV Name brick_c74a94a24dd04c89cefd8e8c7e5f9aeb
VG Name vg_9af38756fe916fced666fcd3de786c19
LV UUID PaQuh1-2LTW-BGBL-QBBb-RZXf-szid-gVsRPz
LV Write Access read/write
LV Creation host, time ks-storage-0, 2023-07-18 14:52:04 +0800
LV Pool name tp_75a46d674329f9f64bdce45666679172
LV Status available
# open 1
LV Size 1.00 GiB
Mapped size 2.00%
Current LE 256
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:6 ... 下面是操作系统的 lv 信息,忽略展示

KubeSphere 管理控制台查验

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

  • 存储类

  • 持久卷声明

  • 服务

清理测试资源

  • 清理测试的 Pod、pvc
kubectl delete -f heketi-pod.yaml -f heketi-pvc.yaml

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

常见问题

问题 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-0 Authorized 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 Server
Loaded: 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 ago
Process: 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: bd753ae13ba74771436f3598da4ec3ad
Allowing 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 running
Creating node 192.168.9.82 ... Unable to create node: New Node doesn't have glusterd running
Creating 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-volume

glusterfs (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

  • 报错信息
[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/glusterfs
volume.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,但是整个操作流程同样适用于其他操作系统。

本文由博客一文多发平台 OpenWrite 发布!

最后的组合:K8s 1.24 基于 Hekiti 实现 GlusterFS 动态存储管理实践的更多相关文章

  1. 基于 Docker 的微服务架构实践

    本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...

  2. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例

    1.前言 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例. 使用技术:SpringBoot.mybatis.shiro.thymeleaf.pagehelp ...

  3. 一种基于RBAC模型的动态访问控制改进方法

    本发明涉及一种基于RBAC模型的动态访问控制改进方法,属于访问控制领域.对原有RBAC模型进行了权限的改进和约束条件的改进,具体为将权限分为静态权限和动态权限,其中静态权限是非工作流的权限,动态权限是 ...

  4. 京东基于Spark的风控系统架构实践和技术细节

    京东基于Spark的风控系统架构实践和技术细节 时间 2016-06-02 09:36:32  炼数成金 原文  http://www.dataguru.cn/article-9419-1.html ...

  5. 基于注解实现jackson动态JsonProperty

    基于注解实现jackson动态JsonProperty @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,但是值是固定的 ...

  6. 基于 koajs 的前后端分离实践

    一.什么是前后端分离? 前后端分离的概念和优势在这里不再赘述,有兴趣的同学可以看各个前辈们一系列总结和讨论: 系列文章:前后端分离的思考与实践(1-6) slider: 淘宝前后端分离实践 知乎提问: ...

  7. 《Flask Web开发——基于Python的Web应用开发实践》一字一句上机实践(上)

    目录 前言 第1章 安装 第2章 程序的基本结构 第3章 模板 第4章 Web表单 第5章 数据库 第6章 电子邮件 第7章 大型程序的结构   前言 学习Python也有一个半月时间了,学到现在感觉 ...

  8. 4712: 洪水 基于链分治的动态DP

    国际惯例的题面:看起来很神的样子......如果我说这是动态DP的板子题你敢信?基于链分治的动态DP?说人话,就是树链剖分线段树维护DP.既然是DP,那就先得有转移方程.我们令f[i]表示让i子树中的 ...

  9. 基于OpenNetVM配置环境的发包实践

    参考: openNetVM 基于OpenNetVM配置环境的发包实践 注意:本文并未对OpenNetVM的服务链进行测试,而是在借助OpenNetVM脚本环境的情况下,分别对Pktgen和MoonGe ...

  10. 基于OVS的VLAN虚拟化简易实践方案

    基于OVS的VLAN虚拟化简易实践方案 前言 本实验基于ovs的vlan流表匹配,根据端口进行vlan标签插入.手工配置ovs,使其具有vlan虚拟化方案. 实验拓扑 ---- ---- | h1 | ...

随机推荐

  1. 【转载】PPT上作图转化为矢量图 —— 论文写作必备技能

    原文地址: https://www.cnblogs.com/scandit/p/15112138.html PPT作出的图本身就为矢量图(可以插入到Word中),另存为PDF后,再通过PDF专业工具适 ...

  2. GAN总结

    GAN总结 本篇文章主要是根据GitHub上的GAN代码库[PyTorch-GAN]进行GAN的复习和回顾,对于之前GAN的各种结构的一种简要的概括. Code 关于评价GAN模型的标准 Incept ...

  3. 什么是状态机?用C语言实现进程5状态模型

    前言 状态机在实际工作开发中应用非常广泛,在刚进入公司的时候,根据公司产品做流程图的时候,发现自己经常会漏了这样或那样的状态,导致整体流程会有问题,后来知道了状态机这样的东西,发现用这幅图就可以很清晰 ...

  4. [计算机网络] IPv6

    1 IPv6 概述 引言 近期突发奇想,能不能用 IPv6 的公网地址,给家里的 NAS 做 内网穿透. 技术上是可行的.只是必须确保是 IPv6 的公网地址. 大学学的 IPv6 的知识,早就抛到九 ...

  5. Python开发中,日期时间的相关处理

    在Python开发中,日期和时间处理是一个常见的需求.Python提供了多种模块和方法来处理日期和时间,以下是一些常用的模块和操作.通过介绍一些系统的Python类库以及第三方的类库,我们可以快速的实 ...

  6. CANopen学习笔记(三)NMT

    NMT NMT主要用来管理和控制各个节点的状态,具体协议可以分为以下四类: NMT protocol Node guard protocol Heartbeat protocol Bootup pro ...

  7. 微信小程序--云开发支付闭环

    云开发支付流程闭环 extends 微信小程序--使用云开发完成支付闭环 在上述文章中,我们对支付结果的处理更多依赖于小程序端的操作 订单号存储在小程序端 支付结果采用小程序端定时触发器轮询 现在我对 ...

  8. docker 参数'--privileged' 的作用

    在Docker中,--privileged 参数给予容器内的进程几乎相同的权限,就像它们在宿主机上一样.这意味着容器可以访问宿主机的所有设备,并且可以执行一些通常需要高级权限的操作,例如加载内核模块. ...

  9. 15. 三数之和 Golang实现

    给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[i] + nums ...

  10. C# 开源教程带你轻松掌握数据结构与算法

    前言 在项目开发过程中,理解数据结构和算法如同掌握盖房子的秘诀.算法不仅能帮助我们编写高效.优质的代码,还能解决项目中遇到的各种难题. 给大家推荐一个支持C#的开源免费.新手友好的数据结构与算法入门教 ...