欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 37_02 _Linux集群系列之五——脚本实现LVS后端服务健康状态检查 有大用

image.png


在 director (我的ip (DIP) 192.168.0.75 ) 上 80 端口启动起来了

[root@mail ~]# service httpd start

启动 httpd:                                               [确定]

[root@mail ~]# netstat -tnlp | grep 80

tcp        0      0 0.0.0.0:32803               0.0.0.0:*                   LISTEN      -

tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      4080/sshd

tcp        0      0 :::80                       :::*                        LISTEN      14578/httpd

tcp        0      0 :::22                       :::*                        LISTEN      4080/sshd

[root@mail ~]#

[root@mail ~]#


我的ip (DIP) 192.168.0.75 

image.png

找不到 httpd 安装在哪里目录下了 ,只看到 首页以 index.html 开始,用如下命令发觉到在 /www/a.org/index.html 目录里面

[root@mail test]# locate index.html | xargs -I {} echo {}| xargs  grep "^index.html"

/www/a.org/index.html:index.html

[root@mail test]#

[root@mail test]# echo "<h1>Director.magedu.com</h1>" > /www/a.org/index.html

[root@mail test]#


我的ip (DIP) 192.168.0.75  看到效果了

image.png

把自己的director 作为 rs 加上去

[root@mail test]# ipvsadm -a -t 192.168.0.77:80 -r 127.0.0.1 -g -w 5

[root@mail test]#

[root@mail test]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

  -> 192.168.0.55:80              Route   1      0          0

[root@mail test]#


为了防止干扰,把director 和两个 rs 的iptables 全部清空 #iptables -F


可以看出三个都能够显示

image.png

image.png

image.png


director 本身是一个负载均衡器,目的不是为了让别人访问,而是作为一个调度器的,  director 的http服务页面不是为了提供服务的,而是紧急情况下(比如rs全都宕机了),此时可以 director的服务器提供一个错误页面,您所访问的服务器正在维护当中


我们可以保存ipvsadm规则

service ipvsadm save

ipvsadm -S


对 director上 VIP,路由设置不能保存


RS上的:arp_ignore,arp_announce,(对于all,对于eth0或lo),VIP地址,路由条目,怎么自动实现


所以我们需要服务脚本

[root@mail test]# chkconfig --list ipvsadm

ipvsadm         0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭

[root@mail test]#

 

ipvsadm 是在内核中生效的,本身并不是一个服务,所以需要其它额外的配置,它还依赖于别的配置文件来保存规则,所以我们就不用它了,我们自己写脚本吧



Director脚本


DR类型中,Director和 RealServer的配置脚本示例

image.png

266 行 iptables -Z :将iptables的计数器清0

image.png

281行,建的是锁文件,前面start时应该是加判断,不存在锁文件的时候,才能start

image.png


Real Server脚本

image.png

345 行应该后面加上删掉 339 行添加的路由

image.png



rs 提供主页面,我们看能不能访问,

# elinks url 就是交互式的,加上 -dump选项,就是把内容加载下来,退出命令

[root@mail test]# elinks -dump http://192.168.0.45/index.html

   RS1.magedu.com

[root@mail test]#

[root@mail test]# echo $?        #美元符问号是上次命令的状态码  上一个命令(上一个进程)执行状态返回值

0

[root@mail test]#


[root@mail test]# elinks -dump http://192.168.0.9/index.html  不存在的页面 卡半天         我们可以定义它的超时时间

image.png


[root@mail test]# echo $?    #结果为1,不对了

1

[root@mail test]#


如果rs 在线,不管;;如果rs不在线,就从real server 列表中移除

如果移除了rs,过一会儿又在线了,就又加到real server 列表中


我们也可以在rs (192.168.0.45)上提供一个测试页

[root@rs1 a.org]# pwd

/www/a.org

[root@rs1 a.org]# vim .health_check.html

OK



在 director (192.168.0.75)上 elinks 一下

[root@mail ~]# elinks -dump http://192.168.0.45/.health_check.html

   OK

[root@mail ~]#

[root@mail ~]# elinks -dump http://192.168.0.45/.health_check.html | grep "OK" &> /dev/null

