參考:https://www.cnblogs.com/netonline/p/10288219.html
一.Heketi簡介
1.簡介
Heketi是一個提供RESTful API管理GlusterFS卷的框架,便於管理員對GlusterFS進行操作:
- 可以用於管理GlusterFS卷的生命周期;
- 能夠在OpenStack,Kubernetes,Openshift等雲平台上實現動態存儲資源供應(動態在GlusterFS集群內選擇bricks構建volume);
- 支持GlusterFS多集群管理。
2.框架

- Heketi支持GlusterFS多集群管理;
-
在集群中通過zone區分故障域。
二.環境
前提k8s集群接Glusterfs集群已部署好
Glusterfs集群部署:https://www.cnblogs.com/minseo/p/6919421.html
例如CentOS7.5只需要執行以下幾步即可
yum -y install centos-release-gluster7.noarch yum --enablerepo=centos-gluster*-test -y install glusterfs-server glusterfs-cli glusterfs-geo-replication systemctl enable glusterd systemctl start glusterd systemctl status glusterd
其中第一步安裝centos-release-gluster7.noarch的版本不清楚的話可以使用命令查看
yum list|grep gluster

注意:Glusterfs之需要安裝並啟動即可,不必組建存儲池
集群IP地址規划
| Hostname | IP | 備注 |
| k8s-master | 192.168.1.63 | |
| k8s-node01 | 192.168.1.65 | |
| k8d-node02 | 192.168.1.66 | |
| heketi | 192.168.1.61 | |
| glusterfs01 | 192.168.1.61 | |
| glusterfs02 | 192.168.1.62 |
所有主機關閉防火牆和Selinux
三.部署heketi
1.安裝heketi
192.168.1.61安裝
#CentOS默認無heketi源,添加源及安裝 yum install -y centos-release-gluster yum install -y heketi heketi-client
2.配置heketi.json
# cat /etc/heketi/heketi.json
{
#默認端口8080
"_port_comment": "Heketi Server Port Number",
"port": "8080",
#默認值false,不需要認證
"_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@123"
},
"_user": "User only has access to /volumes endpoint",
"user": {
"key": "user@123"
}
},
"_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"
],
#默認日志輸出debug
#日志信息輸出在/var/log/message
"loglevel" : "warning"
}
}


3.設置heketi免密訪問GlusterFS
# 選擇ssh執行器,heketi服務器需要免密登陸GlusterFS集群的各節點; # -t:秘鑰類型; # -q:安靜模式; # -f:指定生成秘鑰的目錄與名字,注意與heketi.json的ssh執行器中"keyfile"值一致; # -N:秘鑰密碼,””即為空 [root@heketi ~]# ssh-keygen -t rsa -q -f /etc/heketi/heketi_key -N "" # heketi服務由heketi用戶啟動,heketi用戶需要有新生成key的讀賦權,否則服務無法啟動 [root@heketi ~]# chown heketi:heketi /etc/heketi/heketi_key # 分發公鑰至GlusterFS主機; # -i:指定公鑰 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@192.168.1.61 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@192.168.1.62
4.啟動heketi
#啟動前確保/usr/lib/systemd/system/heketi.service 包含配置--config=/etc/heketi/heketi.json systemctl enable heketi systemctl start heketi systemctl status heketi

驗證
# curl http://127.0.0.1:8080/hello Hello from Heketi
四.設置GlusterFS集群
1.創建topology.json文件
# 通過topology.json文件定義組建GlusterFS集群;
# topology指定了層級關系:clusters-->nodes-->node/devices-->hostnames/zone;
# node/hostnames字段的manage填寫主機ip,指管理通道,在heketi服務器不能通過hostname訪問GlusterFS節點時不能填寫hostname;
# node/hostnames字段的storage填寫主機ip,指存儲數據通道,與manage可以不一樣;
# node/zone字段指定了node所處的故障域,heketi通過跨故障域創建副本,提高數據高可用性質,如可以通過rack的不同區分zone值,創建跨機架的故障域;
# devices字段指定GlusterFS各節點的盤符(可以是多塊盤),必須是未創建文件系統的裸設備
#本次兩台glusterfs主機添加硬盤/dev/sdb
# cat /etc/heketi/topology.json
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"192.168.1.61"
],
"storage": [
"192.168.1.61"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
},
{
"node": {
"hostnames": {
"manage": [
"192.168.1.62"
],
"storage": [
"192.168.1.62"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
}
]
}
]
}
PS:如果需要添加多塊磁盤需要修改配置文件新加即可,例如增加磁盤/dev/sdc則修改配置文件如下


如果是新加需要運行以下命令導入生效
heketi-cli --server http://localhost:8080 --user admin --secret admin@123 topology load --json=/etc/heketi/topology.json

增加后使用命令查看
eketi-cli --user admin --secret admin@123 topology info --server http://localhost:8080

