实现环境:
server1
server2
server3

1、haproxy 实现负载均衡

[root@server1 ~]# yum install haproxy -y  安装软件
[root@server2 ~]# systemctl start httpd   server2上启动apache
[root@server3 ~]# systemctl start httpd   server3上启动apache
[root@server1 ~]# cd /etc/haproxy/
[root@server1 haproxy]# ls
haproxy.cfg
[root@server1 haproxy]# vim haproxy.cfg  编辑配置文件

haproxy 不存在页面 haproxy check_运维

backend app
    balance     roundrobin   roundrobin表示算法
    server  app1 172.25.50.2:80 check   app1表示后端的命名 ,check表示健康检查
    server  app2 172.25.50.3:80 check   app2表示后端的命名 ,  check表示健康检查
[root@server1 haproxy]# systemctl start haproxy.service   启动服务

查看端口

haproxy 不存在页面 haproxy check_负载均衡_02

[root@foundation50 ~]# curl 172.25.50.1  访问调度器,已经实现负载均衡
server2
[root@foundation50 ~]# curl 172.25.50.1
server3
[root@foundation50 ~]# curl 172.25.50.1
server2

haproxy不需要配置后端,对后端自带健康检查

[root@server2 ~]# systemctl stop httpd.service  当停掉后端server2 apache服务
[root@foundation50 ~]# curl 172.25.50.1  再次调度,只有server3了,有健康检查
server3
[root@foundation50 ~]# curl 172.25.50.1
server3
[root@server2 ~]# systemctl start httpd   serve2再次启动apache
[root@foundation50 ~]# curl 172.25.50.1   server2又立即恢复了
server2
[root@foundation50 ~]# curl 172.25.50.1
server3

2、 在haproxy配置文件里加上监控参数和认证参数

[root@server1 haproxy]# vim haproxy.cfg  编辑配置文件

haproxy 不存在页面 haproxy check_运维_03

[root@server1 haproxy]# systemctl restart haproxy.service  重新加载服务

访问 172.25.50.1/status

haproxy 不存在页面 haproxy check_运维_04


给监控页面加一个认证:

haproxy 不存在页面 haproxy check_运维_05

[root@server1 haproxy]# systemctl restart haproxy.service 重新加载

再次访问172.25.50.1需要输入用户和密码

haproxy 不存在页面 haproxy check_haproxy 不存在页面_06


测试:

[root@server2 ~]# systemctl stop httpd.service  停掉server2上httpd服务

监控页面颜色就会有变化

haproxy 不存在页面 haproxy check_负载均衡_07

3、haproxy 日志独立存放

[root@server1 haproxy]# cat haproxy.cfg 查看配置文件

haproxy 不存在页面 haproxy check_vim_08

[root@server1 haproxy]# vim /etc/rsyslog.conf

haproxy 不存在页面 haproxy check_haproxy 不存在页面_09


激活udp端口

haproxy 不存在页面 haproxy check_vim_10

haproxy 不存在页面 haproxy check_vim_11

[root@server1 haproxy]# vim /etc/sysconfig/rsyslog  在rsyslog里加上-r

haproxy 不存在页面 haproxy check_vim_12

[root@server1 haproxy]# systemctl restart rsyslog  重启
[root@foundation50 ~]# curl 172.25.50.1   访问
server2
[root@foundation50 ~]# curl 172.25.50.1
server3
[root@foundation50 ~]# curl 172.25.50.1
server2

查看是否记录日志

haproxy 不存在页面 haproxy check_负载均衡_13


haproxy.log 日志已经存在了监控和认证参数可以放到端口下面

haproxy 不存在页面 haproxy check_运维_14


重启服务,查看端口

haproxy 不存在页面 haproxy check_运维_15


访问就需要用8000端口

haproxy 不存在页面 haproxy check_php_16

4、设置应用最大访问量

[root@server1 haproxy]# vim haproxy.cfg  最大访问量设置为6535

haproxy 不存在页面 haproxy check_vim_17

[root@server1

haproxy]# systemctl restart haproxy.service    重启服务

访问量规则: kener(内核) > system:1024 > app:65535 ,但是操作系统system才1024,内核足以满足大于app65535的需求

所以需要修改操作系统

haproxy 不存在页面 haproxy check_负载均衡_18


设置为系统允许打开文件数65535

5、haproxy算法

有多种算法自己去了解,不一一列举

haproxy 不存在页面 haproxy check_php_19

[root@server1 haproxy]# vim haproxy.cfg  编辑配置文件,更改算法

haproxy 不存在页面 haproxy check_haproxy 不存在页面_20

