一、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=10sorry_server='127.0.0.1'lvstype='-m'checkloop=3   # 循环次数logfile=/var/log/ipvs_health_check.logrs=('192.168.10.11' '192.168.10.12')rw=('1' '1')  # 定义权重rsstatus=(0 0) # 定义初始状态addrs() { # $1: rs, $2: rs weightipvsadm -a -f $fwm -r $1 $lvstype -w $2        [ $? -eq 0 ] && return 0 || return 1}
delrs() {           # $1: rsipvsadm -d -f $fwm -r $1[ $? -eq 0 ] && return 0 || return 1}chkrs() { # $1: rslocal i=1while [ $i -le $checkloop ]; do      if curl --connect-timeout 1 -s http://$1/index.html | grep -i "real[[:space:]]* server" &> /dev/null; thenreturn 0filet i++sleep 2  # 休眠2sdonereturn 1}
initstatus() {for host in `seq 0 $[${#rs[@]}-1]`; doif chkrs ${rs[$host]}; then    if [ ${rsstatus[$host]} -eq 0 ]; thenrsstatus[$host]=1            fi        else    if [ ${rstatus[$host]} -eq 1 ]; thenrsstatus[$host]=0     fifi    done}
initstatuswhile :; dofor host in `seq 0 $[${#rs[@]}-1]`; doif chkrs ${rs[$host]}; then     if [ ${rsstatus[$host]} -eq 0 ]; then             addrs ${rs[$host]} ${rw[$host]}            [ $? -eq 0 ] && rsstatus[$host]=1      fielse     if [ ${rsstatus[$host]} -eq 1 ]; then     delrs ${rs[$host]}     [ $? -eq 0 ] && rsstatus[$host]=0     fifi    done    sleep 10done

作业:改进此脚本

(1) 启用在rs上下线时记录日志;

(2) 在所有rs下线时启用sorry_server;

博客作业:lvs原理、lvs-nat的实现、lvs-dr的实现