2.通過topology.json主機GlusterFS集群
# GlusterFS集群各節點的glusterd服務已正常啟動,但不必組建受信存儲池; # heketi-cli命令行也可手動逐層添加cluster,node,device,volume等; # “--server http://localhost:8080”:localhost執行heketi-cli時,可不指定; # ”--user admin --secret admin@123 “:heketi.json中設置了認證,執行heketi-cli時需要帶上認證信息,否則報”Error: Invalid JWT token: Unknown user”錯 # glusterfs節點添加磁盤后無需格式化及掛載 # heketi-cli --server http://localhost:8080 --user admin --secret admin@123 topology load --json=/etc/heketi/topology.json

查看集群信息
# 查看heketi topology信息,此時volume與brick等未創建; # 通過”heketi-cli cluster info“可以查看集群相關信息; # 通過”heketi-cli node info“可以查看節點相關信息; # 通過”heketi-cli device info“可以查看device相關信息 # 通過heketi-cli --user admin --secret admin@123 topology info查看topology相關信息
PS:如果沒有使用默認的8080端口例如修改了配置文件把端口改成8081了則使用heketi-cli命令都需要加參數--server http://localhost:8081
# 通過heketi-cli --user admin --secret admin@123 topology info查看topology相關信息 heketi-cli --user admin --secret admin@123 topology info

#集群列表 heketi-cli --user admin --secret admin@123 cluster list #查看集群信息 需要加集群cluster ID heketi-cli --user admin --secret admin@123 cluster info ca501b26cc0cfdf391dfe1d7fc7ad242

#查看node列表 heketi-cli --user admin --secret admin@123 node list #查看node詳細信息info 需要加node id heketi-cli --user admin --secret admin@123 node info 4f58f2c0691b92014c6d3b83c390c0a2

#查看磁盤詳細信息info需要加磁盤ID #可以通過命令 heketi-cli --user admin --secret admin@123 topology info 顯示磁盤device ID heketi-cli --user admin --secret admin@123 device info deeb6efc0e8821ba4a443e683dfdf041

5.K8S集群動態掛載GlusterFS存儲
kubernetes共享存儲供應模式:
-
靜態模式(Static):集群管理員手工創建PV,在定義PV時需設置后端存儲的特性;
-
動態模式(Dynamic):集群管理員不需要手工創建PV,而是通過StorageClass的設置對后端存儲進行描述,標記為某種"類型(Class)";此時要求PVC對存儲的類型進行說明,系統將自動完成PV的創建及與PVC的綁定;PVC可以聲明Class為"",說明PVC禁止使用動態模式。
基於StorageClass的動態存儲供應整體過程如下圖所示:

-
集群管理員預先創建存儲類(StorageClass);
-
用戶創建使用存儲類的持久化存儲聲明(PVC:PersistentVolumeClaim);
-
存儲持久化聲明通知系統,它需要一個持久化存儲(PV: PersistentVolume);
-
系統讀取存儲類的信息;
-
系統基於存儲類的信息,在后台自動創建PVC需要的PV;
-
用戶創建一個使用PVC的Pod;
-
Pod中的應用通過PVC進行數據的持久化;
-
而PVC使用PV進行數據的最終持久化處理。
2. 定義StorageClass
# provisioner:表示存儲分配器,需要根據后端存儲的不同而變更; # reclaimPolicy: 默認即”Delete”,刪除pvc后,相應的pv及后端的volume,brick(lvm)等一起刪除;設置為”Retain”時則保留數據,需要手工處理 # resturl:heketi API服務提供的url; # restauthenabled:可選參數,默認值為”false”,heketi服務開啟認證時必須設置為”true”; # restuser:可選參數,開啟認證時設置相應用戶名; # secretNamespace:可選參數,開啟認證時可以設置為使用持久化存儲的namespace; # secretName:可選參數,開啟認證時,需要將heketi服務的認證密碼保存在secret資源中; # clusterid:可選參數,指定集群id,也可以是1個clusterid列表,格式為”id1,id2”; # volumetype:可選參數,設置卷類型及其參數,如果未分配卷類型,則有分配器決定卷類型;如”volumetype: replicate:3”表示3副本的replicate卷,”volumetype: disperse:4:2”表示disperse卷,其中‘4’是數據,’2’是冗余校驗,”volumetype: none”表示distribute卷# # cat gluster-heketi-storageclass.yaml apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: gluster-heketi-storageclass provisioner: kubernetes.io/glusterfs reclaimPolicy: Delete parameters: resturl: "http://192.168.1.61:8080" restauthenabled: "true" restuser: "admin" secretNamespace: "default" secretName: "heketi-secret" #restuserkey: "xiaotech" volumetype: "replicate:2" # 生成secret資源,其中”key”值需要轉換為base64編碼格式 echo -n "admin@123"|base64 # 注意name/namespace與storageclass資源中定義一致; # 密碼必須有“kubernetes.io/glusterfs” type # cat heketi-secret.yaml apiVersion: v1 kind: Secret metadata: name: heketi-secret namespace: default data: # base64 encoded password. E.g.: echo -n "mypassword" | base64 key: YWRtaW5AMTIz type: kubernetes.io/glusterfs