[root@mail ~]# echo $?    #说明能正常访问

0

[root@mail ~]#

如果 elinks 访问错误(rs 挂了),那么会等待,会很慢的


在 director (192.168.0.75)上 curl 


[root@mail ~]# curl  http://192.168.0.45/index.html

RS1.magedu.com

[root@mail ~]#


[root@mail ~]# curl  http://192.168.0.9/index.html    #不存在的页面 也会卡住

curl: (7) couldn't connect to host

[root@mail ~]#


curl 命令选项

--cacert <file> CA证书(SSL)

--capath <directory> CA目录(made using C rehash) to verify peer against (SSL)

--compressed要求返回是压缩的形势(using deflate or gzip)

--connect-timeout <seconds> 设置最大请求时间

-H/--header <line>自定义头信息传递给服务器

-i/--include输出时包括protocol头信息

-I/--head只显示头部文档信息

--interface <interface>使用指定网络接口/地址

-s/--silent静音模式。不输出任何东西     #静默模式,不显示进度表或错误信息,但是仍然会显示网页内容

-u/--user <user[ :password]>设置服务器的用户和密码

-p/--proxytunnel使用HTTP代理



[root@mail ~]# curl --connect-timeout 1  http://192.168.0.9/index.html    #--connect-timeout设置连接请求超时时间,会快点吧

curl: (28) connect() timed out!

[root@mail ~]#



[root@mail ~]# curl -I  http://192.168.0.45/index.html    #-I header方式获取数据,不获取网页真正内容,只获取页面的响应首部        

HTTP/1.1 200 OK            #这里 200 或 301 之类,,,,2或3开头的,说明是能访问到的

Date: Wed, 11 Nov 2020 01:02:30 GMT

Server: Apache/2.4.4 (Unix) PHP/5.4.13

Last-Modified: Thu, 05 Nov 2020 06:50:22 GMT

ETag: "f-5b35682870780"

Accept-Ranges: bytes

Content-Length: 15

Content-Type: text/html


[root@mail ~]#

root@mail ~]# curl -s  http://192.168.0.45/index.html        #静默模式,不显示进度表或错误信息,但是仍然会显示网页内容

RS1.magedu.com

[root@mail ~]#


[root@mail ~]# curl  http://192.168.0.45/index.html &> /dev/null        #送到null 中

[root@mail ~]# echo $?        #根据状态返回值来判断是否在线

0

[root@mail ~]#

[root@mail ~]# curl --connect-timeout 1  http://192.168.0.9/index.html &> /dev/null        #不存在服器务

[root@mail ~]# echo $?    #非零值

7

[root@mail ~]#


[root@mail ~]# man curl

image.png

状态返回值 除了0,其它数字是各式各样的错

image.png


检测 rs 服务器是否在线的脚本




RIP=("192.168.10.7" "192.168.10.8")    #这是一个数组

数组 有如下图的两种赋值方式  

Array_name[index]


第一种方式

Array_name=("element1""element2")


第二种方式;如果中间 没有元素值,都为null,都为未赋值的元素

Array_name[0]="element1"

Array_name[7]="element8"

image.png

[root@mail ~]# RS=("192.168.10.7" "192.168.10.8")

[root@mail ~]# echo $RS[0]

192.168.10.7[0]

[root@mail ~]# echo $RS[1]

192.168.10.7[1]

[root@mail ~]# echo ${RS[0]}        #引用的时候,一定要加花括号(大括号)      美元符号花括号

192.168.10.7

[root@mail ~]# echo ${RS[1]}        #引用的时候,一定要加花括号(大括号)     美元符号花括号

192.168.10.8

[root@mail ~]#

[root@mail ~]# echo $RS        #直接数组变量,表示是数组的第一个元素

192.168.10.7

[root@mail ~]#

[root@mail ~]# echo ${#RS}        # 井号表示第一个元素的字符个数

12

[root@mail ~]# echo ${#RS[*]}        # 井号变量中括号星号 表示 元素的个数

2


[root@mail ~]# echo ${RS[*]}        # 变量中括号星号或艾特符号 表示数组中所有元素

192.168.10.7 192.168.10.8

