CentOS 7安装部署GlusterFS
一、glusterfs简介
Glusterfs是一个开源的分布式文件系统,是Scale存储的核心,能够处理千数量级的客户端。是整合了许多存储块(server)通过Infiniband RDMA或者 Tcp/Ip方式互联的一个并行的网络文件系统。
特征:
• 容量可以按比例的扩展,且性能却不会因此而降低。
• 廉价且使用简单,完全抽象在已有的文件系统之上。
• 扩展和容错设计的比较合理,复杂度较低
• 适应性强,部署方便,对环境依赖低,使用,调试和维护便利
二、glusterfs安装部署
一般在企业中,采用的是分布式复制卷,因为有数据备份,数据相对安全。
网络要求全部千兆环境,gluster 服务器至少有 2 块网卡,1 块网卡绑定供 gluster 使用,剩余一块分配管理网络 IP,用于系统管理。
如果有条件购买万兆交换机,服务器配置万兆网卡,存储性能会更好。网络方面如果安全性要求较高,可以多网卡绑定。
跨地区机房配置 Gluster,在中国网络格局下不适用。
• 注意:GlusterFS将其动态生成的配置文件存储在/var/lib/glusterd中。如果在任何时候GlusterFS无法写入这些文件(例如,当后备文件系统已满),它至少会导致您的系统不稳定的行为;
或者更糟糕的是,让您的系统完全脱机。建议为/var/log等目录创建单独的分区,以确保不会发生这种情况。
###环境说明:
3台机器安装 GlusterFS 组成一个集群。
###服务器:
192.168.1.35
192.168.1.37
192.168.1.38
root/AIops@2018
###配置 hosts
vim /etc/hosts
192.168.1.35 gfs-node01
192.168.1.37 gfs-node02
192.168.1.38 gfs-node03
client:
192.168.1.46 gfs-client
####初始化
yum -y install wget net-tools lrzsz gcc gcc-c++ python-devel python-setuptools make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel vim ncurses-devel autoconf automake zlib-devel python-devel iftop htop iotop sysstat lsof telnet traceroute tree man
yum -y install epel-release
yum -y install libibverbs librdmacm xfsprogs nfs-utils rpcbind libaio liblvm2app lvm2-devel
----
####每个节点修改主机名
hostnamectl set-hostname gfs-node01
hostnamectl set-hostname gfs-node02
hostnamectl set-hostname gfs-node03
hostnamectl set-hostname gfs-client
####配置相互间的ssh信任关系
现在gfs-node01节点上产生公私钥文件,然后将gfs-node01节点的.ssh目录拷贝给其他节点
[root@gfs-node01 ~]# ssh-keygen -t rsa 一路回车
[root@gfs-node01 ~]# cd .ssh/
[root@gfs-node01 ~]# ls
id_rsa id_rsa.pub
[root@gfs-node01 ~]# cp id_rsa.pub authorized_keys
[root@gfs-node01 ~]# scp -r /root/.ssh gfs-node02:/root/
[root@gfs-node01 ~]# scp -r /root/.ssh gfs-node03:/root/
然后在各节点直接验证cephuser用户下的ssh相互信任关系
$ ssh -p22 gfs-node01
$ ssh -p22 gfs-node02
$ ssh -p22 gfs-node03
###安装:
CentOS7 安装glusterfs
在三个节点都安装glusterfs
yum install centos-release-gluster
yum install -y glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma
yum install -y glusterfs*
###配置 GlusterFS 集群:
####启动glusterFS
systemctl start glusterd.service
systemctl enable glusterd.service
####在 gfs-node01 节点上配置,将 节点 加入到 集群中。
[root@gfs-node01 ~]#gluster peer probe gfs-node01
peer probe: success. Probe on localhost not needed
[root@gfs-node01 ~]#gluster peer probe gfs-node02
peer probe: success.
[root@gfs-node01 ~]#gluster peer probe gfs-node03
peer probe: success.
####查看集群状态:
[root@gfs-node01 ~]#gluster peer status
Number of Peers: 2
Hostname: gfs-node02
Uuid: 41573e8b-eb00-4802-84f0-f923a2c7be79
State: Peer in Cluster (Connected)
Hostname: gfs-node03
Uuid: da068e0b-eada-4a50-94ff-623f630986d7
State: Peer in Cluster (Connected)
####创建数据存储目录:
[root@gfs-node01 ~]# mkdir -p /opt/gluster/data
[root@gfs-node02 ~]# mkdir -p /opt/gluster/data
[root@gfs-node03 ~]# mkdir -p /opt/gluster/data
#####查看volume 状态:
[root@gfs-node01 ~]#gluster volume info
No volumes present
####创建GlusterFS磁盘(bigbdata):
[root@gfs-node01 ~]#gluster volume create bigbdata replica 3 gfs-node01:/opt/gluster/data gfs-node02:/opt/gluster/data gfs-node03:/opt/gluster/data force
volume create: bigbdata: success: please start the volume to access data
####GlusterFS几种volume 模式说明:
#####一、 默认模式,既DHT, 也叫分布式卷: 将文件已hash算法随机分布到 一台服务器节点中存储。
gluster volume create test-volume server1:/exp1 server2:/exp2
#####二、 复制模式,既AFR, 创建volume 时带 replica x 数量: 将文件复制到 replica x 个节点中(类似 RAID 1,replica 数必须等于 volume 中 brick 所包含的存储服务器数,可用性高)。
gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2
#####三、 条带模式,既Striped, 创建volume 时带 stripe x 数量: 将文件切割成数据块,分别存储到 stripe x 个节点中
( 类似raid 0,stripe 数必须等于 volume 中 brick 所包含的存储服务器数,文件被分成数据块,以 Round Robin 的方式存储在 bricks 中,并发粒度是数据块,大文件性能好。)。
gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2
gluster volume create bigbdata stripe 2 transport tcp gfs-node01:/opt/gluster/data gfs-node02:/opt/gluster/data gfs-node03:/opt/gluster/data force
#####四、 分布式条带模式(组合型),最少需要4台服务器才能创建。创建volume 时 stripe 2 server = 4 个节点: 是DHT 与 Striped 的组合型。
volume中 brick 所包含的存储服务器数必须是 stripe 的倍数(>=2倍),兼顾分布式和条带式的功能。
gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
#####五、 分布式复制模式(组合型), 最少需要4台服务器才能创建。创建volume 时 replica 2 server = 4 个节点:是DHT 与 AFR 的组合型。
volume中brick所包含的存储服务器数必须是replica 的倍数(>=2倍),兼顾分布式和复制式的功能。(生产场景推荐使用此种方式)
gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
#####六、 条带复制卷模式(组合型), 最少需要4台服务器才能创建。创建volume 时 stripe 2 replica 2 server = 4 个节点: 是 Striped 与 AFR 的组合型。
gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4
#####七、 三种模式混合, 至少需要8台 服务器才能创建。stripe 2 replica 2 , 每4个节点 组成一个组。
gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6 server7:/exp7 server8:/exp8
###查看 volume 状态:
[root@gfs-node01 ~]#gluster volume info
Volume Name: bigbdata
Type: Replicate
Volume ID: e539ff3b-2278-4f3f-a594-1f101eabbf1e
Status: Created
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gfs-node01:/opt/gluster/data
Brick2: gfs-node02:/opt/gluster/data
Brick3: gfs-node03:/opt/gluster/data
Options Reconfigured:
performance.readdir-ahead: on
###启动卷 bigbdata
[root@gfs-node01 ~]#gluster volume start bigbdata
volume start: bigbdata: success
###gluster性能调优:
开启 指定 volume 的配额: (bigbdata 为 volume 名称)
gluster volume quota bigbdata enable
限制 bigbdata 中 / (既总目录) 最大使用 80GB 空间
gluster volume quota bigbdata limit-usage / 80GB
#设置 cache 4GB
gluster volume set bigbdata performance.cache-size 4GB
#开启 异步 ,后台操作
gluster volume set bigbdata performance.flush-behind on
#设置 io 线程 32
gluster volume set bigbdata performance.io-thread-count 32
#设置 回写 (写数据时间,先写入缓存内,再写入硬盘)
gluster volume set bigbdata performance.write-behind on
###部署GlusterFS客户端并mount GlusterFS文件系统 (客户端必须加入 glusterfs hosts 否则报错。)
####配置 hosts
$ vi /etc/hosts
192.168.1.158 gfs-node01
192.168.1.151 gfs-node02
192.168.1.92 gfs-node03
[root@gfs-client ~]#yum install -y glusterfs glusterfs-fuse
[root@gfs-client ~]#mkdir -p /home/apps
####手动挂载卷:
[root@gfs-client ~]#mount -t glusterfs gfs-node01:bigbdata /home/apps
查看挂载结果:
[root@gfs-client ~]# mount -t fuse.glusterfs
卸载目录:
umount -l /home/apps
####自动挂载卷:
除了使用mount挂载,还可以使用/etc/fstab自动挂载
语法格式:HOSTNAME-OR-IPADDRESS:/VOLNAME MOUNTDIR glusterfs defaults,_netdev 0 0
举个例子:
gfs-node01:bigbdata /home/apps glusterfs defaults,_netdev 0 0
gfs-node01:bigbdata /home/apps glusterfs defaults 0 0
[root@gfs-client sellbot]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 39G 2.4G 37G 7% /
devtmpfs 476M 0 476M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.6M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sda1 1014M 181M 834M 18% /boot
tmpfs 98M 0 98M 0% /run/user/0
gfs-node01:bigbdata 39G 2.9G 37G 8% /home/apps
###测试:
####DHT 模式 客户端 创建一个 1G 的文件
[root@gfs-client ~]#time dd if=/dev/zero of=hello bs=1000M count=1
记录了1+0 的读入
记录了1+0 的写出
1048576000字节(1.0 GB)已复制,9.1093 秒,115 MB/秒
real 0m9.120s
user 0m0.000s
sys 0m1.134s
####AFR 模式 客户端 创建一个 1G 的文件
[root@gfs-client ~]#time dd if=/dev/zero of=hello.txt bs=1024M count=1
录了1+0 的读入
记录了1+0 的写出
1073741824字节(1.1 GB)已复制,27.4566 秒,39.1 MB/秒
real 0m27.469s
user 0m0.000s
sys 0m1.065s
####Striped 模式 客户端 创建一个 1G 的文件
[root@gfs-client ~]#time dd if=/dev/zero of=hello bs=1000M count=1
记录了1+0 的读入
记录了1+0 的写出
1048576000字节(1.0 GB)已复制,9.10669 秒,115 MB/秒
real 0m9.119s
user 0m0.001s
sys 0m0.953s
####条带复制卷模式 (Number of Bricks: 1 x 2 x 2 = 4) 客户端 创建一个 1G 的文件
[root@gfs-client ~]#time dd if=/dev/zero of=hello bs=1000M count=1
记录了1+0 的读入
记录了1+0 的写出
1048576000字节(1.0 GB)已复制,17.965 秒,58.4 MB/秒
real 0m17.978s
user 0m0.000s
sys 0m0.970s
####分布式复制模式 (Number of Bricks: 2 x 2 = 4) 客户端 创建一个 1G 的文件
[root@gfs-client ~]#time dd if=/dev/zero of=haha bs=100M count=10
记录了10+0 的读入
记录了10+0 的写出
1048576000字节(1.0 GB)已复制,17.7697 秒,59.0 MB/秒
real 0m17.778s
user 0m0.001s
sys 0m0.886s
###针对分布式复制模式还做了如下测试:
####4K随机写 测试:
安装 fio (yum -y install libaio-devel (否则运行fio 会报错engine libaio not loadable, 已安装需重新编译,否则一样报错))
[root@gfs-client ~]#fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=randwrite -size=10G -filename=1.txt -name="EBS 4KB randwrite test" -iodepth=32 -runtime=60
write: io=352204KB, bw=5869.9KB/s, iops=1467, runt= 60002msec
WRITE: io=352204KB, aggrb=5869KB/s, minb=5869KB/s, maxb=5869KB/s, mint=60002msec, maxt=60002msec
#####4K随机读 测试:
fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=randread -size=10G -filename=1.txt -name="EBS 4KB randread test" -iodepth=8 -runtime=60
read: io=881524KB, bw=14692KB/s, iops=3672, runt= 60001msec
READ: io=881524KB, aggrb=14691KB/s, minb=14691KB/s, maxb=14691KB/s, mint=60001msec, maxt=60001msec
####512K 顺序写 测试:
fio -ioengine=libaio -bs=512k -direct=1 -thread -rw=write -size=10G -filename=512.txt -name="EBS 512KB seqwrite test" -iodepth=64 -runtime=60
write: io=3544.0MB, bw=60348KB/s, iops=117, runt= 60135msec
WRITE: io=3544.0MB, aggrb=60348KB/s, minb=60348KB/s, maxb=60348KB/s, mint=60135msec, maxt=60135msec
###其他的维护命令:
1. 查看GlusterFS中所有的volume:
[root@gfs-node01 ~]#gluster volume list
2. 删除GlusterFS磁盘:
[root@gfs-node01 ~]#gluster volume stop bigbdata #停止名字为 bigbdata 的磁盘
[root@gfs-node01 ~]#gluster volume delete bigbdata #删除名字为 bigbdata 的磁盘
注: 删除 磁盘 以后,必须删除 磁盘( /opt/gluster/data ) 中的 ( .glusterfs/ .trashcan/ )目录。
否则创建新 volume 相同的 磁盘 会出现文件 不分布,或者 类型 错乱 的问题。
3. 卸载某个节点GlusterFS磁盘(删除节点)
[root@gfs-node01 ~]#gluster peer detach gfs-node03
4. 设置访问限制,按照每个volume 来限制
[root@gfs-node01 ~]#gluster volume set bigbdata auth.allow 10.6.0.*,10.7.0.*
5. 添加GlusterFS节点:
[root@gfs-node01 ~]#gluster peer probe gfs-node03
[root@gfs-node01 ~]#gluster volume add-brick bigbdata gfs-node03:/opt/gluster/data
注:如果是复制卷或者条带卷,则每次添加的Brick数必须是replica或者stripe的整数倍
查看状态:gluster peer status
列举节点:gluster pool list
6. 配置卷
[root@gfs-node01 ~]# gluster volume set
7. 缩容volume:
先将数据迁移到其它可用的Brick,迁移结束后才将该Brick移除:
[root@gfs-node01 ~]#gluster volume remove-brick bigbdata gfs-node03:/opt/gluster/data gfs-node02:/opt/gluster/data start
在执行了start之后,可以使用status命令查看移除进度:
[root@gfs-node01 ~]#gluster volume remove-brick bigbdata gfs-node03:/opt/gluster/data gfs-node02:/opt/gluster/data status
不进行数据迁移,直接删除该Brick:
[root@gfs-node01 ~]#gluster volume remove-brick bigbdata gfs-node03:/opt/gluster/data gfs-node02:/opt/gluster/data commit
注意,如果是复制卷或者条带卷,则每次移��的Brick数必须是replica或者stripe的整数倍。
[root@gfs-node01 ~]#gluster volume remove-brick bigbdata gfs-node03:/opt/gluster/data gfs-node02:/opt/gluster/data force
8. 扩容volume:
volume add-brick <VOLNAME> [<stripe|replica> <COUNT> [arbiter <COUNT>]] <NEW-BRICK> ... [force] - add brick to volume <VOLNAME>
gluster volume add-brick bigbdata replica 3 gfs-node03:/opt/gluster/data force
9. 修复命令-替换卷:
[root@gfs-node01 ~]#gluster volume replace-brick bigbdata gfs-node03:/opt/gluster/data gfs-node-3:/opt/gluster/data commit force
10. 均衡卷volume:
[root@gfs-node01 ~]#gluster volume rebalance bigbdata fix-layout start
[root@gfs-node01 ~]#gluster volume rebalance bigbdata start
[root@gfs-node01 ~]#gluster volume rebalance bigbdata start force
[root@gfs-node01 ~]#gluster volume rebalance bigbdata status
[root@gfs-node01 ~]#gluster volume rebalance bigbdata stop
===============================================================================================
###格式化磁盘(全部glusterfs主机)
在每台主机上创建几块硬盘,做接下来的分布式存储使用
注:创建的硬盘要用xfs格式来格式化硬盘,如果用ext4来格式化硬盘的话,对于大于16TB空间格式化就无法实现了。
所以这里要用xfs格式化磁盘(centos7默认的文件格式就是xfs),并且xfs的文件格式支持PB级的数据量。
如果是centos6默认是不支持xfs的文件格式,要先安装xfs支持包
yum install xfsprogs -y
用fdisk -l 查看磁盘设备,例如查看data-1-1的磁盘设备,这里的sdb是新加的硬盘
[root@gfs-node01 ~]# fdisk -l
Disk /dev/sda: 42.9 GB, 42949672960 bytes, 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000a3f5c
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 75497471 36699136 83 Linux
/dev/sda3 75497472 83886079 4194304 82 Linux swap / Solaris
Disk /dev/sdb: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
特别说明:
如果磁盘大于 2T 的话就用 parted 来分区,这里我们不用分区(可以不分区);
做分布式文件系统的时候数据盘一般不需要做 RAID,一般系统盘会做 RAID 1;
如果有raid卡的话,最好用上,raid卡有数据缓存功能,也能提高磁盘的iops,最好的话,用RAID 5;
如果都不做raid的话,也是没问题的,glusterfs也是可以保证数据的安全的。
这里使用官方推荐的格盘方式:http://docs.gluster.org/en/latest/Quick-Start-Guide/Quickstart/#purpose-of-this-document
####磁盘分区及格式化:
[root@gfs-node01 ~]# sudo parted -s /dev/sdb mklabel gpt mkpart primary xfs 0% 100%
[root@gfs-node01 ~]# sudo mkfs.xfs /dev/sdb -f
查看磁盘格式(xfs格式)
[root@gfs-node01 ~]# sudo blkid -o value -s TYPE /dev/sdb
在三台机器上创建挂载块设备的目录,挂载硬盘到目录
[root@gfs-node01 ~]# mkdir -p /opt/data/brick1
[root@gfs-node01 ~]# echo '/dev/sdb /opt/data/brick1 xfs defaults 1 2' >> /etc/fstab
####挂载
[root@gfs-node01 ~]#mount /dev/sdb /opt/data/brick1
[root@gfs-node01 brick1]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 35G 2.6G 31G 8% /
devtmpfs 477M 0 477M 0% /dev
tmpfs 488M 0 488M 0% /dev/shm
tmpfs 488M 7.6M 480M 2% /run
tmpfs 488M 0 488M 0% /sys/fs/cgroup
/dev/sda1 976M 141M 769M 16% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/sdb 100G 33M 100G 1% /opt/data/brick1
注:以上操作均在node01-node03上同时操作(其他节点同上)。
================================================================================================
#kubernetes使用glusterfs做持久化存储
https://github.com/gluster/gluster-kubernetes/blob/master/docs/examples/sample-gluster-endpoints.yaml
https://github.com/gluster/gluster-kubernetes/blob/master/docs/examples/sample-gluster-service.yaml
https://github.com/gluster/gluster-kubernetes/tree/master/docs/examples/dynamic_provisioning_external_gluster
https://github.com/gluster/gluster-kubernetes/blob/master/deploy/kube-templates/glusterfs-daemonset.yaml
###kubernetes上安装glusterfs客户端
#####在所有 k8s node 中安装 glusterfs 客户端
$ yum install -y glusterfs glusterfs-fuse
####配置 hosts
$ vi /etc/hosts
192.168.1.158 gfs-node01
192.168.1.151 gfs-node02
192.168.1.92 gfs-node03
####创建数据存储目录:
[root@gfs-node01 ~]# mkdir -p /opt/data/brick1/gfsdata
[root@gfs-node02 ~]# mkdir -p /opt/data/brick1/gfsdata
[root@gfs-node03 ~]# mkdir -p /opt/data/brick1/gfsdata
#####查看volume 状态:
[root@gfs-node01 ~]#gluster volume info
No volumes present
####创建GlusterFS磁盘(k8s-bigbdata):
[root@gfs-node01 ~]#gluster volume create k8s-bigbdata replica 3 gfs-node01:/opt/data/brick1/gfsdata gfs-node02:/opt/data/brick1/gfsdata gfs-node03:/opt/data/brick1/gfsdata force
volume create: k8s-bigbdata: success: please start the volume to access data
###启动 k8s-bigbdata
[root@gfs-node01 ~]# gluster volume start k8s-bigbdata
volume start: k8s-bigbdata: success
####配置 endpoints
$ curl -O https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/glusterfs/glusterfs-endpoints.json
####修改 endpoints.json ,配置 glusters 集群节点ip
# 每一个 addresses 为一个 ip 组
{
"kind": "Endpoints",
"apiVersion": "v1",
"metadata": {
"name": "glusterfs-cluster"
},
"subsets": [
{
"addresses": [
{
"ip": "192.168.1.158"
}
],
"ports": [
{
"port": 1990
}
]
},
{
"addresses": [
{
"ip": "192.168.1.151"
}
],
"ports": [
{
"port": 1990
}
]
},
{
"addresses": [
{
"ip": "192.168.1.92"
}
],
"ports": [
{
"port": 1990
}
]
}
]
}
####导入 glusterfs-endpoints.json
$ kubectl apply -f glusterfs-endpoints.json
####查看 endpoints 信息
$ kubectl get ep
###配置 service
$ curl -O https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/glusterfs/glusterfs-service.json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "glusterfs-cluster"
},
"spec": {
"ports": [
{"port": 1990}
]
}
}
####service.json 里面查找的是 enpointes 的名称与端口,端口默认配置为 1,我改成了1990
####导入 glusterfs-service.json
$ kubectl apply -f glusterfs-service.json
####查看 service 信息
$ kubectl get svc
####创建测试 pod
$ curl -O https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/glusterfs/glusterfs-pod.json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "glusterfs"
},
"spec": {
"containers": [
{
"name": "glusterfs",
"image": "nginx",
"volumeMounts": [
{
"mountPath": "/mnt/glusterfs",
"name": "glusterfsvol"
}
]
}
],
"volumes": [
{
"name": "glusterfsvol",
"glusterfs": {
"endpoints": "glusterfs-cluster",
"path": "k8s-bigbdata",
"readOnly": true
}
}
]
}
}
####编辑 glusterfs-pod.json
###修改 volumes 下的 path 为上面创建的 volume 名称
"path": "k8s-bigbdata"
####导入 glusterfs-pod.json
$ kubectl apply -f glusterfs-pod.json
####查看 pods 状态
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
glusterfs 1/1 Running 0 1m
####查看 pods 所在 node
$ kubectl describe pods/glusterfs
####登陆 node 物理机,使用 df 可查看挂载目录
$ df -h
172.20.0.113:k8s-volume 1073741824 0 1073741824 0% 172.20.0.113:k8s-volume 1.0T 0 1.0T 0% /var/lib/kubelet/pods/3de9fc69-30b7-11e7-bfbd-8af1e3a7c5bd/volumes/kubernetes.io~glusterfs/glusterfsvol
配置PersistentVolume
PersistentVolume(PV)和 PersistentVolumeClaim(PVC)是kubernetes提供的两种API资源,用于抽象存储细节。
管理员关注于如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载PVC到容器中而不需要关注存储卷采用何种技术实现。
PVC和PV的关系跟pod和node关系类似,前者消耗后者的资源。PVC可以向PV申请指定大小的存储资源并设置访问模式。
PV属性
storage容量
读写属性:分别为ReadWriteOnce:单个节点读写; ReadOnlyMany:多节点只读 ; ReadWriteMany:多节点读写
$ cat glusterfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: gluster-dev-volume
spec:
capacity:
storage: 8Gi
accessModes:
- ReadWriteMany
glusterfs:
endpoints: "glusterfs-cluster"
path: "k8s-bigbdata"
readOnly: false
####导入PV
$ kubectl apply -f glusterfs-pv.yaml
####查看 pv
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
gluster-dev-volume 8Gi RWX Retain Available 3s
PVC属性
访问属性与PV相同
容量:向PV申请的容量 <= PV总容量
配置PVC
$ cat glusterfs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: glusterfs-nginx
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
####导入 pvc
$ kubectl apply -f glusterfs-pvc.yaml
####查看 pvc
$ kubectl get pv
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
glusterfs-nginx Bound gluster-dev-volume 8Gi RWX 4s
创建 nginx deployment 挂载 volume
$ vi nginx-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: gluster-dev-volume
mountPath: "/usr/share/nginx/html"
volumes:
- name: gluster-dev-volume
persistentVolumeClaim:
claimName: glusterfs-nginx
####导入 deployment
$ kubectl apply -f nginx-deployment.yaml
####查看 deployment
$ kubectl get pods |grep nginx-dm
nginx-dm-3698525684-g0mvt 1/1 Running 0 6s
nginx-dm-3698525684-hbzq1 1/1 Running 0 6s
###查看 挂载
$ kubectl exec -it nginx-dm-3698525684-g0mvt -- df -h|grep k8s-volume
172.20.0.113:k8s-volume 1.0T 0 1.0T 0% /usr/share/nginx/html
####创建文件 测试
$ kubectl exec -it nginx-dm-3698525684-g0mvt -- touch /usr/share/nginx/html/index.html
$ kubectl exec -it nginx-dm-3698525684-g0mvt -- ls -lt /usr/share/nginx/html/index.html
-rw-r--r-- 1 root root 0 May 4 11:36 /usr/share/nginx/html/index.html
###验证 glusterfs
# 因为我们使用分布卷,所以可以看到某个节点中有文件
[root@test-001 ~] ls /opt/data/brick1/gfsdata
[root@test-002 ~] ls /opt/data/brick1/gfsdata
index.html
[root@test-003 ~] ls /opt/data/brick1/gfsdata
=========================================================================================================
#用Heketi作为kubernetes的持久存储GlusterFS
yum install -y heketi-client
yum install heketi
https://github.com/heketi/heketi/releases
https://www.cnblogs.com/breezey/p/9589047.html
https://www.cnblogs.com/breezey/p/8849466.html
https://blog.youkuaiyun.com/wenwenxiong/article/details/79530631
https://jimmysong.io/kubernetes-handbook/practice/using-heketi-gluster-for-persistent-storage.html
#分布式复制卷的最佳实践:
1)搭建条件
- 块服务器的数量必须是复制的倍数
- 将按块服务器的排列顺序指定相邻的块服务器成为彼此的复制
例如,8台服务器:
- 当复制副本为2时,按照服务器列表的顺序,服务器1和2作为一个复制,3和4作为一个复制,5和6作为一个复制,7和8作为一个复制
- 当复制副本为4时,按照服务器列表的顺序,服务器1/2/3/4作为一个复制,5/6/7/8作为一个复制
2)创建分布式复制卷
磁盘存储的平衡
平衡布局是很有必要的,因为布局结构是静态的,当新的 bricks 加入现有卷,新创建的文件会分布到旧的 bricks 中,所以需要平衡布局结构,使新加入的 bricks 生效。
布局平衡只是使新布局生效,并不会在新的布局中移动老的数据,如果你想在新布局生效后,重新平衡卷中的数据,还需要对卷中的数据进行平衡。
#在gv2的分布式复制卷的挂载目录中创建测试文件入下
[root@data-1-4 opt]# touch {X..Z}
#新创建的文件只在老的brick中有,在新加入的brick中是没有的
[root@data-1-4 opt]# ll /storage/brick1
总用量 0
[root@data-1-3 ~]# ll /storage/brick1
总用量 0
[root@data-1-1 ~]# ls /storage/brick2
1 2 3 4 5 6 X Y Z
[root@data-1-2 ~]# ls /storage/brick2
1 2 3 4 5 6 X Y Z
# 从上面可以看到,新创建的文件还是在之前的 bricks 中,并没有分布中新加的 bricks 中
# 下面进行磁盘存储平衡
[root@data-1-2 ~]# gluster volume rebalance gv2 start
#查看平衡存储状态
[root@data-1-4 opt]# gluster volume rebalance gv2 status
# 查看磁盘存储平衡后文件在 bricks 中的分布情况
[root@data-1-3 ~]# ls /storage/brick1
1 5 Y Z
[root@data-1-4 opt]# ls /storage/brick1
1 5 Y Z
[root@data-1-1 ~]# ls /storage/brick2
2 3 4 6 X
[root@data-1-2 ~]# ls /storage/brick2
2 3 4 6 X
#从上面可以看出部分文件已经平衡到新加入的brick中了
每做一次扩容后都需要做一次磁盘平衡。 磁盘平衡是在万不得已的情况下再做的,一般再创建一个卷就可以了。
#移除 brick
你可能想在线缩小卷的大小,例如:当硬件损坏或网络故障的时候,你可能想在卷中移除相关的 bricks。
注意:当你移除 bricks 的时候,你在 gluster 的挂载点将不能继续访问数据,只有配置文件中的信息移除后你才能继续访问 bricks 中的数据。
当移除分布式复制卷或者分布式条带卷的时候,移除的 bricks 数目必须是 replica 或者 stripe 的倍数。
但是移除brick在生产环境中基本上不做的,没什么意思,如果是硬盘坏掉的话,直接换个好的硬盘即可,然后再对新的硬盘设置卷标识就可以使用了,后面会演示硬件故障或系统故障的解决办法。
#移除gv2中的data-1-3 data-1-4下的brick
[root@data-1-2 ~]# gluster volume stop gv2
[root@data-1-2 ~]# gluster volume remove-brick gv2 replica 2 data-1-3:/storage/brick1 data-1-4:/storage/brick1 force
[root@data-1-2 ~]# gluster volume start gv2
[root@data-1-3 ~]# ls /storage/brick1
1 5 Y Z
# 如果误操作删除了后,其实文件还在 /storage/brick1 里面的,加回来就可以了
[root@data-1-3 ~]# gluster volume stop gv2
[root@data-1-3 ~]# gluster volume add-brick gv2 replica 2 data-1-3:/storage/brick1 data-1-4:/storage/brick1 force
[root@data-1-3 ~]# gluster volume info gv2
Volume Name: gv2
Type: Distributed-Replicate
Volume ID: 27b85504-0a78-4dae-9332-056da410be2e
Status: Stopped
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: data-1-1:/storage/brick2
Brick2: data-1-2:/storage/brick2
Brick3: data-1-3:/storage/brick1
Brick4: data-1-4:/storage/brick1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
#删除卷
一般会用在命名不规范的时候才会删除
[root@data-1-3 ~]# gluster volume stop gv1
[root@data-1-3 ~]# gluster volume delete gv1
模拟误删除卷信息故障及解决办法
[root@data-1-3 mnt]# ls /var/lib/glusterd/vols
gv2 gv3 gv4
#删除卷gv4的卷信息
[root@data-1-3 brick2]# rm -rf /var/lib/glusterd/vols/gv4
#再查看卷信息情况如下:gv4卷信息被删除了
[root@data-1-3 mnt]# ls /var/lib/glusterd/vols
gv2 gv3
#因为其他节点服务器上的卷信息是完整的,比如从data-1-4上同步所有卷信息如下:
[root@data-1-3 mnt]# gluster volume sync data-1-4
#验证卷信息是否同步过来
[root@data-1-3 mnt]# ls /var/lib/glusterd/vols
gv2 gv3 gv4
模拟复制卷数据不一致故障及解决办法
#复制卷的存储位置的数据如下:
[root@data-1-1 ~]# ls /storage/brick2
2 3 4 6 X
[root@data-1-2 ~]# ls /storage/brick2
2 3 4 6 X
#接着在data-1-1上删除一个数据来模拟复制卷数据不一致
[root@data-1-1 ~]# rm -f /storage/brick2/X
[root@data-1-1 ~]# ls /storage/brick2
2 3 4 6
[root@data-1-2 ~]# ls /storage/brick2
2 3 4 6 X
#通过访问这个复制卷的挂载点的数据来同步数据
[root@data-1-3 mnt]# mount -t glusterfs 127.0.0.1:/gv2 /opt/
[root@data-1-3 mnt]# cat /opt/X
#这时候再看复制卷的数据是否同步成功
[root@data-1-1 ~]# ls /storage/brick2
2 3 4 6 X
[root@data-1-2 ~]# ls /storage/brick2
2 3 4 6 X
8、glusterfs分布式存储优化
GlusterFS文件系统优化
Auth.allow #IP访问授权;缺省值(*.allow all);合法值:Ip地址
Cluster.min-free-disk #剩余磁盘空间阀值;缺省值(10%);合法值:百分比
Cluster.stripe-block-size #条带大小;缺省值(128KB);合法值:字节
Network.frame-timeout #请求等待时间;缺省值(1800s);合法值:1-1800
Network.ping-timeout #客户端等待时间;缺省值(42s);合法值:0-42
Nfs.disabled #关闭NFS服务;缺省值(Off);合法值:Off|on
Performance.io-thread-count #IO线程数;缺省值(16);合法值:0-65
Performance.cache-refresh-timeout #缓存校验时间;缺省值(1s);合法值:0-61
Performance.cache-size #读缓存大小;缺省值(32MB);合法值:字节
Performance.quick-read: #优化读取小文件的性能
Performance.read-ahead: #用预读的方式提高读取的性能,有利于应用频繁持续性的访问文件,当应用完成当前数据块读取的时候,下一个数据块就已经准备好了。
Performance.write-behind: #先写入缓存内,在写入硬盘,以提高写入的性能。
Performance.io-cache: #缓存已经被读过的、
系统优化实例
[root@data-1-1 ~]# gluster volume set gv4 performance.write-behind on
volume set: success
[root@data-1-1 ~]# gluster volume set gv4 performance.flush-behind on
volume set: success
[root@data-1-1 ~]# gluster volume set gv4 performance.cache-refresh-timeout 1
volume set: success
[root@data-1-1 ~]# gluster volume info gv4
Volume Name: gv4
Type: Distribute
Volume ID: bef2ec82-43fd-4219-be8f-b326a34900c9
Status: Started
Snapshot Count: 0
Number of Bricks: 2
Transport-type: tcp
Bricks:
Brick1: data-1-1:/storage/brick1
Brick2: data-1-2:/storage/brick1
Options Reconfigured:
performance.cache-refresh-timeout: 1
performance.flush-behind: on
performance.write-behind: on
transport.address-family: inet
nfs.disable: on
#监控及日常维护
使用zabbix自带的模板即可,CPU、内存、磁盘空间、主机运行时间、系统load。日常情况要查看服务器监控值,遇到报警要及时处理。
#看下节点有没有在线
gluster volume status
#启动完全修复
gluster volume heal gv2 full
#查看需要修复的文件
gluster volume heal gv2 info
#查看修复成功的文件
gluster volume heal gv2 info healed
#查看修复失败的文件
gluster volume heal gv2 heal-failed
#查看主机的状态
gluster peer status
#查看脑裂的文件
gluster volume heal gv2 info split-brain
#激活quota功能
gluster volume quota gv2 enable
#关闭quota功能
gulster volume quota gv2 disable
#目录限制(卷中文件夹的大小)
gluster volume quota gv2 limit-usage /data 20MB --表示/mnt挂载点下的data目录
#quota信息列表
gluster volume quota gv2 list
#限制目录的quota信息
gluster volume quota gv2 list /data
#设置信息的超时时间
gluster volume set gv2 features.quota-timeout 5
#删除某个目录的quota设置
gluster volume quota gv2 remove /data
例如队文件夹的限额设置:
[root@data-1-1 ~]# mount -t glusterfs 127.0.0.1:/gv3 /mnt/
[root@data-1-1 ~]# ls /mnt
10M.file 10M.file2 20M.file mydir
[root@data-1-1 ~]# gluster volume quota gv3 limit-usage /mydir 20MB
[root@data-1-1 ~]# dd if=/dev/zero of=50M.file bs=1024 count=50000
[root@data-1-1 ~]# cp 50M.file /mnt/mydir/
cp: cannot create regular file `/mnt/mydir/50M.file': Disk quota exceeded
#复制大于限额数的时候,提示磁盘限额限制 备注:
quota功能,主要是对挂载点下的某个目录进行空间限额。如:/mnt/mydir目录,而不是对组成卷组的空间进行限制。
9、Gluster日常维护及故障处理
1、硬盘故障
如果底层做了raid配置,有硬件故障,直接更换硬盘,会自动同步数据。
如果没有做raid处理方法:
因为生产环境中主要部署分布式复制卷,所以这里以复制卷的方式演示硬盘故障后修复复制卷的操作,下面在虚拟机上演示如下:
1、首先在虚拟机中移除损坏的硬盘,重新添加一个硬盘,添加的新硬盘在虚拟机中是不立刻生效的,所以还要重启服务器
2、新添加的硬盘序号是在其他硬盘后,所以重启服务器后,系统会对硬盘的序号做自动调整,那么新添加的硬盘序号和损坏的硬盘序号就不一样了
3、格式化新添加的硬盘mkfs.xfs -f /dev/sdd,并对fstab表做一下调整,让以前的硬盘挂载点保持不变,将新添加的硬盘对应的挂载点设置成损坏硬盘的挂载点
4、重新挂载 mount -a
接下来便为复制卷的修复过程
#恢复复制卷 brick1
#恢复流程
1、重新建立故障brick目录
cd /storage/
setfattr -n trusted.gfid -v
0x00000000000000000000000000000001 brick1
setfattr -n trusted.glusterfs.dht -v
0x000000010000000000000000ffffffff brick1
setfattr -n trusted.glusterfs.volume-id -v
0xcc51d546c0af4215a72077ad9378c2ac brick1
-v 的参数设置成你的值
2、设置扩展属性(参考另一个复制 brick)
3、重启 glusterd服务
4、触发数据自修复
find /opt -type f -print0 | xargs -0 head -c1 >/dev/null >/dev/null
#在好的机器上找到复制卷的brick 查看扩展属性
[root@data-1-3 storage]# getfattr -d -m . -e hex brick1
# file: brick1
trusted.gfid=0x00000000000000000000000000000001
trusted.glusterfs.dht=0x00000001000000007fffffffffffffff
trusted.glusterfs.dht.commithash=0x3334383937323537363200
trusted.glusterfs.volume-id=0x27b855040a784dae9332056da410be2e
#brick1中的数据为
[root@data-1-3 ~]# ls /storage/brick1
1 5 hah.txt Y Z
#修复data-1-4上的brick1
[root@data-1-4 storage]# setfattr -n trusted.gfid -v 0x00000000000000000000000000000001 brick1
[root@data-1-4 storage]# setfattr -n trusted.glusterfs.dht -v 0x00000001000000007fffffffffffffff brick1
[root@data-1-4 storage]# setfattr -n trusted.glusterfs.volume-id -v 0x27b855040a784dae9332056da410be2e brick1
[root@data-1-4 storage]# getfattr -d -m . -e hex brick1 # file: brick1
trusted.gfid=0x00000000000000000000000000000001
trusted.glusterfs.dht=0x00000001000000007fffffffffffffff
trusted.glusterfs.volume-id=0x27b855040a784dae9332056da410be2e
[root@data-1-4 storage]# /etc/init.d/glusterd restart
#重启glusterfs查看brick1中的数据还是没有的,那么试着重启复制卷
[root@data-1-4 storage]# gluster volume stop gv2
[root@data-1-4 storage]# gluster volume start gv2
#结果brick1中依然没有数据
最终的方式就是在data-1-3上的挂载点内访问数据才可同步到data-1-4上的brick1中
[root@data-1-3 ~]# cat /opt/1
[root@data-1-4 storage]# ls brick1
1 5 Y
2、主机故障
一台节点故障的情况包括以下情况:
a)物理故障;
b)同时有多快硬盘故障,造成数据丢失;
c)系统损坏不可修复
解决方法:
1)找一台完全一样的机器,至少要保证数量和大小一致,安装系统,配置和故障机器同样的ip安装gluster软件,保证配置都一样,在其他健康的节点上执行命令gluster peer status,查看故障服务器的uuid。
2)修改新加机器的/var/lib/glusterd/glusterd.info和故障机器的一样。
[root@data-1-4 ~]# cat /var/lib/glusterd/glusterd.info
UUID=eaeef3f8-247b-4ff2-9f7b-6fdb678bb36a
在新机器挂在目录上执行磁盘故障的操作,在任意节点上执行
[root@data-1-4 ~]# gluster volume heal gv1 full 就会自动开始同步,但是同步的时候会影响整个系统的性能。
3)查看状态
[root@drbd01~]# gluster volume heal gv2 info