# 創建secret資源 [root@kubenode1 heketi]# kubectl create -f heketi-secret.yaml # 創建storageclass資源; # 注意:storageclass資源創建后不可變更,如修改只能刪除后重建 [root@kubenode1 heketi]# kubectl create -f gluster-heketi-storageclass.yaml
查看storageclass資源
# kubectl describe storageclass gluster-heketi-storageclass Name: gluster-heketi-storageclass IsDefaultClass: No Annotations: <none> Provisioner: kubernetes.io/glusterfs Parameters: restauthenabled=true,resturl=http://192.168.1.61:8080,restuser=admin,secretName=heketi-secret,secretNamespace=default,volumetype=replicate:2 AllowVolumeExpansion: <unset> MountOptions: <none> ReclaimPolicy: Delete VolumeBindingMode: Immediate Events: <none>
3.定義PVC
# cat gluster-heketi-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: gluster-heketi-pvc
namespace: default
#annotations:
# volume.beta.kubernetes.io/storage-class: "glusterfs"
spec:
#與storageclass名字對應
storageClassName: gluster-heketi-storageclass
# ReadWriteOnce:簡寫RWO,讀寫權限,且只能被單個node掛載;
# ReadOnlyMany:簡寫ROX,只讀權限,允許被多個node掛載;
# ReadWriteMany:簡寫RWX,讀寫權限,允許被多個node掛載;
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
#創建pvc資源
# kubectl create -f gluster-heketi-pvc.yaml
persistentvolumeclaim/gluster-heketi-pvc created
2.查看k8s資源
#kubectl describe pvc gluster-heketi-pvc

查看pv信息
# 查看PV詳細信息,除容量,引用storageclass信息,狀態,回收策略等外,同時給出GlusterFS的Endpoint與path; kubectl describe pv pvc-345664d6-052f-4b4b-bf6f-24df1e582fb4

3.查看heketi
heketi-cli --user admin --secret admin@123 topology info
刪除heketi信息
直接刪除 node device可能無法刪除,可以刪除heketi數據文件然后重啟heketi以后重新創建topology
heketi數據文件位置
rm -rf /var/lib/heketi/heketi.db systemctl restart heketi
4.查看GlusterFS節點
lsblk

# 查看volume的具體信息:2副本的replicate卷; # 另有”vgscan”,”vgdisplay”也可查看邏輯卷組信息等 [root@glusterfs01 ~]# gluster volume list [root@glusterfs01 ~]# gluster volume info

GlusterFS開機掛載也自動寫入/etc/fstab

其實是在glusterfs創建了一個大小為2G的LVM
lvdisplay

4.Pod掛載存儲資源
# cat gluster-heketi-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: gluster-heketi-pod
spec:
containers:
- name: gluster-heketi-container
image: busybox
command:
- sleep
- "3600"
volumeMounts:
- name: gluster-heketi-volume
mountPath: "/pv-data"
readOnly: false
volumes:
- name: gluster-heketi-volume
persistentVolumeClaim:
claimName: gluster-heketi-pvc
#創建Pod
# kubectl create -f gluster-heketi-pod.yaml
pod/gluster-heketi-pod created
5.驗證
登錄Pod創建文件
# kubectl exec -it gluster-heketi-pod sh cd /pv-data/ # touch a.txt # echo "This is a file!" >>a.txt
然后去GlusterFS主機查看
df -Th cd /var/lib/heketi/mounts/vg_50070254b398ab4c67a7ef88d9bceb0d/brick_6afabeac98b3670b02e394b5cdf9dbaf/brick cat a.txt
6.驗證StorageClass的reclaimPolicy
storageclass配置的reclaimPolicy策略是刪除delete
#刪除pod pvc storageclass kubectl delete -f gluster-heketi-pod.yaml kubectl delete -f gluster-heketi-pvc.yaml
不需要刪除storageclass即可以在glusterfs上刪除gluster volume 硬盤掛載 lv等
# heketi [root@heketi ~]# heketi-cli --user admin --secret admin@123 topology info

如果glusterfs端掛載目錄忙了可能導致沒有刪除volume可以手動刪除volume
可以通過以下命令刪除volume
heketi-cli --user admin --secret admin@123 volume delete a0f19be24efec270ebfac4ee41446586
如果提示目標忙無法刪除則查看glusterfs主機是否還處於掛載狀態 卸載使用命令umount即可
# GlusterFS節點 [root@glusterfs01 ~]# lsblk [root@glusterfs01 ~]# df -Th [root@glusterfs01 ~]# gluster volume list


沒有glusterfs卷信息


LVM也刪除了
lvdisplay
查看vg是否回收磁盤資源

7.測試heketi出現故障時容器掛載是否正常
啟動好Pod以后停止heketi
systemctl stop heketi
登錄Pop創建文件正常
kubectl exec -it gluster-heketi-pod sh touch test
heketi停止不會影響正常使用,會影響下次創建pvc
PS:如果在heketi停止期間通過kubectl刪除了pvc則不會自動刪除gluster volume 邏輯卷LVM磁盤掛載等信息

