一、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的实现