集群(cluster)

image.png

集群简介

通过高速网络将很多服务器集中起来,作为一个整体对外提供同一种服务,在客户端看起来像只有一个服务器。
集群在扩展性、性能方面都可以做到很灵活。在较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益。
任务调度是集群系统中的核心技术。
创建什么样架构的集群服务器,取决于公司的业务情况,访问量需求。

集群目的

提高性能:如计算密集型应用,如:天气预报、核试验模拟
降低成本:相对百万美元级的超级计算机,价格便宜
提高可拓展性:只要增加集群节点即可
增强可靠性:多个节点完成相同功能,避免单点故障

集群分类

负载均衡集群(LB-Load Balance)
-客户端负载在计算机集群中尽可能平均分摊
高可用集群(HA-High Availability)
-避免单点故障,当一个系统发生故障时,可以快速迁移
高性能计算集群(HPC-High Performance Computing)
-通过以集群开发的并行应用程序,解决复杂的科学问题

LVS概述

image.png

LVS介绍

  • LVS(Linux Virtual Server),Linux虚拟服务器
  • 作者:章文嵩。国防科技大学读博士期间编写
  • 实现高可用的负载均衡集群、可伸缩的Web、Mail、Cache和Media等网络服务
  • 最终目的是利用Linux操作系统和LVS集群软件实现一个高可用、高性能、低成本的服务器应用集群

    LVS集群组成

    前端:负载均衡层
    -有一台或多台负载调度器构成(可采用LVS组成,之前采用Nginx-proxy代理实现)
    中间:服务器群组层
    -由一组实际运行应用服务的服务器组成
    底端:数据共享存储层
    -提供共享存储空间的存储区域

    LVS术语

  • 调度服务器Director Server:调度服务器(LVS服务器)将负载分发到Real Server

  • 真实服务器Real Server:提供服务的服务器
  • VIP:虚拟地址,提供给用户访问的地址
  • DIP:指定地址,LVS服务器上与真实服务器通信的地址
  • RIP:真实地址,真实服务器的地址

    LVS工作模式

    NAT:网络地址转换

    1. - 通过网络地址转换实现的虚拟服务器
    2. - 大并发访问时,调度器的性能成为瓶颈

DR:路由模式

     - 直接使用路由技术实现虚拟服务器
     - 节点服务的需要配置VIP,注意MAC地址广播
     - 只管分发,不管数据接收

TUN:隧道模式(不常用)

     - 通过隧道方式实现虚拟服务器

负载均衡调度算法

常见调度算法(4种)

     - 轮询(Round Robin)
     - 加权轮询(Weighted Round Robin)
     - 最少连接(Least Connections)
     - 加权最少连接(Weighted Least Connections)

其他调度算法(6种)了解,不常用

     - 源地址散列(Source Hashing)
     - 目标地址散列(Destination Hashing)
     - 基于局部性的最少链接
     - 带复制的基于局部性最少链接
     - 最短的期望的延退
     - 最少队列调度

LVS-NAT集群

操作流程

image.png

image.png

基础环境准备

  • client1:eth0->192.168.4.10,网关192.168.4.5
  • lvs1: eth0 -> 192.168.4.5;eth1->192.168.2.5
  • web1:eth1->192.168.2.100;网关192.168.2.5
  • web2:eth1->192.168.2.200;网关192.168.2.5

1)配置初始化4台虚拟机(配置ip、yum、关防火墙)

# 创建4台虚拟机
[root@zzgrhel8 ~]# clone-vm7 
Enter VM number: 1    # 此处填的数字,是虚拟机编号
[root@zzgrhel8 ~]# clone-vm7 
Enter VM number: 2
[root@zzgrhel8 ~]# clone-vm7 
Enter VM number: 3
[root@zzgrhel8 ~]# clone-vm7 
Enter VM number: 4

# 查看虚拟机
[root@zzgrhel8 ~]# virsh list --all
 Id   名称          状态
--------------------------
 -    tedu_node01   关闭
 -    tedu_node02   关闭
 -    tedu_node03   关闭
 -    tedu_node04   关闭

# 启动虚拟机
[root@zzgrhel8 ~]# for i in {1..4}
> do
> virsh start tedu_node0$i
> done

# 初始化虚拟机
[root@zzgrhel8 ~]# virsh console tedu_node01  # 连接tedu_node01控制台
localhost login: root
Password: 123456
# 登陆之后,将以下内容粘贴到终端
hostnamectl set-hostname client1
nmcli connection modify eth0 ipv4.method manual ipv4.addresses 192.168.4.10/24
nmcli connection down eth0
nmcli connection up eth0
echo a | passwd --stdin root
nmcli connection modify eth0 ipv4.gateway 192.168.4.5
nmcli connection down eth0
nmcli connection up eth0

# 退出
[root@localhost ~]# exit
# 退出之后,按ctrl+]可回到真机

# 真机通过ssh连接client1
[root@zzgrhel8 ~]# rm -f ~/.ssh/known_hosts 
[root@zzgrhel8 ~]# ssh 192.168.4.10


# 配置第2台机器作为lvs1
[root@zzgrhel8 ~]# virsh console tedu_node02
Kernel 3.10.0-862.el7.x86_64 on an x86_64

localhost login: root
Password: 123456

# 登陆之后,将以下内容复制到命令行
hostnamectl set-hostname lvs1
nmcli connection modify eth0 ipv4.method manual ipv4.addresses 192.168.4.5/24
nmcli connection down eth0
nmcli connection up eth0
nmcli connection modify eth1 ipv4.method manual ipv4.addresses 192.168.2.5/24
nmcli connection down eth1
nmcli connection up eth1
echo a | passwd --stdin root

# 退出
[root@localhost ~]# exit
# 退出之后,按ctrl+]可回到真机

# 真机通过ssh连接lvs1
[root@zzgrhel8 ~]# ssh 192.168.4.5


# 配置第3台机器作为web1
[root@zzgrhel8 ~]# virsh console tedu_node03
localhost login: root
Password: 123456

# 登陆之后,将以下内容复制到命令行
hostnamectl set-hostname web1
nmcli connection modify eth1 ipv4.method manual ipv4.addresses 192.168.2.100/24
nmcli connection down eth1
nmcli connection up eth1
nmcli connection modify eth1 ipv4.gateway 192.168.2.5
nmcli connection down eth1
nmcli connection up eth1
echo a | passwd --stdin root

# 退出
[root@localhost ~]# exit
# 退出之后,按ctrl+]可回到真机

# 真机通过ssh连接web1
[root@zzgrhel8 ~]# ssh 192.168.2.100


# 配置第4台机器作为web2
[root@zzgrhel8 ~]# virsh console tedu_node04
localhost login: root
Password: 123456

# 登陆之后,将以下内容复制到命令行
hostnamectl set-hostname web2
nmcli connection modify eth1 ipv4.method manual ipv4.addresses 192.168.2.200/24
nmcli connection down eth1
nmcli connection up eth1
nmcli connection modify eth1 ipv4.gateway 192.168.2.5
nmcli connection down eth1
nmcli connection up eth1
echo a | passwd --stdin root

# 退出
[root@localhost ~]# exit
# 退出之后,按ctrl+]可回到真机

# 真机通过ssh连接web2
[root@zzgrhel8 ~]# ssh 192.168.2.200

通过clone-vm7创建出来的虚拟机器,如果有192.168.4.0网段的地址,yum已经配置了。虚拟机已关闭selinux和防火墙 。
image.png
为了方便下面所有的IP都采用简写,如4.10代表192.168.4.10,2.100代表192.168.2.100。
英语词汇:source(src)代表源地址,destination(dest或dst)代表目标地址。
LVS采用的是路由器的NAT通讯原理!通讯流程如下:
1)客户端发送请求数据包(src:4.10,dst:4.5)
2)数据包被发送给LVS调度器,调度器做NAT地址转换(外网转内网,内网转外网)
a)数据包被修改为src:4.10,dst:2.100(dst也有可能被修改为2.200,随机的)
b)LVS调度器把数据包转发给后端真正的web服务器(2.100)
3)web1收到数据包开始回应数据(rsc:2.100,dst:4.10)
备注:谁访问就给谁回复数据,因为src是4.10,所以应该给4.10回应数据!
但是,自己是2.100,对方是4.10,跨网段默认无法通讯,如何解决???
Web1和web2都需要设置默认网关(也就是192.168.2.5)
4)web1想发送数据给4.10但是又无法与其通讯,所以数据包被交给默认网关
5)LVS调度器(软路由)收到后端web发送过来的数据后,再次做NAT地址转换
a)数据包被修改为src:4.5,dst:4.10
b)LVS调度器把数据包转发给客户端主机
6)客户端接收网页数据内容
注意:客户端访问的是4.5,最后是4.5给客户端回复的网页数据!!!!
2)配置2台web服务器

[root@web1 ~]# vim /etc/yum.repos.d/local.repo 
[local_repo]
name=CentOS-$releasever - Base
baseurl=ftp://192.168.2.254/centos-1804
enabled=1
gpgcheck=0
[root@web1 ~]# yum install -y httpd
# web2同样操作

# 创建测试页面
[root@web1 ~]# echo "192.168.2.100" > /var/www/html/index.html
[root@web2 ~]# echo "apache web server2" > /var/www/html/index.html
[root@web1 ~]# systemctl enable httpd --now
[root@web2 ~]# systemctl enable httpd --now

