一 前期准备
1.1 基础知识
Heketi提供了一个RESTful管理界面,可以用来管理GlusterFS卷的生命周期。Heketi会动态在集群内选择bricks构建所需的volumes,从而确保数据的副本会分散到集群不同的故障域内。同时Heketi还支持任意数量的ClusterFS集群。
提示:本实验基于glusterfs和Kubernetes分开部署,heketi管理glusterfs,Kubernetes使用heketi提供的API,从而实现glusterfs的永久存储,,而非Kubernetes部署glusterfs。
1.2 架构示意
提示:本实验Heketi仅管理单zone的glusterfs集群。
1.3 相关规划
1.4 其他准备
所有节点NTP配置;
所有节点添加相应主机名解析:
172.24.8.41 servera
172.24.8.42 serverb
172.24.8.43 serverc
172.24.8.44 heketi
注意:若非必要,建议关闭防火墙和SELinux。
二 规划相应存储卷
2.1 划分LVM
1 [root@servera ~]# fdisk /dev/sdb #创建lvm的sdb1,过程略 2 [root@servera ~]# pvcreate /dev/sdb1 #使用/dev/vdb1创建PV 3 [root@servera ~]# vgcreate vg0 /dev/sdb1 #创建vg 4 [root@servera ~]# lvcreate -L 15G -T vg0/thinpool #创建支持thin的lv池 5 [root@servera ~]# lvcreate -V 10G -T vg0/thinpool -n datalv #创建相应brick的lv 6 [root@servera ~]# vgdisplay #验证确认vg信息 7 [root@servera ~]# pvdisplay #验证确认pv信息 8 [root@servera ~]# lvdisplay #验证确认lv信息
提示:serverb、serverc类似操作,根据规划需求创建完所有基于LVM的brick。
三 安装glusterfs
3.1 安装相应RPM源
1 [root@servera ~]# yum -y install centos-release-gluster
提示:serverb、serverc、client类似操作,安装相应glusterfs源;
安装相应源之后,会在/etc/yum.repos.d/目录多出文件CentOS-Storage-common.repo,内容如下:
1 # CentOS-Storage.repo 2 # 3 # Please see http://wiki.centos.org/SpecialInterestGroup/Storage for more 4 # information 5 6 [centos-storage-debuginfo] 7 name=CentOS-$releasever - Storage SIG - debuginfo 8 baseurl=http://debuginfo.centos.org/$contentdir/$releasever/storage/$basearch/ 9 gpgcheck=1 10 enabled=0 11 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage
3.2 安装glusterfs
1 [root@servera ~]# yum -y install glusterfs-server
提示:serverb、serverc类似操作,安装glusterfs服务端。
3.3 启动glusterfs
1 [root@servera ~]# systemctl start glusterd 2 [root@servera ~]# systemctl enable glusterd
提示:serverb、serverc类似操作,所有节点启动glusterfs服务端;
安装完glusterfs之后建议exit退出终端重新登录,从而可以补全glusterfs相关命令。
3.4 添加信任池
1 [root@servera ~]# gluster peer probe serverb 2 peer probe: success. 3 [root@servera ~]# gluster peer probe serverc 4 peer probe: success. 5 [root@servera ~]# gluster peer status #查看信任池状态 6 [root@servera ~]# gluster pool list #查看信任池列表
提示:加信任池的操作,只需要在servera、serverb、serverc所有集群节点主机中的任意一台上面执行添加其他三个节点的操作即可。
提示:若未关闭防火墙,在添加信任池之前必须放通防火墙相应规则,操作如下:
1 [root@servera ~]# firewallcmd permanent addservice=glusterfs 2 [root@servera ~]# firewallcmd permanent addservice=nfs 3 [root@servera ~]# firewallcmd permanent addservice=rpcbind 4 [root@servera ~]# firewallcmd permanent addservice=mountd 5 [root@servera ~]# firewallcmd permanent addport=5666/tcp 6 [root@servera ~]# firewallcmd reload
四 部署Heketi
4.1 安装heketi服务
1 [root@heketi ~]# yum -y install centos-release-gluster 2 [root@heketi ~]# yum -y install heketi heketi-client
4.2 配置heketi
1 [root@heketi ~]# vi /etc/heketi/heketi.json 2 { 3 "_port_comment": "Heketi Server Port Number", 4 "port": "8080", #默认端口 5 6 "_use_auth": "Enable JWT authorization. Please enable for deployment", 7 "use_auth": true, #基于安全考虑开启认证 8 9 "_jwt": "Private keys for access", 10 "jwt": { 11 "_admin": "Admin has access to all APIs", 12 "admin": { 13 "key": "admin123" #管理员密码 14 }, 15 "_user": "User only has access to /volumes endpoint", 16 "user": { 17 "key": "xianghy" #普通用户 18 } 19 }, 20 21 "_glusterfs_comment": "GlusterFS Configuration", 22 "glusterfs": { 23 "_executor_comment": [ 24 "Execute plugin. Possible choices: mock, ssh", 25 "mock: This setting is used for testing and development.", #用于测试 26 " It will not send commands to any node.", 27 "ssh: This setting will notify Heketi to ssh to the nodes.", #ssh方式 28 " It will need the values in sshexec to be configured.", 29 "kubernetes: Communicate with GlusterFS containers over", #在GlusterFS由kubernetes创建时采用 30 " Kubernetes exec api." 31 ], 32 "executor": "ssh", 33 34 "_sshexec_comment": "SSH username and private key file information", 35 "sshexec": { 36 "keyfile": "/etc/heketi/heketi_key", 37 "user": "root", 38 "port": "22", 39 "fstab": "/etc/fstab" 40 }, 41 …… 42 …… 43 "loglevel" : "warning" 44 } 45 }
4.3 配置免秘钥
1 [root@heketi ~]# ssh-keygen -t rsa -q -f /etc/heketi/heketi_key -N "" 2 [root@heketi ~]# chown heketi:heketi /etc/heketi/heketi_key 3 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@servera 4 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@serverb 5 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@serverc
4.4 启动heketi
1 [root@heketi ~]# systemctl enable heketi.service 2 [root@heketi ~]# systemctl start heketi.service 3 [root@heketi ~]# systemctl status heketi.service 4 [root@heketi ~]# curl http://localhost:8080/hello #测试访问 5 Hello from Heketi
4.5 配置Heketi拓扑
拓扑信息用于让Heketi确认可以使用的存储节点、磁盘和集群,必须自行确定节点的故障域。故障域是赋予一组节点的整数值,这组节点共享相同的交换机、电源或其他任何会导致它们同时失效的组件。必须确认哪些节点构成一个集群,Heketi使用这些信息来确保跨故障域中创建副本,从而提供数据冗余能力,Heketi支持多个Gluster存储集群。
配置Heketi拓扑注意以下几点:
- 可以通过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各节点的盘符(可以是多块盘),必须是未创建文件系统的裸设备。
1 [root@heketi ~]# vi /etc/heketi/topology.json 2 { 3 "clusters": [ 4 { 5 "nodes": [ 6 { 7 "node": { 8 "hostnames": { 9 "manage": [ 10 "172.24.8.41" 11 ], 12 "storage": [ 13 "172.24.8.41" 14 ] 15 }, 16 "zone": 1 17 }, 18 "devices": [ 19 "/dev/mapper/vg0-datalv" 20 ] 21 }, 22 { 23 "node": { 24 "hostnames": { 25 "manage": [ 26 "172.24.8.42" 27 ], 28 "storage": [ 29 "172.24.8.42" 30 ] 31 }, 32 "zone": 1 33 }, 34 "devices": [ 35 "/dev/mapper/vg0-datalv" 36 ] 37 }, 38 { 39 "node": { 40 "hostnames": { 41 "manage": [ 42 "172.24.8.43" 43 ], 44 "storage": [ 45 "172.24.8.43" 46 ] 47 }, 48 "zone": 1 49 }, 50 "devices": [ 51 "/dev/mapper/vg0-datalv" 52 ] 53 } 54 ] 55 } 56 ] 57 } 58 59 [root@heketi ~]# echo "export HEKETI_CLI_SERVER=http://heketi:8080" >> /etc/profile.d/heketi.sh 60 [root@heketi ~]# echo "alias heketi-cli='heketi-cli --user admin --secret admin123'" >> .bashrc 61 [root@heketi ~]# source /etc/profile.d/heketi.sh 62 [root@heketi ~]# source .bashrc 63 [root@heketi ~]# echo $HEKETI_CLI_SERVER 64 http://heketi:8080 65 [root@heketi ~]# heketi-cli --server $HEKETI_CLI_SERVER --user admin --secret admin123 topology load --json=/etc/heketi/topology.json
4.6 集群管理
1 [root@heketi ~]# heketi-cli cluster list #集群列表 2 [root@heketi ~]# heketi-cli cluster info aa83b0045fafa362bfc7a8bfee0c24ad #集群详细信息 3 Cluster id: aa83b0045fafa362bfc7a8bfee0c24ad 4 Nodes: 5 189ee41572ebf0bf1e297de2302cfb39 6 46429de5666fc4c6cc570da4b100465d 7 be0209387384299db34aaf8377c3964c 8 Volumes: 9 10 Block: true 11 12 File: true 13 [root@heketi ~]# heketi-cli topology info aa83b0045fafa362bfc7a8bfee0c24ad #查看拓扑信息
1 [root@heketi ~]# heketi-cli node list #卷信息 2 Id:189ee41572ebf0bf1e297de2302cfb39 Cluster:aa83b0045fafa362bfc7a8bfee0c24ad 3 Id:46429de5666fc4c6cc570da4b100465d Cluster:aa83b0045fafa362bfc7a8bfee0c24ad 4 Id:be0209387384299db34aaf8377c3964c Cluster:aa83b0045fafa362bfc7a8bfee0c24ad 5 [root@heketi ~]# heketi-cli node info 189ee41572ebf0bf1e297de2302cfb39 #节点信息 6 [root@heketi ~]# heketi-cli volume create --size=2 --replica=2 #默认为3副本的replica模式
1 [root@heketi ~]# heketi-cli volume list #卷信息 2 [root@heketi ~]# heketi-cli volume info 7da55685ebeeaaca60708cd797a5e391 3 [root@servera ~]# gluster volume info #通过glusterfs节点查看
4.7 测试验证
1 [root@heketi ~]# yum -y install centos-release-gluster 2 [root@heketi ~]# yum -y install glusterfs-fuse #安装glusterfs-fuse 3 [root@heketi ~]# mount -t glusterfs 172.24.8.41:vol_7da55685ebeeaaca60708cd797a5e391 /mnt
1 [root@heketi ~]# umount /mnt 2 [root@heketi ~]# heketi-cli volume delete 7da55685ebeeaaca60708cd797a5e391 #验证完毕删除
参考:https://www.jianshu.com/p/1069ddaaea78
https://www.cnblogs.com/panwenbin-logs/p/10231859.html
五 Kubernetes动态挂载glusterfs
5.1 StorageClass动态存储
kubernetes共享存储provider模式:
静态模式(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进行数据的最终持久化处理。
提示:关于Kubernetes的部署参考《附003.Kubeadm部署Kubernetes》。
5.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卷
提示:关于glusterfs各种不同类型的卷见《004.RHGS-创建volume》。
1 [root@k8smaster01 ~]# kubectl create ns heketi #创建命名空间 2 [root@k8smaster01 ~]# echo -n "admin123" | base64 #将密码转换为64位编码 3 YWRtaW4xMjM= 4 [root@k8smaster01 ~]# mkdir -p heketi 5 [root@k8smaster01 ~]# cd heketi/ 6 [root@k8smaster01 ~]# vi heketi-secret.yaml #创建用于保存密码的secret 7 apiVersion: v1 8 kind: Secret 9 metadata: 10 name: heketi-secret 11 namespace: heketi 12 data: 13 # base64 encoded password. E.g.: echo -n "mypassword" | base64 14 key: YWRtaW4xMjM= 15 type: kubernetes.io/glusterfs 16 [root@k8smaster01 heketi]# kubectl create -f heketi-secret.yaml #创建heketi 17 [root@k8smaster01 heketi]# kubectl get secrets -n heketi 18 NAME TYPE DATA AGE 19 default-token-5sn5d kubernetes.io/service-account-token 3 43s 20 heketi-secret kubernetes.io/glusterfs 1 5s 21 [root@kubenode1 heketi]# vim gluster-heketi-storageclass.yaml #正式创建StorageClass 22 apiVersion: storage.k8s.io/v1 23 kind: StorageClass 24 metadata: 25 name: gluster-heketi-storageclass 26 parameters: 27 resturl: "http://172.24.8.44:8080" 28 clusterid: "aa83b0045fafa362bfc7a8bfee0c24ad" 29 restauthenabled: "true" #若heketi开启认证此处也必须开启auth认证 30 restuser: "admin" 31 secretName: "heketi-secret" #name/namespace与secret资源中定义一致 32 secretNamespace: "heketi" 33 volumetype: "replicate:3" 34 provisioner: kubernetes.io/glusterfs 35 reclaimPolicy: Delete 36 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-storageclass.yaml
注意:storageclass资源创建后不可变更,如修改只能删除后重建。
1 [root@k8smaster01 heketi]# kubectl get storageclasses #查看确认 2 NAME PROVISIONER AGE 3 gluster-heketi-storageclass kubernetes.io/glusterfs 85s 4 [root@k8smaster01 heketi]# kubectl describe storageclasses gluster-heketi-storageclass
5.3 定义PVC
1 [root@k8smaster01 heketi]# cat gluster-heketi-pvc.yaml 2 apiVersion: v1 3 metadata: 4 name: gluster-heketi-pvc 5 annotations: 6 volume.beta.kubernetes.io/storage-class: gluster-heketi-storageclass 7 spec: 8 accessModes: 9 - ReadWriteOnce 10 resources: 11 requests: 12 storage: 1Gi
注意:accessModes可有如下简写:
- ReadWriteOnce:简写RWO,读写权限,且只能被单个node挂载;
- ReadOnlyMany:简写ROX,只读权限,允许被多个node挂载;
- ReadWriteMany:简写RWX,读写权限,允许被多个node挂载。
1 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-pvc.yaml 2 [root@k8smaster01 heketi]# kubectl get pvc 3 [root@k8smaster01 heketi]# kubectl describe pvc gluster-heketi-pvc 4 [root@k8smaster01 heketi]# kubectl get pv 5 [root@k8smaster01 heketi]# kubectl describe pv pvc-5f7420ef-082d-11ea-badf-000c29fa7a79
1 [root@k8smaster01 heketi]# kubectl describe endpoints glusterfs-dynamic-5f7420ef-082d-11ea-badf-000c29fa7a79
提示:由上可知:PVC状态为Bound,Capacity为1G。查看PV详细信息,除容量,引用storageclass信息,状态,回收策略等外,同时可知GlusterFS的Endpoint与path。EndpointsName为固定格式:glusterfs-dynamic-PV_NAME,且endpoints资源中指定了挂载存储时的具体地址。
5.4 确认查看
通过5.3所创建的信息:
- volume与brick已经创建;
- 主挂载点(通信)在172.24.8.41节点,其余两个节点备选;
- 三副本的情况下,所有节点都会创建brick。
1 [root@heketi ~]# heketi-cli topology info #heketi主机查看 2 [root@serverb ~]# lsblk #glusterfs节点查看 3 [root@serverb ~]# df -hT #glusterfs节点查看 4 [root@servera ~]# gluster volume list #glusterfs节点查看 5 [root@servera ~]# gluster volume info vol_e4c948687239df9833748d081ddb6fd5
5.5 Pod挂载测试
1 [root@xxx ~]# yum -y install centos-release-gluster 2 [root@xxx ~]# yum -y install glusterfs-fuse #安装glusterfs-fuse
提示:所有需要使用glusterfs volume的Kubernetes节点都必须安装glusterfs-fuse以便于正常挂载,同时版本需要和glusterfs节点一致。
1 [root@k8smaster01 heketi]# vi gluster-heketi-pod.yaml 2 kind: Pod 3 apiVersion: v1 4 metadata: 5 name: gluster-heketi-pod 6 spec: 7 containers: 8 - name: gluster-heketi-container 9 image: busybox 10 command: 11 - sleep 12 - "3600" 13 volumeMounts: 14 - name: gluster-heketi-volume #必须和volumes中name一致 15 mountPath: "/pv-data" 16 readOnly: false 17 volumes: 18 - name: gluster-heketi-volume 19 persistentVolumeClaim: 20 claimName: gluster-heketi-pvc #必须和5.3创建的PVC中的name一致 21 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-pod.yaml -n heketi #创建Pod
5.6 确认验证
1 [root@k8smaster01 heketi]# kubectl get pod -n heketi | grep gluster 2 gluster-heketi-pod 1/1 Running 0 2m43s 3 [root@k8smaster01 heketi]# kubectl exec -it gluster-heketi-pod /bin/sh #进入Pod写入测试文件 4 / # cd /pv-data/ 5 /pv-data # echo "This is a file!" >> a.txt 6 /pv-data # echo "This is b file!" >> b.txt 7 /pv-data # ls 8 a.txt b.txt 9 [root@servera ~]# df -hT #在glusterfs节点查看Kubernetes节点的测试文件 10 [root@servera ~]# cd /var/lib/heketi/mounts/vg_47c90d90e03de79696f90bd94cfccdde/brick_721243c3e0cf8a2372f05d5085a4338c/brick/ 11 [root@servera brick]# ls 12 [root@servera brick]# cat a.txt 13 [root@servera brick]# cat b.txt
5.7 删除资源
1 [root@k8smaster01 heketi]# kubectl delete -f gluster-heketi-pod.yaml 2 [root@k8smaster01 heketi]# kubectl delete -f gluster-heketi-pvc.yaml 3 [root@k8smaster01 heketi]# kubectl get pvc 4 [root@k8smaster01 heketi]# kubectl get pv 5 [root@servera ~]# gluster volume list 6 No volumes present in cluster