[root@mail ~]# echo ${RS[@]}

192.168.10.7 192.168.10.8

[root@mail ~]#

[root@mail ~]#

由下图 每个 real server 其实是有端口的 只是我们添加时,80 与 集群服务的80 一样,所以添加时省略掉了

image.png


在director 上

[root@mail ~]# vim health_check.sh


#!/bin/bash

#

VIP=192.168.0.77

CPORT=80

FAIL_BACK=127.0.0.1

RS=("192.168.0.45" "192.168.0.55")

RSTATUS=("1" "1") #这里状态,1表示启用,0表示禁用

RW=("2" "1") #这是权重

RPORT=80

let COUNT=0

TYPE=g


add() {

        ipvsadm -a -t $VIP:$CPORT -r $1 -$TYPE -w $2

        [ $? -eq 0 ] && return 0 || return 1

}


del() {

        ipvsadm -d -t $VIP:$CPORT -r $1

        [ $? -eq 0 ] && return 0 || return 1

}


for I in ${RS[*]}; do

  if curl --connect-timeout 1 http://$I/index.html &> /dev/null; then

    if [ ${RSTATUS[$COUNT]} -eq 0 ]; then

        add $I ${RW[$COUNT]}

        [ $? -eq 0 ] && RSTATUS[$COUNT]=1

    fi

  else

    if [ ${RSTATUS[$COUNT]} -eq 1 ]; then

        del $I

        [ $? -eq 0 ] && RSTATUS[$COUNT]=0

    fi

  fi

  let COUNT++

done




rs2 上的 http服务停掉看看

[root@rs2 ~]# service httpd stop

停止 httpd:                                               [确定]

[root@rs2 ~]#


[root@mail ~]# bash -x health_check.sh

+ VIP=192.168.0.77

+ CPORT=80

+ FAIL_BACK=127.0.0.1

+ RS=("192.168.0.45" "192.168.0.55")

+ RSTATUS=("1" "1")

+ RW=("2" "1")

+ RPORT=80

+ let COUNT=0

+ TYPE=g

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.45/index.html

+ '[' 1 -eq 0 ']'

+ let COUNT++

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.55/index.html

+ '[' 1 -eq 0 ']'

+ let COUNT++

[root@mail ~]#


停掉 rs2 (192.168.0.55) 看看

[root@rs2 ~]# service httpd stop

停止 httpd:                                               [确定]

[root@rs2 ~]#



停掉后 在 director 执行health_check.sh 看看


[root@mail ~]# bash -x health_check.sh        # 看到了 从集群中 删除了 rs2 (192.168.0.55) 

+ VIP=192.168.0.77

+ CPORT=80

+ FAIL_BACK=127.0.0.1

+ RS=("192.168.0.45" "192.168.0.55")

+ RSTATUS=("1" "1")

+ RW=("2" "1")

+ RPORT=80

+ let COUNT=0

+ TYPE=g

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.45/index.html

+ '[' 1 -eq 0 ']'

+ let COUNT++

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.55/index.html

+ '[' 1 -eq 1 ']'

+ del 192.168.0.55

+ ipvsadm -d -t 192.168.0.77:80 -r 192.168.0.55

+ '[' 0 -eq 0 ']'

+ return 0

+ '[' 0 -eq 0 ']'

+ RSTATUS[$COUNT]=0

+ let COUNT++

[root@mail ~]#

[root@mail ~]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#



rs2 ( 192.168.0.55 ) 的web再启动一下

[root@rs2 ~]# service httpd start

启动 httpd:AH00557: httpd: apr_sockaddr_info_get() failed for rs2.magedu.com

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message

                                                           [确定]

[root@rs2 ~]#


启动后,在 director 执行health_check.sh 看看

[root@mail ~]# bash -x health_check.sh

+ VIP=192.168.0.77

+ CPORT=80

+ FAIL_BACK=127.0.0.1

+ RS=("192.168.0.45" "192.168.0.55")

+ RSTATUS=("1" "1")

+ RW=("2" "1")

+ RPORT=80

+ let COUNT=0

+ TYPE=g

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.45/index.html

+ '[' 1 -eq 0 ']'