# 在lvs1上测试到web服务器的访问
[root@lvs1 ~]# curl http://192.168.2.100/
192.168.2.100
[root@lvs1 ~]# ^100^200   # 将上一条命令中的100换成200,执行
curl http://192.168.2.200/
apache web server2

小技巧:[root@lvs1 ~]# ^100^200 # 将上一条命令中的100换成200,执行

ipvsadm使用说明

  • -A: 添加虚拟服务器
  • -E: 编辑虚拟服务器
  • -t: 添加真实tcp服务器
  • -u: 添加真实udp服务器
  • -s: 指定调度算法。如轮询rr/加权轮询wrr/最少连接lc/加权最少连接wlc
  • -a: 添加虚拟服务器后,向虚拟服务器中加入真实服务器
  • -r: 指定真实服务器
  • -w: 设置权重
  • -m: 指定工作模式为NAT
  • -g: 指定工作模式为DR
    • image.png

ipvsadm语法案例
image.png

配置LVS NAT模式

  • 确保lvs1的ip转发功能已经打开。该功能需要改变内核参数 ```shell

    查看ip转发功能的内核参数

    [root@lvs1 ~]# sysctl -a # 查看所有的内核参数 [root@lvs1 ~]# sysctl -a | grep ip_forward # 查看ip_foward参数 net.ipv4.ip_forward = 1 # 1表示打开转发,0表示关闭转发

永久设置打开ip_forward功能

[root@lvs1 ~]# echo ‘net.ipv4.ip_forward = 1’ >> /etc/sysctl.conf [root@lvs1 ~]# sysctl -p #使sysctl.conf配置生效

测试从客户端到服务器的访问

[root@client1 ~]# curl http://192.168.2.100/ 192.168.2.100 [root@client1 ~]# curl http://192.168.2.200/ apache web server2


   - **创建配置集群服务器(LVS)**
```shell
[root@lvs1 ~]# yum install -y ipvsadm  # 安装LVS
# 为web服务器创建虚拟服务器,使用rr调度算法
[root@lvs1 ~]# ipvsadm -A -t 192.168.4.5:80 -s rr
# 查看配置
[root@lvs1 ~]# ipvsadm -Ln
# 向虚拟服务器中添加RIP
[root@lvs1 ~]# ipvsadm -a -t 192.168.4.5:80 -r 192.168.2.100 -w 1 -m
[root@lvs1 ~]# ipvsadm -a -t 192.168.4.5:80 -r 192.168.2.200 -w 2 -m
# 查看配置
[root@lvs1 ~]# ipvsadm -Ln
# 验证
[root@client1 ~]# for i in {1..4}
> do
> curl http://192.168.4.5/
> done
apache web server2
192.168.2.100
apache web server2
192.168.2.100    #权重没生效原因,调度算法为rr

修改调度模式为加权轮询

# 修改调度模式为加权轮询
[root@lvs1 ~]# ipvsadm -E -t 192.168.4.5:80 -s wrr
# 验证配置
[root@client1 ~]# for i in {1..6}; do curl http://192.168.4.5/; done
apache web server2
apache web server2
192.168.2.100
apache web server2
apache web server2
192.168.2.100

LVS DR模式

操作流程

image.pngimage.png
LVS DR模式,LVS主机和web服务器都是单网卡。它们连在同一网络中

修改实验环境

# 删除lvs虚拟服务器配置
[root@lvs1 ~]# ipvsadm -D -t 192.168.4.5:80
[root@lvs1 ~]# ipvsadm -Ln

# 删除lvs1上eth1的配置
[root@lvs1 ~]# nmcli connection modify eth1 ipv4.method disabled ipv4.addresses ''
[root@lvs1 ~]# ifdown eth1

小技巧:修改配置文件方式修改ip地址

# 修改web1的配置:停掉eth1的地址。配置eth0的地址为192.168.4.100
# 进入网卡配置文件目录
[root@web1 ~]# cd /etc/sysconfig/network-scripts/
# eth0网卡的配置文件叫ifcfg-eth0
[root@web1 network-scripts]# ls ifcfg-eth*
ifcfg-eth0  ifcfg-eth1    ifcfg-eth2  ifcfg-eth3
# 配置eth0地址
[root@web1 network-scripts]# vim ifcfg-eth0
TYPE=Ethernet             # 网络类型为以太网
BOOTPROTO=none            # IP地址是静态配置的,也可以用static
NAME=eth0                 # 为设备重命名
DEVICE=eth0               # 网卡设备名
ONBOOT=yes                # 开机激活网卡
IPADDR=192.168.4.100      # IP地址
NETMASK=255.255.255.0     # 子网掩码
GATEWAY=192.168.4.254     # 网关
[root@web1 network-scripts]# ifdown eth0; ifup eth0  # 禁用激活网卡

# 在web1上停掉eth1
[root@web1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
.....
ONBOOT=no
[root@web1 ~]# ifdown eth1

# 同样方法修改web2的网络

配置LVS DR模式

  1. 在lvs1的eth0上配置vip 192.168.4.15。通过为eth0创建逻辑端口的方式配置vip,为逻辑端口起名为eth0:0

    [root@lvs1 ~]# cd /etc/sysconfig/network-scripts/
    [root@lvs1 network-scripts]# cp ifcfg-eth0 ifcfg-eth0:0
    [root@lvs1 network-scripts]# vim ifcfg-eth0:0
    TYPE=Ethernet
    BOOTPROTO=none
    NAME=eth0:0
    DEVICE=eth0:0
    ONBOOT=yes
    IPADDR=192.168.4.15
    PREFIX=24
    [root@lvs1 network-scripts]# ifup eth0:0   #或systemctl restart network 重启网络服务
    [root@lvs1 network-scripts]# ifconfig # 查看新的地址
    #常见问题:RHEL7和Centos7系统中有两个管理网络的服务,有可能冲突?
    #解决方法:关闭NetworkManager服务后重启network即可。
    
  2. 在2台web服务器的lo上配置vip 192.168.4.15

    [root@web1 ~]# cd /etc/sysconfig/network-scripts/
    [root@web1 network-scripts]# cp ifcfg-lo ifcfg-lo:0
    [root@web1 network-scripts]# vim ifcfg-lo:0
    # 这里的子网掩码必须是32(也就是全255),网络地址与IP地址一样,广播地址与IP地址也一样。
    DEVICE=lo:0
    IPADDR=192.168.4.15
    NETMASK=255.255.255.255
    NETWORK=192.168.4.15
    BROADCAST=192.168.4.15
    ONBOOT=yes
    NAME=lo:0
    [root@web1 network-scripts]# ifup lo:0
    [root@web1 network-scripts]# ifconfig 
    # 把web1的配置拷贝到web2上
    [root@web1 network-scripts]# scp ./ifcfg-lo:0 192.168.4.200:/etc/sysconfig/network-scripts/
    [root@web2 ~]# ifup lo:0
    [root@web2 ~]# ifconfig
    
  3. 在2台web服务器上配置内核参数,使得它们不响应对192.168.4.15的请求

防止地址冲突的问题
这里因为web1也配置与调度器一样的VIP地址,默认肯定会出现地址冲突;
sysctl.conf文件写入这下面四行的主要目的就是访问192.168.4.15的数据包,只有调度器会响应,其他主机都不做任何响应,这样防止地址冲突的问题。

[root@web1 ~]# vim /etc/sysctl.conf
#文件末尾手动写入如下4行内容,英语词汇:ignore(忽略、忽视),announce(宣告、广播通知)
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
#当有arp广播问谁是192.168.4.15时,本机忽略该ARP广播,不做任何回应(防止进站冲突)
#本机不要向外宣告自己的lo回环地址是192.168.4.15(防止出站冲突)
[root@web1 ~]# sysctl -p
  1. 在lvs1上配置虚拟服务器 ```shell

    创建虚拟服务器

    [root@lvs1 ~]# ipvsadm -A -t 192.168.4.15:80 -s wlc

    向虚拟服务器中加真实服务器

    [root@lvs1 ~]# ipvsadm -a -t 192.168.4.15:80 -r 192.168.4.100 -w 1 -g [root@lvs1 ~]# ipvsadm -a -t 192.168.4.15:80 -r 192.168.4.200 -w 2 -g

    查看配置

    [root@lvs1 ~]# ipvsadm -Ln

客户验证

[root@client1 ~]# for i in {1..6}; do curl http://192.168.4.15/; done apache web server2 192.168.2.100 apache web server2 apache web server2 192.168.2.100 apache web server2

<a name="klCdG"></a>
### LVS扩展知识
默认LVS不带健康检查功能,需要自己手动编写动态检测脚本,实现该功能:(参考脚本如下,仅供参考)
```shell
[root@proxy ~]# vim check.sh
#!/bin/bash
VIP=192.168.4.15:80
RIP1=192.168.4.100
RIP2=192.168.4.200
while :
do  
    for IP in $RIP1 $RIP2   
    do           
        curl -s http://$IP &>/dev/null
        if [ $? -eq 0 ];then          
                ipvsadm -Ln |grep -q $IP || ipvsadm -a -t $VIP -r $IP   
      else          
               ipvsadm -Ln |grep -q $IP && ipvsadm -d -t $VIP -r $IP    
    fi
  done
sleep 1
done

image.pngKeepAlived高可用集群

KeepAlived概述

  • KeepAlived用于实现高可用集群
  • 它的工作原理是VRRP(虚拟冗余路由协议)
  • KeepAlived最初是为了LVS设计的,专门监控各服务器节点的状态

    KeepAlived运行原理

  • KeepAlived检测每个服务器节点的状态

  • 服务器节点异常或工作出现故障,KeepAlived将故障节点从集群系统中剔除
  • 故障节点恢复后,KeepAlived再将其加入到集群系统中
  • 所有工作自动完成,无需人工干预

    keepalived健康检查方式

    KeepAlived服务

    image.png
    环境说明:

  • web1:eth0->192.168.4.100/24

  • web2:eth0->192.168.4.200/24

    安装keepalived软件

    # 在两台web服务器上安装keepalived
    [root@web1 ~]# yum install -y keepalived
    [root@web2 ~]# yum install -y keepalived
    

    配置keepalived文件解析

    1)修改web1服务器Keepalived配置文件 ```shell

    修改配置文件

    [root@web1 ~]# vim /etc/keepalived/keepalived.conf 12 router_id web1 # 设置本机在集群中的唯一识别符 13 vrrp_iptables # 自动配置iptables放行规则 … … 20 vrrp_instance VI_1 { 21 state MASTER # 状态,主为MASTER,备为BACKUP 22 interface eth0 # 网卡 23 virtual_router_id 51 # 虚拟路由器地址 24 priority 100 # 优先级 25 advert_int 1 # 发送心跳消息的间隔 26 authentication { 27 auth_type PASS # 认证类型为共享密码 28 auth_pass 1111 # 集群中的机器密码相同,才能成为集群 29 }
    30 virtual_ipaddress { 31 192.168.4.80/24 # VIP地址 32 }
    33 }

    删除下面所有行

打开一个新的终端监控日志,新日志将出持续显示在屏幕上。退出按ctrl+c

[root@web1 ~]# tail -f /var/log/messages

在前一个终端启动服务

[root@web1 ~]# systemctl start keepalived

等几秒服务完全启动后,可以查看到vip

[root@web1 ~]# ip a s eth0 # eth0将会增加额外的4.80地址

2)修改web2服务器Keepalived配置文件<br />可以scp web1的配置文件,修改route_ip;state;priority即可<br />因为是高可用集群,所以启动keepalived服务eth0中不会出现vip(192.168.4.80)
```shell
[root@web1 ~]# scp /etc/keepalived/keepalived.conf 192.168.4.200:/etc/keepalived/
[root@web2 ~]# vim /etc/keepalived/keepalived.conf 
 12    router_id web2          # 改id
 13    vrrp_iptables
 ... ... 
 20 vrrp_instance VI_1 {
 21     state BACKUP           # 改状态
 22     interface eth0
 23     virtual_router_id 51
 24     priority 80            # 改优先级
 25     advert_int 1
 26     authentication {
 27         auth_type PASS
 28         auth_pass 1111
 29     }
 30     virtual_ipaddress {
 31         192.168.4.80/24
 32     }
 33 }