[root@server1 haproxy]# systemctl reload haproxy.service   重载服务
source:同一个客户端访问,他不会负载,他会调度到同一个后端
[root@foundation50 ~]# curl 172.25.50.1  访问
server2
[root@foundation50 ~]# curl 172.25.50.1
server2
[root@foundation50 ~]# curl 172.25.50.1
server2

6、haproxy访问控制

[root@server1 haproxy]# vim haproxy.cfg 编辑配置文件

haproxy 不存在页面 haproxy check_负载均衡_21

[root@server1 haproxy]# systemctl reload haproxy.service     重载服务

[root@server3 mnt]# cd /var/www/html/  
[root@server3 html]# ls
index.html
[root@server3 html]# mkdir images   在server3上建立images目录
[root@server3 html]# cd images/
[root@server3 images]# ls
vim.jpg   放入jpg图片

定义了两个策略,两个不同的后端,如果检测到url以策略里面的目录开头,此处是/images,以策略里面的后缀结尾,此处是
jpg格式,如果匹配到了,就访问static后端

访问172.25.50.1/images/vim.jpg 可以访问如下图:

haproxy 不存在页面 haproxy check_运维_22

添加黑名单策略

[root@server1 haproxy]# vim haproxy.cfg

haproxy 不存在页面 haproxy check_负载均衡_23

[root@server1 haproxy]# systemctl reload haproxy.service  重载服务

172.25.50.250主机访问172.25.50.1/images/vim.jpg无法访问,250已经被加入黑名单

haproxy 不存在页面 haproxy check_php_24

172.25.50.4主机访问172.25.50.1/images/vim.jpg可以访问,172.25.50.4没有被加入黑名单

[root@server4 ~]# curl 172.25.50.1   
server2
[root@server4 ~]# curl 172.25.50.1
server2
[root@server4 ~]# curl 172.25.50.1
server2

[root@server1 haproxy]# vim haproxy.cfg 编辑配置文件,也可以是网段

haproxy 不存在页面 haproxy check_运维_25

[root@server1 haproxy]# systemctl reload haproxy.service  重载服务

server4再次访问,报错,但是给客户直接显示报错,不合适

haproxy 不存在页面 haproxy check_php_26


直接给客户显示报错不合适,可以重定向

[root@server1 haproxy]# vim haproxy.cfg 编辑配置文件

haproxy 不存在页面 haproxy check_haproxy 不存在页面_27

[root@server1 haproxy]# systemctl reload haproxy.service  重载

再次访问172.25.50.1/images/vim.jpg直接转到百度上去了

haproxy 不存在页面 haproxy check_运维_28

读写分离:

haproxy 不存在页面 haproxy check_haproxy 不存在页面_29

[root@server1 haproxy]# systemctl reload haproxy.service  重启服务

访问172.25.50.1 ,读在server2上

haproxy 不存在页面 haproxy check_运维_30

写一个动态语言php,就调度在server3上

[root@server3 ~]# yum install php -y 安装一个动态语言
[root@foundation50 haproxy]# scp -r upload/ root@172.25.50.3:/var/www/html/   将upload目录传到server3默认发布目录里
root@172.25.50.3's password: 
index.php                                     100%  257    22.2KB/s   00:00    
upload_file.php                               100%  927     1.7MB/s   00:00  
[root@server3 ~]# cd /var/www/html/  进入server3默认发布目录
[root@server3 html]# mv upload/* ..  将upload目录里面的文件移动到默认发布目录里
[root@server3 html]# ls
images  index.html  index.php  upload  upload_file.php   有两个php文件

[root@server3 html]# vim upload_file.php 编辑文件,修改图片大小最大为2M

haproxy 不存在页面 haproxy check_php_31

[root@server3 html]# chmod 777 upload   将upload目录权限放到最大,以便上传东西到upload目录里,以免权限不允许
[root@server2 ~]# yum install php -y  在server2上也安装php
[root@server3 html]# scp -r index.php upload_file.php upload server2:/var/www/html/  
将server2上的php文件和upload目录拷贝到server2默认发布目录里
[root@server2 ~]# systemctl restart httpd.service   重启apache,使之生效

访问调度器172.25.50.1/index.php 没有上传时还是在server2上,如果点击提交

haproxy 不存在页面 haproxy check_负载均衡_32


提交成功,如下图

haproxy 不存在页面 haproxy check_运维_33


可以看出,虽然在server2上提交的,但是图片上传到了server3上,这就是读写分离

haproxy 不存在页面 haproxy check_php_34

高可用的实现

