最後的組合:K8s 1.24 基於 Hekiti 實現 GlusterFS 動態存儲管理實踐

前言

知識點

  • 定級:入門級
  • 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

glusterfs-remove-1.24

  • v1.25

glusterfs-remove-1.25

  • v1.26

glusterfs-remove-1.26

  • v1.27

glusterfs-remove-1.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 架構

glusterfs-heketi-architecture

存儲服務器初始化配置

請注意,以下操作無特殊說明時需在所有存儲節點上執行。本文只選取 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 管理控制檯中能展示哪些,又是如何展示的?

  • 存儲類

ksp-oe-clusters-storageclasses-v1.24

  • 持久卷聲明

ksp-oe-clusters-volumes-v1.24

ksp-oe-clusters-volumes-test-v1.24

  • 服務

ksp-oe-clusters-services-glusterfs-v1.24

ksp-oe-clusters-services-glusterfs-dynamic-v1.24

清理測試資源

  • 清理測試的 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 發佈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章