# 启动服务
[root@web2 ~]# systemctl start keepalived
# 查看地址,eth0不会出现vip
[root@web2 ~]# ip a s eth0

3)测试:客户端访问4.80

[root@client1 ~]# curl http://192.168.4.80/
192.168.2.100

# 在web2上监控日志
[root@web2 ~]# tail -f /var/log/messages | grep -i keepalived
# 关闭web1上的keepalived,观察web2的日志输出
[root@web1 ~]# systemctl stop keepalived.service 

# 测试,现在访问4.80,看到是web2上的内容
[root@client1 ~]# curl http://192.168.4.80/
apache web server2

# 在web2上查看vip,可以查看到vip 192.168.4.80
[root@web2 ~]# ip a s eth0

KeepAlived+LVS高可用、负载均衡的web集群

image.png

环境准备

  • 环境说明:LVS-DR模式(沿用之前环境增加一台lvs2)
    • client1:eth0->192.168.4.10
    • lvs1:eth0->192.168.4.5
    • lvs2:eth0->192.168.4.6
    • web1:eth0->192.168.4.100
    • web2:eth0->192.168.4.200 ```shell

      关闭2台web服务器上的keepalived

      [root@web1 ~]# systemctl stop keepalived.service [root@web2 ~]# systemctl stop keepalived.service [root@web1 ~]# yum remove -y keepalived [root@web2 ~]# yum remove -y keepalived

创建新虚拟机lvs2

[root@zzgrhel8 ~]# clone-vm7 Enter VM number: 5 # 虚拟机编号, [root@zzgrhel8 ~]# virsh start tedu_node05 # 启动虚机 [root@zzgrhel8 ~]# virsh console tedu_node05 # 连接虚机控制台 localhost login: root Password: 123456

将以下内容粘贴到虚拟机,进行初始化

hostnamectl set-hostname lvs2 nmcli connection modify eth0 ipv4.method manual ipv4.addresses 192.168.4.6/24 nmcli connection down eth0 nmcli connection up eth0 echo a | passwd —stdin root

退出

[root@localhost ~]# exit

按ctrl + ]退回到真机

连接测试

[root@zzgrhel8 ~]# ssh 192.168.4.6

<a name="faWOk"></a>
### 配置步骤

   1. 在2台web服务器的lo上配置vip
   1. 在2台web服务器上配置内核参数
   1. 删除lvs1上的eth0:0。因为vip将由keepalived接管
```shell
[root@lvs1 ~]# ifdown eth0:0
[root@lvs1 ~]# rm -f /etc/sysconfig/network-scripts/ifcfg-eth0:0
  1. 删除lvs1上的lvs规则。因为lvs规则将由keepalived创建

    [root@lvs1 ~]# ipvsadm -Ln   # 查看规则
    [root@lvs1 ~]# ipvsadm -D -t 192.168.4.15:80
    
  2. 配置keepalived ```shell [root@lvs1 ~]# yum install -y ipvsadm keepalived [root@lvs2 ~]# yum install -y ipvsadm keepalived

[root@lvs1 ~]# vim /etc/keepalived/keepalived.conf 12 router_id lvs1 # 为本机取一个唯一的id 13 vrrp_iptables # 自动开启iptables放行规则 … … 20 vrrp_instance VI_1 { 21 state MASTER 22 interface eth0 23 virtual_router_id 51 24 priority 100 25 advert_int 1 26 authentication { 27 auth_type PASS 28 auth_pass 1111 29 }
30 virtual_ipaddress { 31 192.168.4.15 # vip地址,与web服务器的vip一致 32 }
33 }

以下为keepalived配置lvs的规则

35 virtual_server 192.168.4.15 80 { # 声明虚拟服务器地址 36 delay_loop 6 # 健康检查延迟6秒开始 37 lb_algo wrr # 调度算法为wrr 38 lb_kind DR # 工作模式为DR 39 persistence_timeout 50 # 50秒内相同客户端调度到相同服务器 40 protocol TCP # 协议是TCP 41 42 real_server 192.168.4.100 80 { # 声明真实服务器 43 weight 1 # 权重 44 TCP_CHECK { # 通过TCP协议对真实服务器做健康检查 45 connect_timeout 3 # 连接超时时间为3秒 46 nb_get_retry 3 # 3次访问失败则认为真实服务器故障 47 delay_before_retry 3 # 两次检查时间的间隔3秒 48 } 49 } 50 real_server 192.168.4.200 80 { 51 weight 2 52 TCP_CHECK { 53 connect_timeout 3 54 nb_get_retry 3 55 delay_before_retry 3 56 } 57 } 58 }

以下部分删除

启动keepalived服务

[root@lvs1 ~]# systemctl start keepalived

验证

[root@lvs1 ~]# ip a s eth0 # 可以查看到vip [root@lvs1 ~]# ipvsadm -Ln # 出现规则

lvs2同样配置只是修改13行router_id lvs2;21行state BACKUP;24行priority 80 启动keepalived服务ipvsadm -Ln会看到规则

**小技巧:ctrl+r搜索之前输入的(history查不到)命令,esc返回命令行模式**<br />用途:反向搜索执行过的命令。(reverse-i-search)<br />找到你想要的命令后,你可以按回车执行这条命令,还可以按上下键查找该命令前后的命令,按左右键移动光标并修改这条命令<br />**客户端连接测试**
```shell
[root@client1 ~]# for i in {1..6}; do curl http://192.168.4.15/; done
apache web server2
apache web server2
apache web server2
apache web server2
apache web server2
apache web server2
# 为了效率相同的客户端在50秒内分发给同一台服务器。为了使用同一个客户端可以看到轮询效果,可以注释配置文件中相应的行后,重启keepavlied。

验证:
1. 验证真实服务器健康检查


[root@web1 ~]# systemctl stop httpd
[root@lvs1 ~]# ipvsadm -Ln   # web1在规则中消失
[root@lvs2 ~]# ipvsadm -Ln