在server4同样搭建haproxy
[root@server4 haproxy]# yum install haproxy -y  在server4上安装haproxy
[root@server1 haproxy]# scp haproxy.cfg server4:/etc/haproxy/   将server1上的配置文件复制到server4上
[root@server4 haproxy]# systemctl start  haproxy.service  开启服务

lvs所用的高可用软件为keepalived,但是keepalived有个缺陷:当vip被摘掉后keepalived不会监控

haproxy实现高可用,用另一个软件

[root@server1 haproxy]# systemctl status keepalived.service 确保keepalived没有被开启
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
 [root@foundation50 mfs]# cd /mnt/pub/docs/mfs/   进入mfs目录
 [root@foundation50 mfs]# evince Pacemaker-1.1-Clusters_from_Scratch-en-US.pdf  查看文档,按照文档操作
[root@server1 haproxy]# yum install -y pacemaker pcs psmisc policycoreutils-python  安装套件

haproxy 不存在页面 haproxy check_运维_35


发现两个安装包没有安装,需要配置软件仓库

[root@server1 yum.repos.d]# vim dvd.repo 
[dvd]
name=rhel7.6
baseurl=http://172.25.50.250/rhel7.6
gpgcheck=0


[HighAvailability]
name=HighAvailability
baseurl=http://172.25.50.250/rhel7.6/addons/HighAvailability
gpgcheck=0

[root@server1 yum.repos.d]# yum install -y pacemaker pcs psmisc policycoreutils-python  再次安装,安装成功

给server4做免密

[root@server1 yum.repos.d]# ssh-keygen  
[root@server1 .ssh]# ssh-copy-id server4

将serve1上软件仓库拷贝到server4上

[root@server1 yum.repos.d]# scp dvd.repo server4:/etc/yum.repos.d/ 
dvd.repo                                                         100%  182   260.5KB/s   00:00 
[root@server1 haproxy]# ssh server4 yum install -y pacemaker pcs psmisc policycoreutils-python  server4上安装套件
禁掉防火墙
[root@server1 ~]# systemctl enable --now  pcsd.service  启动server1上pcsd后台程序
Created symlink from /etc/systemd/system/multi-user.target.wants/pcsd.service to /usr/lib/systemd/system/pcsd.service.
[root@server1 ~]# ssh server4 systemctl enable --now pcsd  启动server4上pcsd后台程序
Created symlink from /etc/systemd/system/multi-user.target.wants/pcsd.service to /usr/lib/systemd/system/pcsd.service.
当我们安装高可用套件后,系统会创建一个用户叫hacluster,需要给这个用户创建密码
oot@server1 ~]# echo westos | passwd --stdin hacluster   server1上给hacluster用户创建密码
Changing password for user hacluster.
passwd: all authentication tokens updated successfully.
[root@server1 ~]# ssh server4 'echo westos | passwd --stdin hacluster'  server4上给hacluster用户创建密码
Changing password for user hacluster.
passwd: all authentication tokens updated successfully.
[root@server1 ~]# pcs cluster auth server1 server4   添加节点认证,节点为server1和server4,还可以多加几个
Username: hacluster
Password: 
server4: Authorized
server1: Authorized    认证成功
[root@server1 ~]# pcs cluster setup --name mycluster server1 server4  创建两个节点server1和server4集群
[root@server1 ~]# pcs cluster start --all  启动所有节点
server1: Starting Cluster (corosync)...   corosync表示双机热备,负责两个节点之间心跳信息的传递,通过心跳来确定谁挂了,谁来接管
server4: Starting Cluster (corosync)...
server4: Starting Cluster (pacemaker)...  pacemaker表示集群资源管理器,管理集群整个资源
server1: Starting Cluster (pacemaker)...
[root@server1 ~]#  pcs cluster enable --all   设定节点开机自启
server1: Cluster Enabled
server4: Cluster Enabled
[root@server1 ~]# pcs status  查看集群状态,有警告

haproxy 不存在页面 haproxy check_php_36

[root@server1 ~]# pcs property set stonith-enabled=false   有警告,需要禁掉此功能
[root@server1 ~]# crm_verify  -LV  语法检测,没有报错

查看状态,发现警告没有了

haproxy 不存在页面 haproxy check_haproxy 不存在页面_37


[root@server1 ~]# pcs resource --help 查看创建资源帮助,里面有例子

haproxy 不存在页面 haproxy check_haproxy 不存在页面_38


[root@server1 ~]# pcs resource describe ocf💓IPaddr2 查看里面有那些参数

haproxy 不存在页面 haproxy check_vim_39

[root@server1 ~]# pcs resource create vip ocf:heartbeat:IPaddr2 ip=172.25.50.100 cidr_netmask=24 op monitor interval=30s  创建资源,添加vip资源,  
ocf:heartbeat:IPaddr2 表示脚本 ,ip为脚本里的参数,必须加的,
 cidr_netmask表示子网掩码,monitor interval=30s  监控屏率,表示每隔30s监控一次vip的状态

haproxy 不存在页面 haproxy check_负载均衡_40


haproxy 不存在页面 haproxy check_haproxy 不存在页面_41


vip 已经交给集群了,现在做如下测试:

[root@server1 ~]# pcs node standby 失效处理,先让server1歇着,运行的只有server4,所以vip会跳到server4上

haproxy 不存在页面 haproxy check_haproxy 不存在页面_42


可以发现vip上传到server4上

即使将server4上的vip删除掉,30s后他会重新启动vip

[root@server4 haproxy]# ip addr del 172.25.50.100/24 dev eth0 删除vip
 [root@server4 haproxy]# ip addr

haproxy 不存在页面 haproxy check_vim_43

如何把haproxy服务交给集群

[root@server1 ~]# systemctl stop haproxy.service 先停止服务
 [root@server1 ~]# pcs resource create haproxy systemd:haproxy op monitor interval=60s systemd:haproxy表示调用systemd里面的haproxy脚本
 [root@server1 ~]# pcs status 查看状态

haproxy 不存在页面 haproxy check_haproxy 不存在页面_44


会自动haprxoy启动起来

问题:现在vip 和haproxy 资源都在一个节点上,会不会不在一个结点上?

[root@server1 ~]# pcs node unstandby 将server1恢复
 [root@server1 ~]# pcs status 查看pcs状态

haproxy 不存在页面 haproxy check_haproxy 不存在页面_45

root@server1 ~]# pcs resource group add hagroup vip haproxy  将vip haproxy 资源放在一个组里,必须同时在一起,在一个节点上,而且资源的书写顺序,就是资源在集群中激活的顺序
[root@server1 ~]# pcs status

haproxy 不存在页面 haproxy check_负载均衡_46

测试:

[root@server4 haproxy]# pcs node standby     将server4做失效处理,vip和haproxy同时转到server1上

haproxy 不存在页面 haproxy check_haproxy 不存在页面_47

[root@server4 haproxy]# pcs node unstandby  恢复server4

haproxy 不存在页面 haproxy check_负载均衡_48


再次恢复不会再切到server4上

假设server1网络接口坏了ip link set down eth0,server1和server4之间的心跳也就断了,他们认为彼此坏了,出现了脑裂;
一旦出现网络故障或者内核崩溃,就会造成脑裂,如何解决??

引入fence:

FENCE设备是RHCS集群中必不可少的一个组成部分,通过FENCE设备可以避免因出现不可预知的情况而造成的“脑裂”现象
FENCE设备的出现,就是为了解决类似这些问题,Fence设备主要就是通过服务器或存储本身的硬件管理接口或者外部电源管理设备,来对服务器或存储直接发出硬件管理指令,将服务器重启或关机,或者与网络断开连接

在serve1和server4上安装fence客户端
root@server1 ~]# yum install -y fence-virt
[root@server4 haproxy]# yum install -y fence-virt
[root@server1 ~]# stonith_admin  -I  列出
 fence_xvm
 fence_virt
2 devices found
[root@server1 ~]# stonith_admin  -M -a fence_xvm  查看fence_xvm代理元数据信息 -M表示元数据,-a表示代理

fence运行原理:

管理工具操作外部接口来管理内核

haproxy 不存在页面 haproxy check_haproxy 不存在页面_49


通过libvirt后端连接libvirt外部接口从而对虚拟机进行启停

haproxy 不存在页面 haproxy check_vim_50

在宿主机上安装fence安装包

[root@foundation50 isos]# yum install fence-virtd-multicast.x86_64 fence-virtd.x86_64 fence-virtd-libvirt.x86_64 -y
[root@foundation50 isos]# rpm -qa | grep ^fence  以下三个安装包以安装完成
fence-virtd-multicast-0.4.0-9.el8.x86_64
fence-virtd-libvirt-0.4.0-9.el8.x86_64
fence-virtd-0.4.0-9.el8.x86_64
[root@foundation50 ~]# fence_virtd -c    创建配置文件,并配置
Module search path [/usr/lib64/fence-virt]:   回车

Available backends:
    libvirt 0.3     可用的后端
Available listeners:
    multicast 1.2  可用的后端

Listener modules are responsible for accepting requests
from fencing clients.

Listener module [multicast]:   回车 ,监听模块

The multicast listener module is designed for use environments
where the guests and hosts may communicate over a network using
multicast.

The multicast address is the address that a client will use to
send fencing requests to fence_virtd.

Multicast IP Address [225.0.0.12]:   回车,地址

Using ipv4 as family.

Multicast IP Port [1229]:    回车, 端口

Setting a preferred interface causes fence_virtd to listen only
on that interface.  Normally, it listens on all interfaces.
In environments where the virtual machines are using the host
machine as a gateway, this *must* be set (typically to virbr0).
Set to 'none' for no interface.

Interface [virbr0]: br0    此处需要写br0  因为虚拟机和宿主机是通过br0来通讯的
The key file is the shared key information which is used to
authenticate fencing requests.  The contents of this file must
be distributed to each physical host and virtual machine within
a cluster.

Key File [/etc/cluster/fence_xvm.key]:    key ,要确认key有没有

Backend modules are responsible for routing requests to
the appropriate hypervisor or management layer.

Backend module [libvirt]:       回车

The libvirt backend module is designed for single desktops or
servers.  Do not use in environments where virtual machines
may be migrated between hosts.

Libvirt URI [qemu:///system]:   回车

Configuration complete.

=== Begin Configuration ===
backends {
	libvirt {
		uri = "qemu:///system";
	}

}

listeners {
	multicast {
		port = "1229";
		family = "ipv4";
		interface = "br0";
		address = "225.0.0.12";
		key_file = "/etc/cluster/fence_xvm.key";
	}

}

fence_virtd {
	module_path = "/usr/lib64/fence-virt";
	backend = "libvirt";
	listener = "multicast";
}

=== End Configuration ===
Replace /etc/fence_virt.conf with the above [y/N]? y   写入
 
 [root@foundation50 ~]# ll /etc/cluster/fence_xvm.key  确认有没有fence_xvm.key 这个文件
ls: cannot access '/etc/cluster/fence_xvm.key': No such file or directory   发现没有
[root@foundation50 ~]# mkdir /etc/cluster  如果没有这个目录,创建此目录
[root@foundation50 ~]# cd /etc/cluster/   进入此目录
[root@foundation50 cluster]# dd if=/dev/urandom of=fence_xvm.key bs=128 count=1   随即序列创建fence_xvm.key文件
1+0 records in
1+0 records out
128 bytes copied, 5.3822e-05 s, 2.4 MB/s
[root@foundation50 cluster]# ls
fence_xvm.key  创建完成
[root@foundation50 cluster]# systemctl restart fence_virtd.service  重启服务
[root@foundation50 cluster]# netstat -anulp | grep :1229  
udp        0      0 0.0.0.0:1229            0.0.0.0:*                           37701/fence_virtd    此时1229端口已经打开

[root@server1 ~]# mkdir /etc/cluster 在集群节点server1上建立key目录
[root@server4 ~]# mkdir /etc/cluster 在集群节点server4上建立key目录
[root@foundation50 cluster]# scp fence_xvm.key root@172.25.50.1:/etc/cluster  在宿主机上将fence_xvm.key 拷贝到server1上
root@172.25.50.1's password: 
fence_xvm.key                                 100%  128   227.6KB/s   00:00
[root@foundation50 cluster]# scp fence_xvm.key root@172.25.50.4:/etc/cluster    在宿主机上将fence_xvm.key 拷贝到server4上
The authenticity of host '172.25.50.4 (172.25.50.4)' can't be established.
ECDSA key fingerprint is SHA256:xz6MrlZHE0V7Nv7ukq0/9OR0n8BMz6PLp88JFhoXC4M.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.25.50.4' (ECDSA) to the list of known hosts.
root@172.25.50.4's password: 
fence_xvm.key                                 100%  128   204.3KB/s   00:00 
[root@server1 ~]# pcs stonith create  vmfence fence_xvm pcmk_host_map="server1:vm1;server4:vm4" op monitor interval=60s  在集群节点创建fence
pcmk_host_map 表示影射,因为集群中是主机名,而虚拟机管理界面是虚拟机名,为了识别一一对应,需要影射
[root@server1 ~]# pcs property set stonith-enabled=true   打开此属性

测试:

断开网卡

haproxy 不存在页面 haproxy check_haproxy 不存在页面_51


[root@server1 ~]# pcs status

haproxy 不存在页面 haproxy check_php_52


server4虚拟机会重启,server1接管vmfence

[root@server1 ~]# echo c > /proc/sysrq-trigger 在server1上做内核崩溃
 server1就会立马重启,重启后重新加如集群