一、HAProxy全透明代理
全透明代理 : 可以用 客户端IP地址或者任何其他地址来连接后端服务器。 这个特性仅在Linux 2.4/2.6内核打了cttproxy 补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。
1.检查系统内核是否已支持Tproxy:
[root@www ~]# grep TPROXY /boot/config-`uname -r`
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
看到上述信息,说明内核支持tproxy,2.6.32以后的内核,都支持这个功能,无需在打补丁。
要点是,在编译HAProxy时加上 USE_LINUX_TPROXY=1,这是开启全透明代理的参数。
2、设置iptables和路由
安装HAproxy服务的机器,防火墙一定要打开,让所有进入网桥设备的mangle表的包都打上标记,然后新增一条路由规则将这些打了标记的数据包发送至本地回环接口进行处理。
[root@www ~]# ip rule add fwmark 1 lookup 100
[root@www ~]# ip route add local 0.0.0.0/0 dev lo table 100
[root@www ~]# iptables -t mangle -N DIVERT
[root@www ~]# iptables -t mangle -A DIVERT -j MARK --set-mark 1
[root@www ~]# iptables -t mangle -A DIVERT -j ACCEPT
[root@www ~]# iptables -t mangle -A PREROUTING -p tcp -m socket -jDIVERT
配置内核参数支持IP转发和对源地址进行检查:
echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
echo 1 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 1 > /proc/sys/net/ipv4/conf/eth0/send_redirects
防火墙保存好后,配置文件应该如下:
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [80:4800]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [160:8960]
:POSTROUTING ACCEPT [160:8960]
:DIVERT - [0:0]
-A PREROUTING -p tcp -m socket -j DIVERT
-A DIVERT -j MARK --set-xmark 0x1/0xffffffff
-A DIVERT -j ACCEPT
COMMIT
3、最重要的一点是修改HAProxy的配置文件,每个 backend server都要加上下边的设置,才能使用全透名模式。
source
0.0.0.0 usesrc clientip
#
重点,TPROXY需要加上这行
使用这个功能,要把配置文件中的运行用户和去掉,需要root身份运行才行,然后把后端服务的网管,改成
HAproxy
的
ip
,到此为此基于
TProxy
的
Haproxy
全透明代理完成了。
有篇文章说数据再返回客户端的时候,会有问题,还要在改写内核参数,我测试没有发现有此问题,有过,遇到问题,请参考以下文章:
http://www.360doc.com/content/13/0821/17/13047933_308812287.shtml
。
二、
Unix套接字命令(Unix Socket commands
)
socat
是一个多功能的网络工具,名字来由是“
Socket CAT
”,可以看作是
netcat
的N倍加强版,
socat
的官方网站:
http://www.dest-unreach.org/socat/
。
socat
是一个两个独立数据通道之间的双向数据传输的继电器。这些数据通道包含文件、管道、设备(终端或调制解调器等)、插座
(
Unix
,
IP4
,
IP6 - raw
,
UDP
,
TCP
)、
SSL
、
SOCKS
4
客户端或代理
CONNECT
。
socat
支持广播和多播、抽象
Unix sockets
、
Linux tun/tap
、
GNU readline
和
PTY
。它提供了分叉、记录和进程间通信的不同模式。多个选项可用于调整
socat
和其渠道,
Socat
可以作为TCP中继(一次性或守护进程),作为一个守护进程基于
socksifier
,作为一个
shell Unix
套接字接口,作为
IP6
的继电器,或面向TCP的程序重定向到一个串行线。
socat
的主要特点就是在两个数据流之间建立通道;且支持众多协议和链接方式:
ip, tcp, udp, ipv6, pipe,exec,system,open,proxy,openssl,socket
等。
使用
socat
可以查看和设置
HAProxy
状态,首先得让
HAProxy
产生出一个
sock
出来
(hatop
,
socat
都是基于这个的,没这个什么都做不了)。
1
、设置配置文件开启
unix socket
在
global
下面 加一行:
stats socket /usr/local/haproxy/stats #路径和名字随意
然后重启服务就可以了。
2、安装socat
从官网下在socat最新版,有人说版本太高安装不上,我没有遇到问题。
[root@www~]# wget http://www.dest-unreach.org/socat/download/socat-1.7.2.4.tar.gz
[root@www~]# tar xf socat-1.7.2.4.tar.gz
[root@www~]# cd socat-1.7.2.4
[root@www~]# ./configure
[root@www~]# make &&make install
3、socat使用
echo "help"| socat stdio /usr/local/haproxy/stats #会有帮助提示
echo "show info"| socat stdio /usr/local/haproxy/stats #资源使用信息
echo "show stat"| socat stdio /usr/local/haproxy/stats #状态信息
熟悉使用方法后,完全可以使用socat,编写脚本,将HAProxy加到监控里边,实时运行监控状态情况。
以上仅是获取HAProxy信息,如果想通过socat进行设置HAProxy,权限还是不够的,需要修改配置文件,设置操作权限,修改HAProxy配置文件如下:
stats socket/usr/local/haproxy/stats level admin #将等级设置为管理
重启服务,然后就可以操作了。
例如禁用启用成员:
[root@www~]#echo "disable server web_cluters/iask51"|socat stdio/usr/local/haproxy/stats
[root@www ~]# echo "enable serverweb_cluters/iask51"|socat stdio /usr/local/haproxy/stats
[root@www ~]# echo "disable frontend http_80_in"|socat stdio /usr/local/haproxy/stats
[root@www ~]# echo "enable frontend http_80_in"|socat stdio /usr/local/haproxy/stats
disable与enable支持“agent”、“frontend”、“health”和“server”,命令要比图形界面强大的多,好多参数设定,都可以使用socat来操作。记住一个格式“命令 backend/server”,其它的命令用法自己研究吧。
三、HAProxy负载均衡保持客户端和服务器Session亲缘性的三种方式
1、用户IP 识别
haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令),这种方式不用多少,大家都很熟悉,也很常用,就算清空了cookie,同一ip的请求也不会被分发到别的机器上。
配置指令: balance source
2、cookie 识别
HAProxy 将WEB服务端发送给客户端的cookie中插入(或添加前缀)haproxy定义的后端的服务器COOKIE ID。
编写一个可插入cookie的php测试页,来验证实验。代码如下:
<html>
<head>
<title>PHP测试</title>
</head>
<body>
<?phpecho '<p>Hello World </p>'; ?>
<?php echo "访问的服务器地址是:"."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
echo"访问的服务器域名是:"."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>";
?>
</body>
</html>
配置指令例举 cookieSESSION_COOKIE insert indirect nocache
SESSION_COOKIE这个名字可以随便起,用firebug可以观察到用户的请求头的cookie里 有类似"Cookie jsessionid=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=app1" SESSION_COOKIE=ask50就是haproxy添加的内容。
这样haproxy就会按cookie id值分配到对应的服务器上,只要客户端不清除cookie,轮询功能也就失去了作用,和ip hash功能差不多了,当客户端清除cookie后,请求服务器的时候,就会被分发到别的机器上了。
Ctrl+F5刷新后,页面没有变化,cookie id没有变换,访问的是同一台服务器
清空浏览器cookie,再次访问,发现页面有变化,访问的是另一台服务器
3、session 识别
HAProxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。
测试程序代码如下:
<?php
session_start();
$_SESSION['time']=date("Y-m-d H:s",time());
echo "本次访问时间: "."<fontcolor=red>".$_SESSION['time']."</font>"."<br>";
echo "访问的服务器地址是: "."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
echo "访问的服务器域名是: "."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>";
echo"SESSIONNAME是: "."<fontcolor=red>".session_name()."</font>"."<br>";
echo "SESSIONID是: "."<fontcolor=red>".session_id()."</font>"."<br>";
?>
配置指令例举 appsession JSESSIONID len 64 timeout 5hrequest-learn,注意JSESSIONID这个值替换成你的php.ini 里session.name的值。
和cookie识别模式差不多
Ctrl+F5刷新后,页面没有变化,session id没有变换,访问的是同一台服务器
清空浏览器cookie,再次访问,发现页面有变化,访问的是另一台服务器