Gluster分布式文件存储

    xiaoxiao2022-07-02  130

     

    目录

    一、GlusterFS Volume

    1. Glusterfs Volume介绍

    2. Glusterfs Volume类型介绍

    二、Heketi使用

    1. 基本安装配置

    2. 导入GlusterFS信息

    3. 创建Volume及管理

    4. Heheti基本原理

    三、基于Kubernetes的GlusterFS存储卷

    1. 创建StorageClass

    2. 创建PVC


    一、GlusterFS Volume

    1. Glusterfs Volume介绍

    Gluster volume是由多个brick组成的,每个brick实际是服务器上的一个目录

    如下,volume1这个卷是由k8s-node1上的/data/brick1目录和k8s-node2上的/data/brick1组成的,往这个卷上写数据实际上就是往对应的brick目录中写数据

      

    一个volume中的brick可以是多个服务器下的目录,也可以是一个服务器下的多个目录

    如下volumetest卷就是k8s-node1服务器上的两个目录组成

     

    2. Glusterfs Volume类型介绍

    Distributed:分布式卷

    文件通过 hash 算法随机分布到由 bricks 组成的卷上。GlusterFS默认创建的都是分布式卷

    // 创建卷 gluster volume create volume1 k8s-node1:/data/brick1 k8s-node2:/data/brick1 // 启动卷 gluster volume start volume1 // 查看卷 gluster volume info volume1

    卷创建完成后可以通过客户端进行使用(客户端需要安装glusterfs-fuse支持glusterfs文件系统,安装步骤略)

    // 挂载glusterfs volume mount -t glusterfs 172.16.2.100:/volume1 /opt/testdata // 查看挂载目录 df -h | grep /opt/testdata 172.16.2.100:/volume1 3.6T 1.7T 1.9T 47% /opt/testdata

    可以往目录下创建几个文件

    [root@k8s-node1 ~]# cd /opt/testdata/ [root@k8s-node1 testdata]# touch testfile{1..6} [root@k8s-node1 testdata]# ll total 0 -rw-r--r-- 1 root root 0 May 22 14:52 testfile1 -rw-r--r-- 1 root root 0 May 22 14:52 testfile2 -rw-r--r-- 1 root root 0 May 22 14:52 testfile3 -rw-r--r-- 1 root root 0 May 22 14:52 testfile4 -rw-r--r-- 1 root root 0 May 22 14:52 testfile5 -rw-r--r-- 1 root root 0 May 22 14:52 testfile6

    可以看到在/opt/testdata目录下创建了6个文件可以全部展示

    前面说过往gluster volume中写数据实际上上往volume对应的brick中写数据,volume1对应的是k8s-node1上的/data/brick1目录和k8s-node2上的/data/brick1目录,分别查看

    // k8s-node1节点 [root@k8s-node1 ~]# cd /data/brick1/ [root@k8s-node1 brick1]# ll total 0 -rw-r--r-- 2 root root 0 May 22 14:52 testfile5 // k8s-node2节点 [root@k8s-node2 ~]# cd /data/brick1/ [root@k8s-node2 brick1]# ll total 0 -rw-r--r-- 2 root root 0 May 22 14:52 testfile1 -rw-r--r-- 2 root root 0 May 22 14:52 testfile2 -rw-r--r-- 2 root root 0 May 22 14:52 testfile3 -rw-r--r-- 2 root root 0 May 22 14:52 testfile4 -rw-r--r-- 2 root root 0 May 22 14:52 testfile6

    可以看到6个文件分布在两个brick中(具体的分布算法略)

    Replicated: 复制式卷

    类似 RAID 1,replica 数必须等于 volume 中 brick 所包含的存储服务器数,可用性高。

    (为了测试将之前创建的分布式的volume1删除)

    // 解除挂载 [root@k8s-node1 ~]# umount /opt/testdata/ // 停止volume [root@k8s-node1 ~]# gluster volume stop volume1 Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y volume stop: volume1: success // 删除volume [root@k8s-node1 ~]# gluster volume delete volume1 Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y volume delete: volume1: success

    创建复制卷

    创建Replicated卷需要指定副本数(注意,副本数需要等于brick所在的服务器数量)

    // 创建卷 gluster volume create volume2 replica 2 k8s-node1:/data/brick1 k8s-node2:/data/brick1 // 启动卷 gluster volume start volume2 // 查看卷 gluster volume info volume2

    挂载(略)

    创建文件进行测试

    // 创建6个文件 [root@k8s-node1 ~]# cd /opt/testdata [root@k8s-node1 testdata]# touch testfile{1..6} [root@k8s-node1 testdata]# ll total 0 -rw-r--r-- 1 root root 0 May 22 15:06 testfile1 -rw-r--r-- 1 root root 0 May 22 15:06 testfile2 -rw-r--r-- 1 root root 0 May 22 15:06 testfile3 -rw-r--r-- 1 root root 0 May 22 15:06 testfile4 -rw-r--r-- 1 root root 0 May 22 15:06 testfile5 -rw-r--r-- 1 root root 0 May 22 15:06 testfile6

    查看volume对应的brick目录下的文件

    // k8s-node1节点 [root@k8s-node1 ~]# cd /data/brick1/ [root@k8s-node1 brick1]# ll total 0 -rw-r--r-- 2 root root 0 May 22 15:06 testfile1 -rw-r--r-- 2 root root 0 May 22 15:06 testfile2 -rw-r--r-- 2 root root 0 May 22 15:06 testfile3 -rw-r--r-- 2 root root 0 May 22 15:06 testfile4 -rw-r--r-- 2 root root 0 May 22 15:06 testfile5 -rw-r--r-- 2 root root 0 May 22 15:06 testfile6 // k8s-node2节点 [root@k8s-node2 ~]# cd /data/brick1/ [root@k8s-node2 brick1]# ll total 0 -rw-r--r-- 2 root root 0 May 22 15:10 testfile1 -rw-r--r-- 2 root root 0 May 22 15:10 testfile2 -rw-r--r-- 2 root root 0 May 22 15:10 testfile3 -rw-r--r-- 2 root root 0 May 22 15:10 testfile4 -rw-r--r-- 2 root root 0 May 22 15:10 testfile5 -rw-r--r-- 2 root root 0 May 22 15:10 testfile6

    可以看到对于Replicated类型的卷,在两个brick下有相同的文件(对文件进行复制)

    Striped: 条带式卷

    类似 RAID 0,stripe 数必须等于 volume 中 brick 所包含的存储服务器数,文件被分成数据块,以 Round Robin 的方式存储在 bricks 中,并发粒度是数据块,大文件性能好。

    gluster volume create volume3 stripe 2 k8s-node1:/data/brick1 k8s-node2:/data/brick1 gluster volume start volume3 gluster volume info volume3

    挂载并创建文件进行测试

    条带卷主要是将文件分割存储,所以本次创建几个实际大小的文件

    // 创建10M的文件 [root@k8s-node1 testdata]# dd if=/dev/zero bs=1024 count=10000 of=10M.file 10000+0 records in 10000+0 records out 10240000 bytes (10 MB) copied, 0.651303 s, 15.7 MB/s // 创建20M的文件 [root@k8s-node1 testdata]# dd if=/dev/zero bs=1024 count=20000 of=20M.file 20000+0 records in 20000+0 records out 20480000 bytes (20 MB) copied, 1.29391 s, 15.8 MB/s // 查看文件大小 [root@k8s-node1 testdata]# du -sh * 9.8M 10M.file 20M 20M.file

    看看volume对应的brick

    // k8s-node1节点 [root@k8s-node1 ~]# cd /data/brick1/ [root@k8s-node1 brick1]# ll total 15024 -rw-r--r-- 2 root root 5128192 May 22 15:20 10M.file -rw-r--r-- 2 root root 10256384 May 22 15:20 20M.file [root@k8s-node1 brick1]# du -sh * 4.9M 10M.file 9.8M 20M.file // k8s-node2节点 [root@k8s-node2 ~]# cd /data/brick1/ [root@k8s-node2 brick1]# ll total 14976 -rw-r--r-- 2 root root 5111808 May 22 15:20 10M.file -rw-r--r-- 2 root root 10223616 May 22 15:20 20M.file [root@k8s-node2 brick1]# du -sh * 4.9M 10M.file 9.8M 20M.file

    可以看到同一个文件分成了几部分分别存储在不同的brick目录下

    (一个本质的区别是 分布式卷和复制卷的brick中存储的都是一个完整的文件,直接从brick中拷贝文件也可以直接使用,但是条带卷的brick中存储的只是文件的一部分,一个数据块,不能直接使用,往条带卷中写文件的效率是最高的,类似于raid0,一个文件写的时候是将文件分成几块,并发的往brick中写数据)

    Distributed Striped: 分布式的条带卷

    volume中 brick 所包含的存储服务器数必须是 stripe 的倍数(>=2倍),兼顾分布式和条带式的功能。

    Distributed Replicated: 分布式的复制卷

    volume 中 brick 所包含的存储服务器数必须是 replica 的倍数(>=2倍),兼顾分布式和复制式的功能。

     

    二、Heketi使用

    Glusterfs Volume是由多个brick目录组成的,volume的大小和brick目录的大小相关

    但是实际场景下不可能提前准备好相关的目录,也不可能等到创建的时候再去创建相关大小的目录

    Heketi (https://github.com/heketi/heketi ),是一个基于 RESTful API 的 GlusterFS 卷管理框架,可以方便的管理volume

    1. 基本安装配置

    yum安装heketi(也可以容器化部署)

    yum install heketi heketi-client -y

    配置Heketi

    { "_port_comment": "Heketi Server Port Number", "port": "8080", // 端口 "_use_auth": "Enable JWT authorization. Please enable for deployment", "use_auth": false, "_jwt": "Private keys for access", "jwt": { "_admin": "Admin has access to all APIs", "admin": { "key": "My Secret" }, "_user": "User only has access to /volumes endpoint", "user": { "key": "My Secret" } }, "_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", // 执行方式,使用SSH连接 "_sshexec_comment": "SSH username and private key file information", "sshexec": { // 密钥信息 "keyfile": "/root/.ssh/id_rsa", "user": "root", "port": "22", "_fstab_comment": "It's vary dangerous to use the default '/etc/fstab'!", "fstab": "/etc/heketi/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": "/etc/heketi/fstab" }, "_db_comment": "Database file name", "db": "/var/lib/heketi/heketi.db", "brick_max_size_gb" : 1024, "brick_min_size_gb" : 1, "max_bricks_per_volume" : 33, "_loglevel_comment": [ "Set log level. Choices are:", " none, critical, error, warning, info, debug", "Default is warning" ], "loglevel": "warning" } }

    Heketi通过ssh的方式连接到Glusterfs各个节点执行操作,heketi配置文件中需要指明私钥文件,并把对应的公钥文件上传到GlusterFS各台服务器的 /root/.ssh/ 下面,并重命命名为authorized_keys,/etc/heketi/heketi.json 中 的 keyfile 指向生成的私钥文件(包含路径),总之要确保heketi节点可以无密码访问glusterfs各节点。

    启动Heketi

    systemctl enable heketi systemctl start heketi

    基本RestAPI测试

    [root@k8s-node1 ~]# curl http://127.0.0.1:8080/hello Hello from Heketi

    2. 导入GlusterFS信息

    通过一个json文件可以定义GlusterFs节点的信息,包括节点以及节点的磁盘信息。示例文件如下:

    { "clusters": [ { "nodes": [ { "node": { "hostnames": { "manage": [ "192.168.1.100" ], "storage": [ "192.168.1.100" ] }, "zone": 1 }, "devices": [ "/dev/sdc" ] }, { "node": { "hostnames": { "manage": [ "192.168.2.100" ], "storage": [ "192.168.2.100" ] }, "zone": 1 }, "devices": [ "/dev/sdc" ] } ] } ] } // 导入topo信息 [root@k8s-node1 heketi]# export HEKETI_CLI_SERVER=http://127.0.0.1:8083 [root@k8s-node1 heketi]# heketi-cli topology load --json=topology.json // 查看topo信息 [root@k8s-node1 heketi]# heketi-cli topology info

    3. 创建Volume及管理

    // 创建一个10G大小Volume heketi-cli volume create --name=volumeheketi --replica=2 --size=1 // 获取Volume列表 heketi-cli volume list // 获取volume详情 heketi-cli volume info volumeheketi

    可以看到通过heketi创建volume不再需要指定brick目录,并且可以根据需要创建指定大小的卷

    4. Heheti基本原理

    我们知道GlusterFs Volume的brick是一个directory,但我们在heketi导入glusterfs集群的topologyfile中申明的是磁盘,那heketi如何使用磁盘的呢

    答案很简单,当用户通过heketi-cli创建volume时, heketi会把节点上的磁盘组成vg,然后volume的每个brick对应的其实是vg上的一个lvm。heketi会负责这个流程,并最终将lvm挂载到某个目录,这个目录就成为brick。具体示例,如下面所示

    heketi首先会将磁盘信息组成一个vg

    // k8s-node1节点 [root@k8s-node1 ~]# pvs PV VG Fmt Attr PSize PFree /dev/sdc vg_1e121d3f725764eb55cb15cc42aa8f99 lvm2 a-- <2.73t <2.59t [root@k8s-node1 ~]# vgs VG #PV #LV #SN Attr VSize VFree vg_1e121d3f725764eb55cb15cc42aa8f99 1 38 0 wz--n- <2.73t <2.59t // k8s-node2节点 [root@k8s-node2 ~]# pvs PV VG Fmt Attr PSize PFree /dev/sdc vg_e193b95ccea9ee90b09e837e80f5c3b9 lvm2 a-- <2.73t <2.59t [root@k8s-node2 ~]# vgs VG #PV #LV #SN Attr VSize VFree vg_e193b95ccea9ee90b09e837e80f5c3b9 1 38 0 wz--n- <2.73t <2.59t

    通过heketi创建volume并查看volume信息

    [root@k8s-node1 ~]# heketi-cli volume create --name=volumeheketi --replica=2 --size=1 Name: volumeheketi Size: 1 Volume Id: c17457b22899059d4b09b5f56cf74e7b Cluster Id: 6b6e86c292608a56f4c4065832392a10 Mount: 172.16.2.200:volumeheketi Mount Options: backup-volfile-servers=172.16.2.100 Block: false Free Size: 0 Block Volumes: [] Durability Type: replicate Distributed+Replica: 2

    通过Gluster直接查看volume信息

    [root@k8s-node1 ~]# gluster volume info volumeheketi Volume Name: volumeheketi Type: Replicate Volume ID: 91a3764a-4ceb-4bc3-b523-65e2b847fb13 Status: Started Snapshot Count: 0 Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: 192.168.1.100:/var/lib/heketi/mounts/vg_1e121d3f725764eb55cb15cc42aa8f99/brick_ad96a8bd3d00505ad0bc026f7debe146/brick Brick2: 192.168.2.100:/var/lib/heketi/mounts/vg_e193b95ccea9ee90b09e837e80f5c3b9/brick_6c64490e4130c1b4ce833377c417a19d/brick Options Reconfigured: transport.address-family: inet nfs.disable: on

    可以看到在glusterfs中仍然有brick信息,但是这个目录是一个由hetike自动生成的lv

    [root@k8s-node1 ~]# lvdisplay /dev/vg_1e121d3f725764eb55cb15cc42aa8f99/brick_ad96a8bd3d00505ad0bc026f7debe146 --- Logical volume --- LV Path /dev/vg_1e121d3f725764eb55cb15cc42aa8f99/brick_ad96a8bd3d00505ad0bc026f7debe146 LV Name brick_ad96a8bd3d00505ad0bc026f7debe146 VG Name vg_1e121d3f725764eb55cb15cc42aa8f99 LV UUID OqGMZK-WSS0-YO1q-Af4L-lj0R-kEdc-DdJS8x LV Write Access read/write LV Creation host, time k8s-node1, 2019-05-24 14:15:19 +0800 LV Pool name tp_ad96a8bd3d00505ad0bc026f7debe146 LV Status available # open 1 LV Size 1.00 GiB // LV大小是创建时指定的volume大小 Mapped size 0.66% Current LE 256 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:88

    查看该lv的挂载信息

    [root@k8s-node1 ~]# df -h| grep brick_ad96a8bd3d00505ad0bc026f7debe146 /dev/mapper/vg_1e121d3f725764eb55cb15cc42aa8f99-brick_ad96a8bd3d00505ad0bc026f7debe146 1020M 33M 987M 4% /var/lib/heketi/mounts/vg_1e121d3f725764eb55cb15cc42aa8f99/brick_ad96a8bd3d00505ad0bc026f7debe146

    可以看到该目录就是volume对应的brick目录

    三、基于Kubernetes的GlusterFS存储卷

    Kubernetes通过创建StorageClass来使用 Dynamic Provisioning 特性,StorageClass连接Heketi,可以根据需要自动创建GluserFS的Volume,StorageClass还是要系统管理员创建,不过StorageClass不需要每次创建,因为这个不需要很多,不同的PVC可以用同一个StorageClass。

    1. 创建StorageClass

    // 配置文件 [root@k8s-node1 ~]# cat glusterfs-sc.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: heketi-sc parameters: clusterid: 6b6e86c292608a56f4c4065832392a10 resturl: http://192.168.1.100:8083 volumetype: replicate:2 provisioner: kubernetes.io/glusterfs // 创建 [root@k8s-node1 ~]# kubectl create -f glusterfs-sc.yaml storageclass "heketi-sc" created

    其中clusterid可以通过heketi获取

    [root@k8s-node1 ~]# heketi-cli cluster list Clusters: Id:6b6e86c292608a56f4c4065832392a10 [file][block]

    2. 创建PVC

    (按照正常K8s使用Glusterfs volume的方式,还需要创建ep、pv,并且需要预先在glusterfs上创建好volume,但现在通过storageclass,这些步骤可以通通省略,只需要直接创建PVC即可)

    [root@k8s-node1 ~]# cat glusterfs-pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: glusterfs-test-vol1 annotations: volume.beta.kubernetes.io/storage-class: "heketi-sc" spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi [root@k8s-node1 ~]# kubectl create -f glusterfs-pvc.yaml persistentvolumeclaim "glusterfs-test-vol1" created

     

    最新回复(0)