[root@web1 ~]# systemctl start httpd
[root@lvs1 ~]# ipvsadm -Ln   # web1重新出现在规则中
[root@lvs2 ~]# ipvsadm -Ln
  1. 验证lvs的高可用性
    [root@lvs1 ~]# shutdown -h now    # 关机
    [root@lvs2 ~]# ip a s eth0     # 可以查看到vip
    # 客户端访问vip依然可用
    [root@client1 ~]# for i in {1..6}; do curl http://192.168.4.15/; done
    192.168.2.100
    apache web server2
    apache web server2
    192.168.2.100
    apache web server2
    apache web server2
    

    HAProxy负载均衡调度器

    HAProxy简介

  • 适用于负载特别大的web站点,这些站点通常又会需要会话保持或七层处理
  • 提供高可用性、负载均衡以及基于TCP和HTTP应用的代理
  • 客户端访问服务器,服务器代替客户端去访问网站,得到数据后再转发给客户端

image.png

衡量负载均衡器性能的因素

  • ·Session rate 会话率:每秒钟产生的会话数
  • ·Session concurrency 并发会话数:服务器处理会话的时间越长,并发会话数越多
  • ·Data rate 数据速率:以MB/s或Mbps衡量

    HAProxy工作模式

  • mode http:只适用于web服务

  • mode tcp:适用于各种服务
  • mode health:仅做健康检查,很少使用

    HAProxy配置实例

    image.png

    环境准备

    • client1:eth0 -> 192.168.4.10
    • HAProxy:eth0 -> 192.168.4.5
    • web1:eth0 -> 192.168.4.100
    • web2:eth0 -> 192.168.4.200 ```shell

      关闭192.168.4.6

      [root@lvs2 ~]# shutdown -h now

清理192.168.4.5

[root@lvs1 ~]# yum remove -y ipvsadm keepalived [root@lvs1 ~]# hostnamectl set-hostname haproxy1

web服务器,不需要配置vip,不需要改内核参数。但是存在对haproxy也没有影响。

<a name="xvBER"></a>
#### 配置HAProxy
配置文件可由下面两部分构成:<br />default:<br />为后续的其他部分设置缺省参数<br />缺省参数可以被后续部分重置<br />listen:<br />定义服务器集群
```shell
# 装包
[root@haproxy1 ~]# yum install -y haproxy
[root@haproxy1 ~]# vim /etc/haproxy/haproxy.cfg 
global        # 配置文件中,global是全局配置;
    log 127.0.0.1 local2   ##[err warning info debug]
    pidfile /var/run/haproxy.pid ##haproxy的pid存放路径 
    user haproxy
    group haproxy 
    daemon                    ##以后台进程的方式启动服务
defaults    # default是缺省配置,如果后续有相同的配置,default配置将会被覆盖。
      mode http                ##默认的模式mode { tcp|http|health }
option dontlognull      ##不记录健康检查的日志信息
      option httpclose        ##每次请求完毕后主动关闭http通道
    option httplog          ##日志类别http日志格式 
    option redispatch    ##当某个服务器挂掉后强制定向到其他健康服务器
    timeout client 300000 ##客户端连接超时,默认毫秒,也可以加时间单位 
    timeout server 300000 ##服务器连接超时 
    maxconn  3000          ##最大连接数
    retries  3             ##3次连接失败就认为服务不可用,也可以通过后面设置 
# 配置文件中,frontend描述haproxy怎么和用户交互;backend描述haproxy怎么和后台应用服务器交互。这两个选项,一般不单独使用,而是合并到一起,名为listen。
# 将61行之后全部删除,写入以下内容
 61 listen myweb 0.0.0.0:80   #定义集群,listen后名称任意,端口为80
 62     balance roundrobin    # 调度算法为轮询(不能用简写的rr)
 # 对web服务器做健康检查,inter设定健康检查的时间间隔(ms),rise定义成功次数,fall定义失败次数,2秒检查一次,如果连续2次检查成功,认为服务器是健康的,如果连续5次检查失败,认为服务器坏了
 63     server web1 192.168.4.100 check inter 2000 rise 2 fall 5
 64     server web2 192.168.4.200 check inter 2000 rise 2 fall 5
 65     
 66 listen stats 0.0.0.0:1080  # 定义监控地址
 67     stats refresh 30s      # 设置监控页面自动刷新时间为30秒
 68     stats uri /stats       # 定义监控地址是/stats
 69     stats auth admin:admin  # 监控页面的用户名和密码都是admin

小技巧:服务没起来排错时,可以tail -f /var/log/message | grep -i 服务名查看日志报错

测试

# 启服务
[root@haproxy1 ~]# systemctl start haproxy.service 
# 使用firefox访问监控地址 http://192.168.4.5:1080/stats

# 客户端访问测试
[root@client1 ~]# for i in {1..6}; do curl http://192.168.4.5/; done
192.168.2.100
apache web server2
192.168.2.100
apache web server2
192.168.2.100
apache web server2

客户端配置与HAProxy相同网络的IP地址,并使用火狐浏览器访问http://192.168.4.5:1080/stats测试状态监控页面是否正常。访问状态监控页的内容
image.png
备注:

  • Queue队列数据的信息(当前队列数量,最大值,队列限制数量);
  • Session rate每秒会话率(当前值,最大值,限制数量);
  • Sessions总会话量(当前值,最大值,总量,Lbtot: total number of times a server was selected选中一台服务器所用的总时间);
  • Bytes(入站、出站流量);
  • Denied(拒绝请求、拒绝回应
  • Errors(错误请求、错误连接、错误回应);
  • Warnings(重新尝试警告retry、重新连接redispatches);
  • Server(状态、最后检查的时间(多久前执行的最后一次检查)、权重、备份服务器数量、down机服务器数量、down机时长)。

    集群调度软件对比

    性能:LVS>Haproxy>Nginx
    功能:Nginx> Haproxy> LVS
    功能越多,软件越大,软件越大,运行效率越低。

    Nginx分析

    优点
    -工作在7层,可以针对http做分流策略
    -1.9版本开始支持4层代理
    -正则表达式比HAProxy强大
    -安装、配置、测试简单,通过日志可以解决多数问题
    -并发量可以达到几万次
    -Nginx还可以作为Web服务器使用
    缺点
    -7层代理仅支持http、https、mail协议,应用面小
    -监控检查仅通过端口,无法使用url检查

    LVS分析

    优点
    -负载能力强,工作在4层,对内存、CPU消耗低
    -配置性低,没有太多可配置性,减少人为错误
    -应用面广,几乎可以为所有应用提供负载均衡
    缺点
    -不支持正则表达式,不实现动静分离
    -如果网站架构庞大,LVS-DR配置比较繁琐

    HAProxy分析优点

    优点
    -支持session、cookie功能
    - 可以通过url进行健康检查
    - 效率、负载均衡速度,高于Nginx,低于LVS
    -HAProxy支持TCP,可以对MySQL进行负载均衡
    -调度算法丰富
    缺点
    - 正则弱于Nginx
    -日志依赖于syslogd

    集群与存储(Cehp存储)

    基础知识

    分布式存储

  • 分布式是值一种独特的系统架构,它由一组网络进行通信、为了完成共同的任务而协调工作的计算机节点组成

  • 分布式系统是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务
  • 其目的就是利用更多的机器,处理更多的数据

    常见的分布式文件系统

  • Lustre

  • Hadoop
  • FastDFS
  • Ceph
  • GlusterFS

    常见的存储

  • DAS(直连存储),就是接在主板上的硬盘

  • NAS(网络附加存储),例如:NFS、Samba、FTP、HTTP,优点是管理简单,缺点是单点故障
  • SAN(网络块存储),例如:Iscsi
  • 分布式云存储,例如:Ceph、Swift

    常见的存储类型

  • Block-based access(基于块存储的访问),对应的是块存储(block),例如:直接接在主板上的硬盘、Iscsi、Ceph

  • File-based access(基于文件系统的访问),对应的是文件系统存储(filesystem),例如:NFS、Samba、FTP、HTTP、Ceph
  • Object-based access(基于对象的访问),对应的是对象存储(object),例如:Ceph

    Cehp概述

  • ceph被称作面向未来的存储

  • 中文手册:
  • ceph是一个分布式存储系统,具有高拓展、高可用、高性能的特点
    • 如果需要扩容,只要向ceph集中增加服务器即可。
  • ceph可以提供对象存储、块存储、文件系统存储
    • 块存储:提供像普通硬盘一样的存储,为使用者提供“硬盘”
    • 文件系统存储:类似于NFS的共享方式,为使用者提供共享文件夹
    • 对象存储:像百度云盘一样,需要使用单独的客户端
  • ceph可以提供PB级别的存储空间(1024G*10224G)
  • 软件定义存储(Software Defined Storage)作为存储行业的一大发展趋势,已经越来越受到市场的认可
  • ceph存储数据时采用多副本的方式进存储,生产环境下,一个文件至少要存3份。ceph默认也是三副本存储。

    Cehp的构成

  • Ceph OSD 守护进程: Ceph OSD 用于存储数据。此外,Ceph OSD 利用 Ceph 节点的 CPU、内存和网络来执行数据复制、纠删代码、重新平衡、恢复、监控和报告功能。存储节点有几块硬盘用于存储,该节点就会有几个osd进程。

  • Ceph Mon监控器: Ceph Mon是集群监控组件,维护 Ceph 存储集群映射的主副本和 Ceph 存储群集的当前状态。监控器需要高度一致性,确保对Ceph 存储集群状态达成一致。维护着展示集群状态的各种图表,包括监视器图、 OSD 图、归置组( PG )图、和 CRUSH 图。
    • 一般来说,在实际运行中,Ceph Monitor的个数是 2n + 1 ( n >= 0) 个,在线上至少3个,只要正常的节点数 >= n+1,Ceph 的 Paxos 算法就能保证系统的正常运行。
  • MDSs: Ceph 元数据服务器( MDS )为 Ceph 文件系统存储元数据(如大小、属主属组、权限等)。
  • RGW:对象存储网关。主要为访问ceph的软件提供API接口。

    搭建ceph集群

    ceph官方网站:

    可以查看帮助

    搭建ceph集群操作思路:

    一、准备工作:
    IP,主机名,hosts解析,ssh密钥,时间同步,yum源,防火墙,selinux
    二、部署ceph:
    1.安装软件
    ceph-deploy(脚本) ceph-mon; ceph-osd; ceph-mds; ceph-radosgw(集群)
    2.修改配置启动服务mon
    mkdir 目录;cd 目录 ;
    ceph-deploy new node1 node2 node3 (生成配置文件)
    ceph-deploy mon create-initial (拷贝配置文件并启动mon服务)
    3.启动osd服务共享硬盘
    ceph-deploy disk zap 主机名:磁盘名 … …
    ceph-deploy osd create 主机名:磁盘 … …
    三、使用Ceph的思路:
    1.块共享

    - 服务器: rbd  create  创建一个共享镜像     
    - 客户端: 安装cpeh-common;  cp 配置文件和密钥  ; rbd  map  |  rbd  unmap
    

2.文件系统共享(文件系统由inode和block)

  - 服务器: 创建两个共享池(名称任意)
     - 使用两个共享池合并一个文件系统
     - 安装ceph-mds软件,并启动服务(ceph-deploy mds create node3)
  -  客户端: mount  -t  MON的IP:6789:/   /挂载点   -o  name=用户名,secret=密码

3.对象存储

  - 服务器启动一个radosgw即可(RGW)
  -  ceph-deploy  rgw  create  node3

四、ceph-deploy脚本用法:

   ceph-deploy  new   node1  node2  node3  #生成配置文件
   ceph-deploy  mon   create-initial       #远程所有主机启动mon服务  
   ceph-deploy  disk zap  主机名:磁盘名       #初始化磁盘  
   ceph-deploy  osd   create  主机名:磁盘名   #远程主机并启动osd服务   
   ceph-deploy  mds   create   主机名        #远程主机并启动mds服务  
   ceph-deploy  rgw  create  主机名          #远程主机并启动RGW服务

环境准备

虚拟机(主机名、ip、yum、selinux、firewalld);添加磁盘;时间同步 ;无密码登录

  • 节点准备 | 主机名 | IP地址 | | —- | —- | | node1 | 192.168.4.11/24 | | node2 | 192.168.4.12/24 | | node3 | 192.168.4.13/24 | | client | 192.168.4.10/24 |
# 创建4台虚拟机
[root@zzgrhel8 ~]# clone-vm7

1)关机,为node1-node3各添加2块20GB的硬盘