+ let COUNT++

+ for I in '${RS[*]}'

+ curl --connect-timeout 1 http://192.168.0.55/index.html

+ '[' 1 -eq 0 ']'

+ let COUNT++

[root@mail ~]#

[root@mail ~]# ipvsadm -L -n        # 好像 rs2 192.168.0.55 没有加进来  看 health_check.sh 代码 因为事实上 RSTATUS的初始数组里面的元素永远都为1 ,,我们应该删除rs时,把RSTATUS里面相应的元素的值(应该为0)写到某配置文件里吧,随着脚本health_check.sh的启动而启动;;或者上来先测试状态,保留状态结果,然后再一个一个的检测???或者我们的脚本执行起来后,不让退出,随时进行检测

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#


在  director 上 修改health_check.sh 为 health_check2.sh

root@mail ~]# vim health_check2.sh

#!/bin/bash

#

VIP=192.168.0.77

CPORT=80

FAIL_BACK=127.0.0.1

RS=("192.168.0.45" "192.168.0.55")

RSTATUS=("1" "1")

RW=("2" "1")

RPORT=80


TYPE=g


add() {

        ipvsadm -a -t $VIP:$CPORT -r $1 -$TYPE -w $2

        [ $? -eq 0 ] && return 0 || return 1

}


del() {

        ipvsadm -d -t $VIP:$CPORT -r $1

        [ $? -eq 0 ] && return 0 || return 1

}


while : ; do

 let COUNT=0

 for I in ${RS[*]}; do

  if curl --connect-timeout 1 http://$I/index.html &> /dev/null; then

    if [ ${RSTATUS[$COUNT]} -eq 0 ]; then

        add $I ${RW[$COUNT]}

        [ $? -eq 0 ] && RSTATUS[$COUNT]=1

    fi

  else

    if [ ${RSTATUS[$COUNT]} -eq 1 ]; then

        del $I

        [ $? -eq 0 ] && RSTATUS[$COUNT]=0

    fi

  fi

  let COUNT++

 done

sleep 5

done


root@mail ~]# bash  health_check2.sh        #一直在循环执行着


director (192.168.0.75) 另一个窗口

[root@mail ~]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#

[root@mail ~]# ipvsadm -L -n        # 没看到  rs2 (192.168.0.55)

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#


重启  rs2 (192.168.0.55) 

[root@rs2 ~]# service httpd restart

停止 httpd:                                               [确定]

启动 httpd:AH00557: httpd: apr_sockaddr_info_get() failed for rs2.magedu.com

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message

                                                           [确定]

[root@rs2 ~]#



director (192.168.0.75) 另一个窗口

[root@mail ~]# ipvsadm -L -n        #依然没有  rs2 (192.168.0.55)

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#


手动添加   #ipvsadm -a -t 192.168.0.77:80 -r 192.168.0.55 -g -w 1

再在 rs2 (192.168.0.55) 上执行web服务停掉,正常了,,为什么上一次不正常?也许是没有回到初始状态吧

director上 

[root@mail ~]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#


启动,正常了

director上 

[root@mail ~]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.55:80              Route   1      0          0

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]# 

在 rs1 (192.168.0.45) 上执行web服务停掉,启动,也正常了 (就不贴代码了

)



如果两个rs 都挂了,,那么就把 127.0.0.1加进来

127.0.0.1是为了rs全挂的情况下,才加进来的,叫做 fallback server

[root@mail ~]# ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.77:80 wlc

  -> 192.168.0.55:80              Route   1      0          0

  -> 192.168.0.45:80              Route   2      0          0

  -> 127.0.0.1:80                 Local   5      0          0

[root@mail ~]#


先删掉本机作为rs的那个规则

[root@mail ~]# ipvsadm -d -t 192.168.0.77:80 -r 127.0.0.1

[root@mail ~]#


director 上 (health_check3.sh  是对 health_check2.sh的改动)

[root@mail ~]# vim health_check3.sh    #马哥说 这个代码就自己写吧

当两个rs全挂的时候,把127.0.0.1添加进来,

但有一个rs上线的时候,再把127.0.0.1删掉


普通分类: