第七周
一、lnmp安全加固总结
LNMP=linux+nginx+mysql+php
#linux安全加固
1.账户安全:定期查看系统账户,删除多余的用户账户和组,限制密码最下长度,审查账户权限等。
2.用户登录安全:可以禁用root登录,连续登录失败多次自动锁定,超时自动退出,使用堡垒机等。
3.服务安全:关闭不需要的服务,修改常用服务端口,加固各种服务配置参数等。
4.文件安全:给予最小访问权限,chattr加固重要文件等。
5.及时安装补丁
6.清除系统安装时的配置信息并隐藏系统信息
7.内核优化:net.ipv4.tcp_syncookies = 1,net.ipv4.tcp_max_orphans = 262114等。
#ngxin安全加固
1.配置日志
2.禁止目录浏览
3.删除指定目录执行权限
4.错误页面重定向
5.隐藏版本信息
6.限制http请求方法
7.限制允许和拒绝特定ip访问
8.限制并发和速度
9.控制超时时间
10.nginx降权
11.配置防盗链
12.补丁更新
#mysql安全加固
1.以普通用户运行mysql
2.用户密码安全:设置复杂密码并定期修改密码
3.数据库授权应配置最小权限
4.开启日志审计功能:二进制日志,错误日志,慢查询日志等。
5.安装最新补丁
6.禁止root远程访问,禁止匿名用户登录
7.设置可信ip访问控制
8.设置最大最小连接数
9.禁止使用--skip-grant-tables选项启动MySQL服务
10.修改默认端口
11.禁用symbolic-links选项
12.确保没有用户配置了通配符主机名
13.删除'test'数据库
14.禁用local-infile选项
#php安全加固
1.信息屏蔽:版本号屏蔽,错误信息屏蔽
2.防止全局变量覆盖
3.使用php的访问限制:文件系统限制,远程访问限制,开启安全模式,禁用危险函数。
4.php中的cookie安全:cookei的httponly,cookie的secure,指定cookie的使用范围。
5.php的安装与升级:尽量减少非必要模块的加载,使用第三方安全扩展。
6.常见漏洞与防护,sql注入漏洞防护,xml注入漏洞防护,php组件漏洞防护,文件包含安全,系统命令注入等。
二、keepalived实现LVS的高可用
#环境:centos8
10.0.0.150 ka1
10.0.0.160 ka2
10.0.0.170 web1
10.0.0.180 web2
10.0.0.190 client
#ka1配置
[root@ka1 ~]#yum install -y httpd keepalived
[root@ka1 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id ka1
vrrp_mcast_group4 224.0.100.10
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
10.0.0.188/24 dev eth0 label eth0:1
}
}
virtual_server 10.0.0.188 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.170 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
real_server 10.0.0.180 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
}
[root@ka1 ~]#echo sorry server>> /var/www/html/index.html
[root@ka1 ~]#systemctl enable --now httpd keepalived
#ka2配置
[root@ka2 ~]#yum install -y httpd keepalived
[root@ka2 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id ka2
vrrp_mcast_group4 224.0.100.10
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
10.0.0.188/24 dev eth0 label eth0:1
}
}
virtual_server 10.0.0.188 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.170 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
real_server 10.0.0.180 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
}
[root@ka2 ~]#echo sorry server>> /var/www/html/index.html
[root@ka2 ~]#systemctl enable --now httpd keepalived
#web1配置
[root@web1 ~]#cat lvs_dr_rs.sh
#!/bin/bash
#================================================================
# Copyright (C) 2022 IEucd Inc. All rights reserved.
#
# 文件名称:lvs_dr_rs.sh
# 创 建 者:TanLiang
# 创建日期:2022年08月25日
# 描 述:This is a test file
#
#================================================================
vip=10.0.0.188
mask='255.255.255.255'
dev=lo:1
rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
service httpd start &> /dev/null && echo "The httpd Server is Ready!"
echo "<h1>`hostname`</h1>" > /var/www/html/index.html
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask #broadcast $vip up
#route add -host $vip dev $dev
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
[root@web1 ~]#bash lvs_dr_rs.sh start
The httpd Server is Ready!
The RS Server is Ready!
[root@web1 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.0.0.188/32 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:90:bc:7e brd ff:ff:ff:ff:ff:ff
inet 10.0.0.170/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:46:bf:71 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:46:bf:71 brd ff:ff:ff:ff:ff:ff
[root@web1 ~]#curl localhost
<h1>web1.tan.com</h1>
#web2配置
[root@web2 ~]#cat lvs_dr_rs.sh
#!/bin/bash
#================================================================
# Copyright (C) 2022 IEucd Inc. All rights reserved.
#
# 文件名称:lvs_dr_rs.sh
# 创 建 者:TanLiang
# 创建日期:2022年08月25日
# 描 述:This is a test file
#
#================================================================
vip=10.0.0.188
mask='255.255.255.255'
dev=lo:1
rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
service httpd start &> /dev/null && echo "The httpd Server is Ready!"
echo "<h1>`hostname`</h1>" > /var/www/html/index.html
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask #broadcast $vip up
#route add -host $vip dev $dev
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
[root@web2 ~]#bash lvs_dr_rs.sh start
The httpd Server is Ready!
The RS Server is Ready!
[root@web2 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.0.0.188/32 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:98:bc:23 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.180/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe98:bc23/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:46:bf:71 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:46:bf:71 brd ff:ff:ff:ff:ff:ff
[root@web2 ~]#curl localhost
<h1>web2.tan.com</h1>
#访问验证
[root@redis-node5 ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
#故障测试
#停止keepalived的master节点,访问正常
[root@ka1 ~]#systemctl stop keepalived.service
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
#停掉web1后,有三次调度到web1丢失后,恢复正常访问web2
[root@web1 ~]#systemctl stop httpd
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web2.tan.com</h1>
#重新启动web1后,恢复轮询
[root@web1 ~]#systemctl start httpd
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web2.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
#依次停掉web1,web2,sorryserver上线
[root@web1 ~]#systemctl stop httpd
[root@web2 ~]#systemctl stop httpd
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
<h1>web2.tan.com</h1>
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
curl: (7) Failed to connect to 10.0.0.188 port 80: Connection refused
sorry server
sorry server
sorry server
sorry server
sorry server
sorry server
三、实现haproxy+keepalived集群高可用集群转发
#环境:centos8
10.0.0.150 ka1
10.0.0.160 ka2
10.0.0.170 web1
10.0.0.180 web2
10.0.0.190 client
######ka1配置
#安装软件包
[root@ka1 ~]#yum install -y haproxy keepalived
#配置haroxy
[root@ka1 ~]#cat /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
listen httpd_80
bind 10.0.0.188:80
mode tcp
server web1 10.0.0.170:80 check
server web2 10.0.0.180:80 check
listen stats
mode http
bind 10.0.0.150:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
#启用内核参数
[root@ka1 ~]#echo "net.ipv4.ip_nonlocal_bind = 1" >/etc/sysctl.conf
[root@ka1 ~]#sysctl -p
net.ipv4.ip_nonlocal_bind = 1
#配置keepalived
[root@ka1 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.188/24 dev eth0 label eth0:1
}
}
#启动haproxy和keepalived服务
[root@ka1 ~]#systemctl enable --now haproxy keepalived
#查看端口
[root@ka1 ~]#lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
haproxy 35741 haproxy 7u IPv4 117609 0t0 TCP 10.0.0.188:http (LISTEN)
[root@ka1 ~]#ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:42603 0.0.0.0:*
LISTEN 0 128 10.0.0.150:9999 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 10.0.0.188:80
######ka2配置
#安装软件包
[root@ka2 ~]#yum install -y haproxy keepalived
#配置haroxy
[root@ka2 ~]#cat /etc/haproxy/haproxy.cfg
[root@ka2 ~]#cat /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
listen httpd_80
bind 10.0.0.188:80
server web1 10.0.0.170:80 check
server web2 10.0.0.180:80 check
#启用内核参数
[root@ka2 ~]#echo "net.ipv4.ip_nonlocal_bind = 1" >/etc/sysctl.conf
[root@ka2 ~]#sysctl -p
net.ipv4.ip_nonlocal_bind = 1
#配置keepalived
[root@ka2 ~]#cat /etc/keepalived/keepalived.conf
[root@ka2 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_iptables
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.188/24 dev eth0 label eth0:1
}
}
#启动haproxy和keepalived服务
[root@ka2 ~]#systemctl enable --now haproxy keepalived
#查看端口
[root@ka2 ~]#lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
haproxy 34824 haproxy 7u IPv4 99144 0t0 TCP 10.0.0.188:http (LISTEN)
[root@ka2 ~]#ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 0.0.0.0:53277 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 10.0.0.188:80 0.0.0.0:*
######web1配置
#安装软件包,编写主页文件,启动httpd服务
[root@web1 ~]#yum install -y httpd && echo "<h1>`hostname`</h1>" > /var/www/html/index.html &&systemctl enable --now httpd
######web2配置
#安装软件包,编写主页文件,启动httpd服务
[root@web2 ~]#yum install -y httpd && echo "<h1>`hostname`</h1>" > /var/www/html/index.html &&systemctl enable --now httpd
######在client上验证访问httpd和haproxy状态页
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
[root@client ~]#curl http://haadmin:123456@10.0.0.150:9999/haproxy-status|grep httpd
######故障模拟:停掉ka1主机的keepalived和haproxy访问不受影响
[root@ka1 ~]#systemctl stop keepalived.service haproxy.service
[root@client ~]#while :; do curl 10.0.0.188; sleep 1; done;
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
<h1>web2.tan.com</h1>
<h1>web1.tan.com</h1>
四、haproxy调试算法总结
●HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。
●HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。
#静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
●对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等
●static-rr:基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr
●first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少,不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
#动态算法:基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
●roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,
HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛
●leastconn加权的最少连接的动态,支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。
●在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求
#其它算法即可作为静态算法,又可以通过选项成为动态算法
●source:源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
●map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
●一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
● uri:基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash?type指定map-based和consistent,来定义使用取模法还是一致性hash。注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
●url_param:对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法
●hdr:针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
●rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
#静态
static-rr--------->tcp/http
first------------->tcp/http
#动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
#以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
rdp-cookie-------->tcp
first #使用较少
static-rr #做了session共享的web集群
roundrobin
random
leastconn #数据库
source #基于客户端公网IP的会话保持
Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http #可以实现session保持
hdr #基于客户端请求报文头部做下一步处理
rdp-cookie #基于Windows主机,很少使用