# 查看添加的硬盘,注意硬盘名字
[root@node1 ~]# lsblk 
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  30G  0 disk 
└─vda1 253:1    0  30G  0 part /
vdb    253:16   0  20G  0 disk 
vdc    253:32   0  20G  0 disk

2)配置yum源。除了系统yum源以外,还需要配置ceph的yum源

# 在真机上提供yum源。真机务必关掉防火墙
[root@zzgrhel8 ~]# yum install -y vsftpd
[root@zzgrhel8 ~]# systemctl start vsftpd
[root@zzgrhel8 ~]# mkdir /var/ftp/ceph
[root@zzgrhel8 ~]# cp /linux-soft/2/ceph10.iso /iso/
[root@zzgrhel8 ~]# vim /etc/fstab   # 追加一行如下
/iso/ceph10.iso /var/ftp/ceph   iso9660 defaults,loop   0 0
[root@zzgrhel8 ~]# mount -a
[root@zzgrhel8 ~]# df -h /var/ftp/ceph/
文件系统        容量  已用  可用 已用% 挂载点
/dev/loop3      284M  284M     0  100% /var/ftp/ceph
[root@zzgrhel8 ~]# ls /var/ftp/ceph/
EULA  MON  README                      Tools
GPL   OSD  RPM-GPG-KEY-redhat-release  TRANS.TBL

# 在node1-3节点上配置yum
[root@node1 ~]# vim /etc/yum.repos.d/ceph.repo
baseurl=ftp://192.168.4.254/ceph/OSD
enabled=1
gpgcheck=0
[mon]
name=ceph mon
baseurl=ftp://192.168.4.254/ceph/MON
enabled=1
gpgcheck=0
[tools]
name=ceph tools
baseurl=ftp://192.168.4.254/ceph/Tools
enabled=1
gpgcheck=0

[root@node1 ~]# yum repolist
[root@node1 ~]# scp /etc/yum.repos.d/ceph.repo 192.168.4.12:/etc/yum.repos.d/   #  通过scp将yum配置文件拷贝给node2和node3

3)各节点务必关闭selinux和防火墙

4)配置无密码连接(包括自己远程自己也不需要密码),在node1操作

  • ceph为我们提供了一个ceph-deploy(部署)工具,可以在某一节点上统一操作全部节点
    # 将Node1作为部署节点,将来的操作都在node1上进行。这样,需要node1能够免密操作其他主机
    [root@node1 ~]# ssh-keygen    # 生成密钥对
    [root@node1 ~]# for i in {10..13}
    > do
    > ssh-copy-id 192.168.4.$i
    > done
    

    5)修改/etc/hosts并同步到所有主机。

    注意:/etc/hosts解析的域名要与本机主机名一致!!!!
    [root@node1 ~]# vim /etc/hosts   # 增加4行
    ... ...
    192.168.4.10    client1
    192.168.4.11    node1
    192.168.4.12    node2
    192.168.4.13    node3
    [root@node1 ~]# for i in 10 12 13
    > do
    > scp /etc/hosts 192.168.4.$i:/etc/
    > done
    

    6)给所有节点安装ceph相关软件包。

    [root@node1 ceph-cluster]# for i in node1 node2 node3
    do    
    ssh  $i "yum -y install ceph-mon ceph-osd ceph-mds ceph-radosgw"
    done
    
    小技巧:ssh 远程主机名 操作命令 可以远程主机进行一些命令操作

    7)Client1主机配置NTP服务器。

    [root@client1 ~]# yum install -y chrony
    [root@client1 ~]# vim /etc/chrony.conf 
    allow 192.168.4.0/24    # 约26行,授权192.168.4.0/24可以时钟同步
    local stratum 10   # 约29行,即使没有从一个源同步时钟,也为其他主机提供时间
    [root@client1 ~]# systemctl restart chronyd
    

    8)node1,node2,node3修改NTP客户端配置。

    ```shell [root@node1 ~]# for i in node{1..3}

    do ssh $i yum install -y chrony done [root@node1 ~]# vim /etc/chrony.conf # 只改第7行 7 server 192.168.4.10 iburst # 替换gateway [root@node1 ~]# for i in node{2..3} do scp /etc/chrony.conf $i:/etc/ done [root@node1 ~]# for i in node{1..3} do ssh $i systemctl restart chronyd done

验证时间是否同步 client1前面有^*表示同步成功

[root@node1 ~]# chronyc sources -v … … ^* client1 10 6 17 40 -4385ns[-1241us] +/- 162us

<a name="KbKZ9"></a>
### 部署ceph集群

1. 安装部署工具ceph-deploy
1. 创建ceph集群
1. 创建OSD存储空间
1. 查看ceph状态,验证ceph -s
<a name="zoD2V"></a>
#### 1)安装部署软件ceph-deploy,创建工作目录
```shell
# 在node1上安装ceph-deploy部署工具
[root@node1 ~]#  yum -y install ceph-deploy
[root@node1 ~]#  ceph-deploy  --help # 查看使用帮助
[root@node1 ~]#  ceph-deploy mon --help  # 查看mon子命令的帮助
# 创建ceph-deploy工作目录
[root@node1 ~]# mkdir ceph-cluster
[root@node1 ~]# cd ceph-cluster

2)创建配置Ceph集群

# 创建一个新的集群。
[root@node1 ceph-cluster]# ceph-deploy new node{1..3}
[root@node1 ceph-cluster]# ls
ceph.conf  ceph-deploy-ceph.log  ceph.mon.keyring
[root@node1 ceph-cluster]# tree .   #tree是一个命令,需安装软件tree
.
├── ceph.conf               # 集群配置文件
├── ceph-deploy-ceph.log    # 日志文件
└── ceph.mon.keyring        # 共享密钥
# 开启COW分层快照功能。COW:Copy On Write写时复制(差分盘)
[root@node1 ceph-cluster]# vim ceph.conf   # 尾部追加一行如下
rbd_default_features = 1
**    初始化monitor**
[root@node1 ceph-cluster]# ceph-deploy mon create-initial
[root@node1 ceph-cluster]# systemctl status ceph-mon*
● ceph-mon@node1.service .. ..
[root@node2 ~]# systemctl status ceph*
● ceph-mon@node2.service ... ...
[root@node3 ~]# systemctl status ceph*
● ceph-mon@node3.service ... ...
#备注:管理员可以自己启动(start)、重启(restart)、关闭(stop),查看状态(status).
#提醒:这些服务在30分钟只能启动3次,超过就报错.
#StartLimitInterval=30min
#StartLimitBurst=3
#在这个文件中有定义/usr/lib/systemd/system/ceph-mon@.service
#如果修改该文件,需要执行命令# systemctl  daemon-reload重新加载配置

# 查看集群状态
[root@node1 ceph-cluster]# ceph -s
     health HEALTH_ERR   # 因为还没有硬盘,所以状态是HEALTH_ERR

3)创建OSD

a.初始化清空磁盘数据(仅node1操作即可)。

  • 初始化磁盘,将所有磁盘分区格式设置为GPT格式(根据实际情况填写磁盘名称)

    [root@node1 ceph-cluster]# ceph-deploy disk --help
    # 初始化各主机的硬盘。vmware应该是sdb和sdc
    [root@node1 ceph-cluster]# ceph-deploy disk zap node1:vdb node1:vdc 
    [root@node1 ceph-cluster]# ceph-deploy disk zap node2:vdb node2:vdc 
    [root@node1 ceph-cluster]# ceph-deploy disk zap node3:vdb node3:vdc
    

    b.创建OSD存储空间(仅node1操作即可)

  • ceph会硬盘分为两个分区,第一个分区大小为5GB,用于保存ceph的内部资源;另一个分区是剩余全部空间 ```shell [root@node1 ceph-cluster]# ceph-deploy osd —help [root@node1 ceph-cluster]# ceph-deploy osd create node1:vd{b,c} [root@node1 ceph-cluster]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 30G 0 disk └─vda1 253:1 0 30G 0 part / vdb 253:16 0 20G 0 disk ├─vdb1 253:17 0 15G 0 part /var/lib/ceph/osd/ceph-0 └─vdb2 253:18 0 5G 0 part vdc 253:32 0 20G 0 disk ├─vdc1 253:33 0 15G 0 part /var/lib/ceph/osd/ceph-1 └─vdc2 253:34 0 5G 0 part

    将会出现2个osd进程,因为有两块硬盘用于ceph

    [root@node1 ceph-cluster]# systemctl status ceph-osd*

继续初始化其他节点的OSD

[root@node1 ceph-cluster]# ceph-deploy osd create node2:vd{b,c} [root@node1 ceph-cluster]# ceph-deploy osd create node3:vd{b,c}

c.验证测试
```shell
# 查看集群状态
[root@node1 ceph-cluster]# ceph -s
     health HEALTH_OK     # 状态是HEALTH_OK表示一切正常
[root@node1 ~]#  ceph   osd   tree

常见错误(非必须操作)
如果查看状态包含如下信息:

[root@node1 ceph-cluster]# ceph -s
        health: HEALTH_WARN            clock skew detected on  node2, node3…

clock skew表示时间不同步,解决办法:请先将所有主机的时间都使用NTP时间同步!!!
Ceph要求所有主机时差不能超过0.05s,否则就会提示WARN。
如果状态还是失败,可以尝试执行如下命令,重启所有ceph服务:

[root@node1 ~]#  systemctl restart ceph.target

4)删除某个OSD

ceph osd tree
ceph osd out osd.4
ceph osd tree
ceph -s
ceph osd crush remove osd.4
ceph auth del osd.4
ceph -s
ceph osd rm osd.4
最后要找到对应的主机,umount把osd.4对应的磁盘卸载

创建Ceph块存储

单机块存储:光盘、磁盘;分布式块存储:Ceph、Cinder

  1. 创建块存储镜像
  2. 客户端映射镜像
  3. 删除镜像

块设备存取数据时,可以一次存取很多。字符设备只能是字符流

[root@node1 ceph-cluster]# ll /dev/vda
brw-rw---- 1 root disk 253, 0 11月  4 10:15 /dev/vda
# b表示block,块设备
[root@node1 ceph-cluster]# ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 11月  4 10:54 /dev/tty
# c表示character,字符设备
  • 块存储,就是可以提供像硬盘一样的设备。使用块存储的节点,第一次连接块设备,需要对块设备进行分区、格式化,然后挂载使用。
  • ceph提供存储时,需要使用存储池。为了给客户端提供存储资源,需要创建名为存储池的容器。
  • 存储池类似于逻辑卷管理中的卷组。卷组中包含很多硬盘和分区;存储池中包含各节点上的硬盘。

    1)创建镜像

    ```shell

    查看结果显示,共享池的名称为rbd,这个共享池的编号为0,英语词汇:pool(池塘、水塘),rbd(RADOS block device)RADOS块设备

    [root@node1 ~]# ceph osd lspools 0 rbd,

    查看存储池大小

    [root@node1 ceph-cluster]# ceph df GLOBAL: SIZE AVAIL RAW USED %RAW USED 92093M 91889M 203M 0.22 POOLS: NAME ID USED %USED MAX AVAIL OBJECTS rbd 0 16 0 30629M 3

在默认存储池中,创建一个大小为10G的镜像,提供给客户端使用

[root@node1 ceph-cluster]# rbd create demo-image —size 10G

查看默认存储池中的镜像

[root@node1 ceph-cluster]# rbd list demo-image

查看demo-image的详细信息

[root@node1 ceph-cluster]# rbd info demo-image rbd image ‘demo-image’: size 10240 MB in 2560 objects order 22 (4096 kB objects) block_name_prefix: rbd_data.1035238e1f29 format: 2 features: layering flags:

rbd image有4个 features,layering, exclusive-lock, object-map, fast-diff, deep-flatten

- layering: 支持分层
- striping: 支持条带化 v2
- exclusive-lock: 支持独占锁
- object-map: 支持对象映射(依赖 exclusive-lock )
- fast-diff: 快速计算差异(依赖 object-map )
- deep-flatten: 支持快照扁平化操作
- journaling: 支持记录 IO 操作(依赖独占锁)

因为目前内核版本 3.10仅支持layering,修改默认配置<br />每个ceph node的**/etc/ceph/ceph.conf** 添加一行<br />**rbd_default_features = 1**<br />这样之后创建的image 只有这一个feature

format 1 - 新建 rbd 映像时使用最初的格式。此格式兼容所有版本的 librbd 和内核模块,但是不支持较新的功能,像克隆。<br />format 2 - 使用第二版 rbd 格式, librbd 和 3.11 版以上内核模块才支持(除非是分拆的模块)。此格式增加了克隆支持,使得扩展更容易,还允许以后增加新功能

**rbd查看命令**

   - **rbd list   # 列出镜像**
   - **rbd info  镜像名称 # 查看镜像的信息**
   - **rbd snap ls  镜像名称  # 查看镜像的快照**
   - **rbd showmapped   # 查看镜像的映射**
<a name="nIiLc"></a>
#### 2)动态镜像调整(rbd resize/rm)
```shell
# 扩容
[root@node1 ceph-cluster]# rbd resize --size 15G demo-image
Resizing image: 100% complete...done.
[root@node1 ceph-cluster]# rbd info demo-image
rbd image 'demo-image':
    size 15360 MB in 3840 objects

# 缩减
[root@node1 ceph-cluster]# rbd resize --size 7G demo-image --allow-shrink
[root@node1 ceph-cluster]# rbd info demo-image
rbd image 'demo-image':
    size 7168 MB in 1792 objects

# 删除
[root@node1 ceph-cluster]# rbd rm demo-image

3)客户端使用块设备(通过KRBD访问)

  • 怎么用?装软件
  • ceph集群在哪?通过配置文件说明集群地址
  • 权限。keyring文件 ```shell

    安装ceph客户端软件

    [root@client1 ~]# yum install -y ceph-common

将配置文件(否则不知道集群在哪)和密钥(否则无连接权限)keyring文件拷贝给客户端

[root@node1 ceph-cluster]# scp /etc/ceph/ceph.conf 192.168.4.10:/etc/ceph/ [root@node1 ceph-cluster]# scp /etc/ceph/ceph.client.admin.keyring 192.168.4.10:/etc/ceph/

客户端查看镜像

[root@client1 ~]# rbd list demo-image

将ceph提供的镜像映射到本地

[root@client1 ~]# rbd map demo-image /dev/rbd0 [root@client1 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 30G 0 disk └─vda1 253:1 0 30G 0 part / rbd0 252:0 0 7G 0 disk # 多了一块7GB的硬盘 [root@client1 ~]# ls /dev/rbd0 /dev/rbd0

查看磁盘名和共享镜像名称的对应关系

[root@client1 ~]# rbd showmapped id pool image snap device
0 rbd demo-image - /dev/rbd0

客户端格式化(第一次用操作)、挂载分区
```shell
[root@client1 ~]# mkfs.xfs /dev/rbd0
[root@client1 ~]# mount /dev/rbd0 /mnt/
[root@client1 ~]# df -h /mnt/
文件系统        容量  已用  可用 已用% 挂载点
/dev/rbd0       7.0G   33M  7.0G    1% /mnt

备注:客户端可能遇到无法映射的问题,原因是rbd镜像的一些特性,OS kernel并不支持,所以映射失败

  • rbd image有多个 features,因为目前内核版本 3.10仅支持layering,把其他的删除就行了

rbd feature disable ceph-client1-rbd1 exclusive-lock object-map fast-diff deep-flatten
解决办法:

4)停用设备

