一、FWM
FWM: firewall mark
iptables/netfilter:
filter, nat, mangle, raw
mangle: 防火墙标记
前提:在ipvs生效之前的netfilter的某hook function上定义iptables规则,实现给报文打上防火墙标记;
定义方法:
(1) 打标:在Director上mangle表的PREROUTING链上实现
# iptables -t mangle -A PREROUTING -d $vip -p $protocol --dport $port -j MARK --set-mark [1-99]
(2) 基于FWM定义集群服务
# ipvsadm -A -f FWM -s SCHEDULER
# ipvsadm -a -f FWM -r server-address -g|-i|-m -w #
二、lvs的persistence:lvs持久连接
无论使用哪一种调度方法,持久连接功能都能保证在指定时间范围之内,来自于同一个IP的请求将始终被定向至同一个RS;
persistence template:持久连接模板
PPC:每端口持久
持久连接生效范围仅为单个集群服务;如果有多个集群服务,每服务被单独持久调度;
PCC:每客户端持久
持久连接生效范围为所有服务;定义集群服务时,其TCP或UDP协议的目标端口要使用0;
PFWM:每FWM持久
持久连接生效范围为定义为同一个FWM下的所有服务;
定义方法:
ipvsadm -A -t|-u|-f service-address -s SCHEDULER [-p [#]]
无-p选项:不启用持久连接
-p #:指定持久时长,省略时长,默认为360seconds
三、lvs健康检测
lvs本身不支持对RS的健康状态作检测;
健康:周期性检查机制
状态发生转变时,要作出相应处理
up --> down: 建议要至少确认三次;
down --> up: 建议一次以上(含一次);
下线处理机制:
(1) 设置权重为0;
(2) 将相应的RS从ipvs的可用RS列表中移除;
上线处理机制:
(1) 设置为正常权重;
(2) 将相应的RS添加至ipvs的可用RS列表;
解决方案:
(1) 写程序完成相应功能;
如何做健康状态检查:
三种方案:
IP层:ping等主机在线状态探查工具;
传输层:端口扫描工具探查服务在线状态;
应用层:请求专用于健康状态检查的资源或者某正常资源;
备用服务器:
sorry server, backup server
可以在Director上直接实现:即配置director成为web服务,仅提供有限资源,在所有RS都故障时,方才启用此server;
作业:写脚本,完成RS健康状态检查;
#!/bin/bash # fwm=10 sorry_server='127.0.0.1' lvstype='-m' checkloop=3 # 循环次数 logfile=/var/log/ipvs_health_check.log rs=('192.168.10.11' '192.168.10.12') rw=('1' '1') # 定义权重 rsstatus=(0 0) # 定义初始状态 addrs() { # $1: rs, $2: rs weight ipvsadm -a -f $fwm -r $1 $lvstype -w $2 [ $? -eq 0 ] && return 0 || return 1 }
delrs() { # $1: rs ipvsadm -d -f $fwm -r $1 [ $? -eq 0 ] && return 0 || return 1 } chkrs() { # $1: rs local i=1 while [ $i -le $checkloop ]; do if curl --connect-timeout 1 -s http://$1/index.html | grep -i "real[[:space:]]* server" &> /dev/null; then return 0 fi let i++ sleep 2 # 休眠2s done return 1 }
initstatus() { for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then rsstatus[$host]=1 fi else if [ ${rstatus[$host]} -eq 1 ]; then rsstatus[$host]=0 fi fi done }
initstatus while :; do for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then addrs ${rs[$host]} ${rw[$host]} [ $? -eq 0 ] && rsstatus[$host]=1 fi else if [ ${rsstatus[$host]} -eq 1 ]; then delrs ${rs[$host]} [ $? -eq 0 ] && rsstatus[$host]=0 fi fi done sleep 10 done
作业:改进此脚本
(1) 启用在rs上下线时记录日志;
(2) 在所有rs下线时启用sorry_server;
博客作业:lvs原理、lvs-nat的实现、lvs-dr的实现