# 查看块设备映射信息
[root@client1 ~]# rbd showmapped
id pool image      snap device    
0  rbd  demo-image -    /dev/rbd0 
[root@client1 ~]# lsblk 
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  30G  0 disk 
└─vda1 253:1    0  30G  0 part /
rbd0   252:0    0   7G  0 disk /mnt

# 停用设备
[root@client1 ~]# umount /mnt/
[root@client1 ~]# lsblk 
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  30G  0 disk 
└─vda1 253:1    0  30G  0 part /
rbd0   252:0    0   7G  0 disk    # 已经卸载

[root@client1 ~]# rbd unmap /dev/rbd0
[root@client1 ~]# lsblk    # /dev/rbd0消失
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  30G  0 disk 
└─vda1 253:1    0  30G  0 part /

部署ceph集群常见错误及解决办法

常见错误提示一:

  • 如果提示错误信息:[ceph_deploy][ERROR ]RuntimeError: bootstrap-osd keyring

not found; run ‘gatherkeys’

  • 解决方案: 重新配置ceph的密钥文件

[root@node1 ceph-cluster]# ceph-deploy gatherkeys node1 node2 node3

常见错误提示二:

  • 检查集群状态如遇以下报错表示时间同步的问题需要认真检查NTP时间同步服务,如配置正确,可以重启chronyd服务

[root@node1 ceph-cluster]# ceph -s
health HEALTH_WARN #集群状态为警告
clock skew detected on mon.node2,mon. node3
Monitor clock skew detected

clock skew表示时间不同步,解决办法:
请先将所有主机的时间都使用NTP时间同步!!!
Ceph要求所有主机时差不能超过0.05s,否则就会提示WARN。

  • 解决方案:三台node重启chronyd

[root@node1 ~]# systemctl restart chronyd
[root@node2 ~]# systemctl restart chronyd
[root@node3 ~]# systemctl restart chronyd
[root@node2 ~]# chronyc sources -v
稍等片刻,时间同步需要时间
[root@node1 ~]# ceph -s
health HEALTH_OK #集群状态为OK

常见错误提示三:

  • [ceph_deploy.config][ERROR] RuntimeError:config file /etc/ceph/ceph.conf exists whit different content; use –overwrite-conf to overwrite
  • 修改了ceph用户里的ceph.conf文件内容,但是没有把这个文件里的最新消息发送给其他节点,所有要推送消息

  • 解决方案:[root@node1 ceph-cluster]# ceph-deploy –overwrite-conf mon create-initial

    ceph块存储应用案例(快照)

  • 快照可以保存某一时间点时的状态数据

  • 希望回到以前的一个状态,可以恢复快照

    1)创建/删除镜像快照(rbd snap create/remove)

    ```shell

    查看demo-image的快照

    [root@node1 ~]# rbd snap ls demo-image

    为demo-image创建名为demo-snap1的快照。由于快照采用COW技术,所以快照创建非常快。

    [root@node1 ~]# rbd snap create demo-image —snap demo-snap1 [root@node1 ~]# rbd snap ls demo-image SNAPID NAME SIZE 6 demo-snap1 7168 MB

删除快照

[root@node1 ~]# rbd snap remove demo-image —snap demo-snap1

删除镜像

[root@node1 ~]# rbd rm demo-image

<a name="LSTIV"></a>
#### 2)使用镜像、快照综合示例
<a name="dv4Gs"></a>
##### a. 在rbd存储池中创建10GB的镜像,名为img1
```shell
[root@node1 ~]# rbd --help   # 查看子命令
[root@node1 ~]# rbd help create  # 查看子命令create的帮助
[root@node1 ~]# rbd create img1 --size 10G
[root@node1 ~]# rbd list
img1
[root@node1 ~]# rbd info img1
rbd image 'img1':
    size 10240 MB in 2560 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.1061238e1f29
    format: 2
    features: layering
    flags:

b. 在客户端使用镜像img1,将其挂载到/mnt
[root@client1 ~]# rbd list
img1
[root@client1 ~]# rbd map img1
/dev/rbd0
[root@client1 ~]# mkfs.xfs /dev/rbd0
[root@client1 ~]# mount /dev/rbd0 /mnt/
[root@client1 ~]# rbd showmapped
id pool image snap device    
0  rbd  img1  -    /dev/rbd0 
[root@client1 ~]# df -h /mnt/
文件系统        容量  已用  可用 已用% 挂载点
/dev/rbd0        10G   33M   10G    1% /mnt

c. 向/mnt中写入数据
[root@client1 ~]# cp /etc/hosts /mnt/
[root@client1 ~]# cp /etc/passwd /mnt/
[root@client1 ~]# ls /mnt/
hosts  passwd

d. 创建img1的快照,名为img1-sn1
[root@node1 ~]# rbd snap create img1 --snap img1-sn1
[root@node1 ~]# rbd snap ls img1
SNAPID NAME         SIZE 
     8 img1-sn1 10240 MB

e. 删除/mnt/中的数据
[root@client1 ~]# rm -f /mnt/*

f. 通过快照还原数据
[root@client1 ~]# umount /mnt/
[root@client1 ~]# rbd unmap /dev/rbd0
[root@client1 ~]# rbd help snap rollback   # 查看子命令帮助
# 回滚img1到快照img1-sn1
[root@client1 ~]# rbd snap rollback img1 --snap img1-sn1
# 重新挂载
[root@client1 ~]# rbd map img1
/dev/rbd0
[root@client1 ~]# mount /dev/rbd0 /mnt/
[root@client1 ~]# ls /mnt/   # 数据还原完成
hosts  passwd

3)保护/取消保护快照(rbd snap protect/unprotect)

[root@node1 ~]# rbd help snap protect
# 保护镜像img1的快照img1-sn1
[root@node1 ~]# rbd snap protect img1 --snap img1-sn1
[root@node1 ~]# rbd snap rm img1 --snap img1-sn1   # 删除被保护的快照,会失败

4)克隆快照(rbd clone)

  • 不能将一个镜像同时挂载到多个节点,如果这样操作,将会损坏数据
  • 如果希望不同的节点,拥有完全相同的数据盘,可以使用克隆技术
  • 克隆是基于快照的,不能直接对镜像克隆
  • 快照必须是受保护的快照,才能克隆
  • 克隆流程
    • (镜像)—创建—>(快照)—保护—>(受保护的快照)—克隆—>(克隆的镜像)
    • rbd create —->rbd protect —->rbd clone ```shell

      1. 创建名为img2的镜像,大小10GB

      [root@node1 ~]# rbd create img2 —size 10G

2. 向镜像中写入数据

[root@node1 ~]# rbd map img2 /dev/rbd0 [root@node1 ~]# mkfs.xfs /dev/rbd0 [root@node1 ~]# mount /dev/rbd0 /mnt/ [root@node1 ~]# for i in {1..20}

do echo “Hello World $i” > /mnt/file$i.txt done [root@node1 ~]# ls /mnt/ file10.txt file15.txt file1.txt file5.txt file11.txt file16.txt file20.txt file6.txt file12.txt file17.txt file2.txt file7.txt file13.txt file18.txt file3.txt file8.txt file14.txt file19.txt file4.txt file9.txt

3. 卸载镜像

[root@node1 ~]# umount /mnt/ [root@node1 ~]# rbd unmap /dev/rbd0

4. 为img2创建名为img2-sn1快照

[root@node1 ~]# rbd snap create img2 —snap img2-sn1

5. 保护img2-sn1快照

[root@node1 ~]# rbd snap protect img2 —snap img2-sn1

6. 通过受保护的快照img2-sn1创建克隆镜像

[root@node1 ~]# rbd clone img2 —snap img2-sn1 img2-sn1-1 —image-feature layering [root@node1 ~]# rbd clone img2 —snap img2-sn1 img2-sn1-2 —image-feature layering

7. 查看创建出来的、克隆的镜像

[root@node1 ~]# rbd list img1 img2 img2-sn1-1 img2-sn1-2

8. 不同的客户端挂载不同的克隆镜像,看到的是相同的数据

[root@client1 ~]# rbd map img2-sn1-1 /dev/rbd1 [root@client1 ~]# mkdir /data [root@client1 ~]# mount /dev/rbd1 /data [root@client1 ~]# ls /data file10.txt file15.txt file1.txt file5.txt file11.txt file16.txt file20.txt file6.txt file12.txt file17.txt file2.txt file7.txt file13.txt file18.txt file3.txt file8.txt file14.txt file19.txt file4.txt file9.txt

**查看克隆镜像与父镜像快照的关系**
```shell
# 查看父镜像快照信息
[root@node1 ~]# rbd info img2 --snap img2-sn1
rbd image 'img2':
    size 10240 MB in 2560 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.107a238e1f29
    format: 2
    features: layering
    flags: 
    protected: True    # 受保护

# 查看克隆的快照
[root@node1 ~]# rbd info img2-sn1-2
rbd image 'img2-sn1-2':
    size 10240 MB in 2560 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.10842eb141f2
    format: 2
    features: layering
    flags: 
    parent: rbd/img2@img2-sn1  # 父对象是rbd池中img2镜像的img2-sn1快照
    overlap: 10240 MB

合并父子镜像

  • 克隆镜像的很多数据都来自于快照链(相当于文件的软链接的概念),不能独立使用。
  • 如果父镜像删除了,子镜像也无法使用。
  • 将父镜像内容合并到子镜像中,子镜像就可以独立使用了。
    # 把img2的数据合并到子镜像img2-sn1-2中
    [root@node1 ~]# rbd flatten img2-sn1-2
    # 查看状态,它就没有父镜像了
    [root@node1 ~]# rbd info img2-sn1-2
    rbd image 'img2-sn1-2':
      size 10240 MB in 2560 objects
      order 22 (4096 kB objects)
      block_name_prefix: rbd_data.10842eb141f2
      format: 2
      features: layering
      flags:
    
    删除父镜像 ```shell

    1. 删除镜像img2-sn1-1

    [root@node1 ~]# rbd rm img2-sn1-1

    2. 取消img2-sn1的保护

    [root@node1 ~]# rbd snap unprotect img2 —snap img2-sn1

    3. 删除img2-sn1快照

    [root@node1 ~]# rbd snap rm img2 —snap img2-sn1

    4. 删除img2

    [root@node1 ~]# rbd rm img2

因为img2-sn1-2已经是独立的镜像了,所以它还可以使用

[root@client1 ~]# rbd list img1 img2-sn1-2 [root@client1 ~]# rbd map img2-sn1-2 /dev/rbd1 [root@client1 ~]# mount /dev/rbd1 /data/ [root@client1 ~]# ls /data/ file10.txt file15.txt file1.txt file5.txt file11.txt file16.txt file20.txt file6.txt file12.txt file17.txt file2.txt file7.txt file13.txt file18.txt file3.txt file8.txt file14.txt file19.txt file4.txt file9.txt

<a name="bhrIN"></a>
### ceph文件系统(cephFS)
<a name="BQhQQ"></a>
#### 基础知识

- 文件系统:相当于是组织数据存储的方式。
- 格式化时,就是在为存储创建文件系统。
- 分布式文件系统(Distributed File System):是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连
- CephFS使用Ceph集群提供与POSIX兼容的文件系统
- 允许Linux直接将Ceph存储mount到本地
- 元数据(Metadata)
   - 任何文件系统中的数据分为数据和元数据
   - 数据是指普通文件中的实际数据
   - 而元数据指用来描述一个文件的特征的系统数据
   - 比如:访问权限、文件拥有者以及文件数据块的分布信息(inode...)等
- 要想实现文件系统的数据存储方式,需要有MDS(元数据服务器)组件
<a name="FeXmb"></a>
#### 部署ceph文件系统

   1. 部署MDSs节点
   1. 创建Ceph文件系统
   1. 客户端挂载文件系统
<a name="sCPTT"></a>
##### a.安装部署元数据服务器(MDS)
```shell
# 在node3节点上安装MDS
[root@node1 ~]# ssh node3
[root@node3 ~]# yum install -y ceph-mds

# 的node1配置MDS
[root@node1 ~]# cd ceph-cluster/
[root@node1 ceph-cluster]# ceph-deploy mds create node3

b.使用MDS

  • 新建存储池
    • 归置组PG:存储池包含PG。PG是一个容器,用于存储数据。PG是一个逻辑概念,没有对应的物质形态,是为了方便管理OSD而设计的概念。
      • 为了方便理解,可以把PG想象成为是目录,可以创建32个目录来存放OSD,也可以创建64个目录来存放OSD。
    • 为了管理方便,将数量众多的数据放到不同的PG中管理,而不是直接把所有的数据扁平化存放。
    • 通常一个存储池中创建100个PG。
  • ceph文件系统中,数据和元数据是分开存储的 ```shell

    1. 新建一个名为data1的存储池,目的是存储数据,有100个PG

    [root@node1 ceph-cluster]# ceph osd pool create data1 100

2. 新建一个名为matadata1的存储池,目的是存储元数据

[root@node1 ceph-cluster]# ceph osd pool create metadata1 100

3. 创建名为myfs1的cephfs,数据保存到data1中,元数据保存到matadata1中

[root@node1 ceph-cluster]# ceph fs new myfs1 metadata1 data1

**查看/删除存储池**
```shell
# 查看存储池
[root@node1 ceph-cluster]# ceph osd lspools 
0 rbd,1 data1,2 metadata1,
[root@node1 ceph-cluster]# ceph df
GLOBAL:
    SIZE       AVAIL      RAW USED     %RAW USED 
    92093M     91574M         519M          0.56 
POOLS:
    NAME          ID     USED       %USED     MAX AVAIL     OBJECTS 
    rbd           0      86469k      0.28        30488M        2606 
    data1         1           0         0        30488M           0 
    metadata1     2        2068         0        30488M          20
# 删除存储池 
[root@node1 ceph-cluster]#  ceph osd pool rm matadata1 matadata1 --yes-i-really-really-mean-it

c.客户端挂载文件系统

# 挂载文件系统需要密码。查看密码
[root@client1 ~]# cat /etc/ceph/ceph.client.admin.keyring 
[client.admin]
    key = AQBmhINh1IZjHBAAvgk8m/FhyLiH4DCCrnrdPQ==

# -t 指定文件系统类型。-o是选项,提供用户名和密码
# cephfs的端口号默认是6789
[root@client1 ~]# mount -t ceph -o name=admin,secret=AQBmhINh1IZjHBAAvgk8m/FhyLiH4DCCrnrdPQ==   192.168.4.13:6789:/ /media
[root@client1 ~]# df -h /media/
文件系统             容量  已用  可用 已用% 挂载点
192.168.4.13:6789:/   90G  520M   90G    1% /media

ceph对象存储

基础知识

  • 对象存储
    • 也就是键值存储,通其接口指令,也就是简单的GET、PUT、DEL和其他扩展,向存储服务上传下载数据
    • 对象存储中所有数据都被认为是一个对象,所以,任何数据都可以存入对象存储服务器,如图片、视频、音频等
  • RGW全称是Rados Gateway
  • RGW是Ceph对象存储网关,用于向客户端应用呈现存储界面,提供RESTful API访问接口

    部署ceph对象存储

    1. 安装部署Rados Gateway
    2. 启动RGW服务
    3. 设置RGW的前端服务与端口
    4. 客户端测试
      [root@node1 ceph-cluster]# ssh node3
      [root@node3 ~]# yum install -y ceph-radosgw
      [root@node1 ~]# cd ceph-cluster/
      [root@node1 ceph-cluster]# ceph-deploy rgw create node3
      
      登陆node3验证服务是否启动
      [root@node3 ~]# ps aux |grep radosgw
      ceph      4109  0.2  1.4 2289196 14972 ?       Ssl  22:53   0:00 /usr/bin/radosgw -f --cluster ceph --name client.rgw.node3 --setuser ceph --setgroup ceph
      [root@node3 ~]# systemctl  status ceph-radosgw@\*
      
      修改服务端口:
      登陆node3,RGW默认服务端口为7480,修改为8000或80更方便客户端记忆和使用
      [root@node3 ~]#  vim  /etc/ceph/ceph.conf
      [client.rgw.node3]
      host = node3
      rgw_frontends = "civetweb port=8000"
      #node3为主机名
      #civetweb是RGW内置的一个web服务
      [root@node3 ~]# systemctl  restart ceph-radosgw@\*
      
      客户端测试(扩展选做实验)
      1)curl测试
      [root@client ~]# curl 192.168.4.13:8000
      2)使用第三方软件访问
      登陆node3(RGW)创建账户
      [root@node3 ~]#  radosgw-admin user create \
      --uid="testuser" --display-name="First User"
      … …
      "keys": [  
        {       
            "user": "testuser",       
            "access_key": "5E42OEGB1M95Y49IBG7B",      
            "secret_key": "i8YtM8cs7QDCK3rTRopb0TTPBFJVXdEryRbeLGK6"    
        }  
        ],
      [root@node5 ~]# radosgw-admin user info --uid=testuser
      //testuser为用户名,access_key和secret_key是账户密钥
      
      3)客户端安装软件(软件需要自己上网搜索下载)
      [root@client ~]# yum install s3cmd-2.0.1-1.el7.noarch.rpm
      修改软件配置(注意,除了下面设置的内容,其他提示都默认回车) ```shell [root@client ~]# s3cmd —configure Access Key: 5E42OEGB1M95Y49IBG7BSecret Key: i8YtM8cs7QDCK3rTRopb0TTPBFJVXdEryRbeLGK6 S3 Endpoint [s3.amazonaws.com]: 192.168.4.13:8000

Use HTTPS protocol [Yes]: No Test access with supplied credentials? [Y/n] n Save settings? [y/N] y

注意,其他提示都默认回车

4)创建存储数据的bucket(类似于存储数据的目录)
```shell
[root@client ~]# s3cmd ls
[root@client ~]# s3cmd mb s3://my_bucket
Bucket 's3://my_bucket/' created
[root@client ~]# s3cmd ls
2018-05-09 08:14 s3://my_bucket

[root@client ~]# s3cmd put /var/log/messages s3://my_bucket/log/

[root@client ~]# s3cmd ls s3://my_bucket
DIR s3://my_bucket/log/
[root@client ~]# s3cmd ls s3://my_bucket/log/
2018-05-09 08:19 309034 s3://my_bucket/log/messages

5)测试下载功能
[root@client ~]# s3cmd get s3://my_bucket/log/messages /tmp/
6)测试删除功能
[root@client ~]# s3cmd del s3://my_bucket/log/messages