马哥架构第2周课程作业

news2024/11/27 2:22:11

haproxy、nginx、lvs负责均衡相关的话题

  • 一. nginx和haproxy的异同点
  • 二. 实现haproxy四层地址透传,并且做基于cookie的会话保持
    • 2.1 haproxy四层地址透传
    • 2.2 基于cookie的会话保持
      • 2.2.1 配置选项
    • 2.2.2 配置示例
      • 2.2.3 验证 Cookie 信息
  • 三. 实现自定义错误页面和https的实验
    • 3.1 自定义错误页面
      • 3.1.1 基于自定义的错误页面文件
      • 3.1.2 基于http重定向错误页面
    • 3.2 https的实验
      • 3.2.1 证书制作
      • 3.2.2 Https 配置示例
      • 3.2.3 修改后端服务器的日志格式
      • 3.2.4 验证 Https
  • 四. 画出2出架构图,写出3的关键点(重点配置)
  • 五. 做题要求,每题首先使用脑图工具(亿图)画出原理架构图。
  • 六. 完成keepalived的单播非抢占多主机高可用IP, 抢占邮件通知。
    • 6.1 vip单播配置
    • 6.2 Keepalived 通知脚本配置
      • 6.2.1 通知脚本类型
      • 6.2.2 脚本的调用方法
      • 6.2.3 实战案例1:实现 Keepalived 状态切换的通知脚本
      • 6.2.4 实战案例2:实现 Keepalived 状态切换的通知脚本
        • 6.2.4.1 邮件配置
        • 6.2.4.2 创建通知脚本
  • 七. 完成lvs + keepalived 高可用配置
  • 7.1 实战案例:实现单主的 LVS-DR 模式
    • 7.2 实战案例:实现双主的 LVS-DR 模式
    • 7.3 实战案例:实现单主的 LVS-DR 模式,利用FWM绑定成多个服务为一个集群服务
  • 八. 完成lvs + nginx 高可用配置

一. nginx和haproxy的异同点

haproxy定位跟lvs类似,仅仅作为反向代理没有别的功能,nginx擅长做web服务也有反向代理的功能但是作为web服务性能还是不错的,但是作为反向代理性能上没有lvs那么强,lvs工作在内核级,并发可以达到百万级,但是lvs跟nginx相比较它有缺点:功能上没有nginx丰富,web先不说,反向代理可以提供四层也可以提供七层,它还有一些健康检查的功能,haproxy介于两者之间,反向代理性能比nginx好一些比lvs功能更加丰富,他是一个专业级的反向代理,定位是专业级反向代理所以甚至比nginx更加丰富,重点调度算法跟lvs、nginx对比

二. 实现haproxy四层地址透传,并且做基于cookie的会话保持

2.1 haproxy四层地址透传

https://www.haproxy.com/de/blog/using-haproxy-with-the-proxy-protocol-to-better-secure-your-database/

#haproxy 配置:
listen web_http_nodes
   bind  172.16.0.100:80 #因下面wangxiaochun.com的站点建立在阿里云有防火墙,此处必须用80
端口,如无防火墙可以使用其它端口
   mode tcp            #不支持http协议
   balance roundrobin
   server web1 www.wangxiaochun.com:80 send-proxy check inter 3000 fall 3
rise 5 #添加send-proxy
#nginx 配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
http {
 log_format main  '$remote_addr - $remote_user [$time_local] "$request" 
"$proxy_protocol_addr"'
   server {
       listen       80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理
访问
       server_name www.wangxiaochun.com;

抓包可以看到 continuation 信息中带有客户端的源IP

在这里插入图片描述

范例: nginx 开启四层日志功能

#nginx在开启proxy_protocol前
[root@internet ~]#curl 172.16.0.100
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@VM_0_10_centos ~]# tail -f /apps/nginx/logs/nginx.access.log
111.199.187.69 - - [09/Apr/2020:20:48:51 +0800] "PROXY TCP4 10.0.0.7 58.87.87.99 
35948 80" sendfileon
111.199.187.69 - - [09/Apr/2020:20:48:54 +0800] "PROXY TCP4 10.0.0.7 58.87.87.99 
35952 80" sendfileon
111.199.187.69 - - [09/Apr/2020:20:48:57 +0800] "PROXY TCP4 10.0.0.7 58.87.87.99 
35954 80" sendfileon
#在nginx服务器上开启日志格式和proxy_protocal
[root@VM_0_10_centos ~]# vim /apps/nginx/conf/nginx.conf
http {
.......
 log_format main  '$remote_addr - $remote_user [$time_local] "$request" 
"$proxy_protocol_addr"'
   sendfile       on;
   keepalive_timeout  65;
   client_max_body_size 100m;
   server {
       listen       80 default_server proxy_protocol ;
......
#nginx在开启proxy_protocol后,可以看客户端真实源IP
[root@VM_0_10_centos ~]# tail -f /apps/nginx/logs/nginx.access.log
111.199.187.69 - - [09/Apr/2020:20:52:52 +0800] "GET / HTTP/1.1"
"172.16.0.200"sendfileon

2.2 基于cookie的会话保持

cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址
hash 调度算法对客户端的粒度更精准,但同时也加重了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
注意:不支持 tcp mode,使用 http mode

2.2.1 配置选项

cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ 
preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name: #cookie 的 key名称,用于实现持久连接
insert: #插入新的cookie,默认不插入cookie
indirect: #如果客户端已经有cookie,则不会再发送cookie信息
nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,
因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器

2.2.2 配置示例

listen web_port
 bind 10.0.0.7:80
 balance roundrobin
 mode http #不支持 tcp mode
 log global
 cookie WEBSRV insert nocache indirect
 server web1  10.0.0.17:80 check inter 3000 fall 2 rise 5 cookie web1
 server web2  10.0.0.27:80 check inter 3000 fall 2 rise 5 cookie web2 

2.2.3 验证 Cookie 信息

在这里插入图片描述
在这里插入图片描述
通过命令行验证

[root@centos6 ~]#curl -i 10.0.0.7
HTTP/1.1 200 OK
date: Thu, 02 Apr 2020 02:26:08 GMT
server: Apache/2.4.6 (CentOS)
last-modified: Thu, 02 Apr 2020 01:44:28 GMT
etag: "a-5a244f0fd5175"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
set-cookie: WEBSRV=web2; path=/
cache-control: private
10.0.0.27
[root@centos6 ~]#curl -i 10.0.0.7
HTTP/1.1 200 OK
date: Thu, 02 Apr 2020 02:26:15 GMT
server: Apache/2.4.6 (CentOS)
last-modified: Thu, 02 Apr 2020 01:44:13 GMT
etag: "a-5a244f01f8adc"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
set-cookie: WEBSRV=web1; path=/
cache-control: private
10.0.0.17
[root@centos6 ~]#curl -b WEBSRV=web1 10.0.0.7
10.0.0.17
[root@centos6 ~]#curl -b WEBSRV=web2 10.0.0.7
10.0.0.27
[root@centos6 ~]#curl -vb WEBSRV=web1 10.0.0.7
* About to connect() to 10.0.0.7 port 80 (#0)
*   Trying 10.0.0.7... connected
* Connected to 10.0.0.7 (10.0.0.7) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 
zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 10.0.0.7
> Accept: */*
> Cookie: WEBSRV=web1
> 
< HTTP/1.1 200 OK
< date: Thu, 02 Apr 2020 02:27:54 GMT
< server: Apache/2.4.6 (CentOS)
< last-modified: Thu, 02 Apr 2020 01:44:13 GMT
< etag: "a-5a244f01f8adc"
< accept-ranges: bytes
< content-length: 10
< content-type: text/html; charset=UTF-8
< 
10.0.0.17
* Connection #0 to host 10.0.0.7 left intact
* Closing connection #0
[root@centos6 ~]#curl -vb WEBSRV=web2 10.0.0.7
* About to connect() to 10.0.0.7 port 80 (#0)
*   Trying 10.0.0.7... connected
* Connected to 10.0.0.7 (10.0.0.7) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 
zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 10.0.0.7
> Accept: */*
> Cookie: WEBSRV=web2
> 
< HTTP/1.1 200 OK
< date: Thu, 02 Apr 2020 02:27:57 GMT
< server: Apache/2.4.6 (CentOS)
< last-modified: Thu, 02 Apr 2020 01:44:28 GMT
< etag: "a-5a244f0fd5175"
< accept-ranges: bytes
< content-length: 10
< content-type: text/html; charset=UTF-8
< 
10.0.0.27
* Connection #0 to host 10.0.0.7 left intact
* Closing connection #0

三. 实现自定义错误页面和https的实验

3.1 自定义错误页面

对指定的报错进行重定向,进行优雅的显示错误页面
使用errorfile和errorloc指令的两种方法,可以实现自定义各种错误页面

3.1.1 基于自定义的错误页面文件

#自定义错误页
errorfile <code> <file> 
<code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> #包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀为".http",以和一般的html文件相区#示例:
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http

范例:

defaults
#option forwardfor
#no option http-use-htx 支持html文件,此设置和版本有关,2.1不支持
#...... 
#加下面行
errorfile 500 /usr/local/haproxy/html/500.http
errorfile 502 /usr/local/haproxy/html/502.http
errorfile 503 /usr/local/haproxy/html/503.http

范例:

[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
errorfile 503 /apps/haproxy/html/503.http  
listen
.......
[root@centos7 ~]#vim /apps/haproxy/html/503.http 
HTTP/1.1 503 Service Unavailable
Content-Type:text/html;charset=utf-8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍候再试</h1></center>
<center><h2>联系电话:400-123-4567</h2></center>
<center><h3>503 Service Unavailable</h3></center>
</body>
[root@centos7 ~]#systemctl restart haproxy
#将后端服务器down,可以观察到以下页面

在这里插入图片描述
范例:启用 no option http-use-htx

[root@haproxy ~]#vi /etc/haproxy/haproxy.cfg 
defaults
   option http-keep-alive
   no option http-use-htx  #在defaults 块中添加
   errorfile 503 /apps/haproxy/errorfiles/503.html  
[root@haproxy ~]#cat /apps/haproxy/errorfiles/503.html 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍侯再试</h1></center>
<center><h2>联系电话:400-123-8888</h2></center>
<center><h3>503 Service Unavailable</h3></center>
</body>
#注意没有响应头信息
[root@internet ~]#curl -I 172.16.0.100
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍侯再试</h1></center>
<center><h2>联系电话:400-123-8888</h2></center>
<center><h3>503 Service Unavailable</h3></center>
</body>
#ubuntu的客户端提示错误
root@ubuntu2004:~# curl   172.16.0.100
curl: (1) Received HTTP/0.9 when not allowed

3.1.2 基于http重定向错误页面

#错误页面重定向
errorloc <code> <url>
#相当于errorloc302 <code> <url>,利用302重定向至指URL
#示例:
errorloc 503 http://www.wang.com/error_pages/503.html
errorloc 503 http://www.wang.com/

范例:

[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg
defaults
#option http-keep-alive
#option forwardfor
#no option http-use-htx
#...... 加以下一行
#errorfile 503 /apps/haproxy/html/503.http
errorloc 503 http://10.0.0.8/error_page/503.html
[root@centos8 ~]#cat /var/www/html/error_page/503.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍侯再试</h1></center>
<center><h2>联系电话:400-123-4567</h2></center>
<center><h3>503 Service Unavailable</h3></center>
</body>
#浏览器访问http://haproxy/ 302自动跳转至下面页面

在这里插入图片描述

3.2 https的实验

haproxy支持https,基于性能考虑,证书是在后端服务器比如nginx上实现,即用户到haproxy利用tcp模式再到后端服务器
范例: 基于tcp 模式实现

listen web_http                                                                 
                            
     bind 192.168.10.100:80
     redirect scheme https if !{ ssl_fc }
     mode http
     log global
     server web1  10.0.0.8:80 check
     server web2  10.0.0.18:80 check
listen web_https
     bind 192.168.10.100:443
     mode tcp
     log global
     server web1  10.0.0.8:443 check
     server web2  10.0.0.18:443 check

Haproxy 可以实现 Https 的证书安全,即从用户到haproxy为https,从haproxy到后端服务器用http通信

#配置HAProxy支持https协议,支持ssl会话;
 bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE 
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥 
 cat demo.key demo.crt > demo.pem 
#把80端口的请求利用302重向定443
 bind *:80
 redirect scheme https if !{ ssl_fc } 
#向后端传递用户请求的协议和端口(frontend或backend)
 http_request set-header X-Forwarded-Port %[dst_port]
 http_request add-header X-Forwared-Proto https if { ssl_fc }

3.2.1 证书制作

#方法1
[root@centos7 ~]mkdir /etc/haproxy/certs/
[root@centos7 ~]cd /etc/haproxy/certs/
[root@centos7 certs]#openssl genrsa -out haproxy.key 2048
[root@centos7 certs]#openssl req -new -x509 -key haproxy.key -out haproxy.crt 
-subj "/CN=www.wang.org"
#或者用下一条命令实现
[root@centos7 certs]#openssl req -x509 -newkey rsa:2048 -subj 
"/CN=www.wang.org" -keyout haproxy.key -nodes -days 365 -out haproxy.crt
[root@centos7 certs]#cat haproxy.key haproxy.crt > haproxy.pem
[root@centos7 certs]#openssl x509 -in haproxy.pem -noout -text #查看证书
#方法2
[root@centos7 ~]#mkdir /etc/haproxy/certs/
[root@centos7 ~]#cd /etc/pki/tls/certs
[root@centos7 certs]#make /etc/haproxy/certs/haproxy.pem 
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365
-out $PEM2 ; \
cat $PEM1 > /etc/haproxy/certs/haproxy.pem ; \
echo ""   >> /etc/haproxy/certs/haproxy.pem ; \
cat $PEM2 >> /etc/haproxy/certs/haproxy.pem ; \
rm -f $PEM1 $PEM2
Generating a 2048 bit RSA private key
.+++
..............................................+++
writing new private key to '/tmp/openssl.x8hOA8'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:wang
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:www.wang.org
Email Address []:
[root@centos7 certs]#ll /etc/haproxy/certs/
total 4
-rw------- 1 root root 3027 Apr  4 10:35 haproxy.pem

3.2.2 Https 配置示例

[root@centos7 ~]#cat /etc/haproxy/conf.d/test.cfg
frontend wang_http_port
 bind 10.0.0.7:80
###################### https setting ##############################  
 bind 10.0.0.7:443 ssl crt /etc/haproxy/certs/haproxy.pem
 redirect scheme https if !{ ssl_fc }        # 注意{ }内的空格
 http-request set-header X-forwarded-Port   %[dst_port]
 http-request add-header X-forwarded-Proto https if { ssl_fc } 
  
 mode http
 balance roundrobin
 log global
 option httplog
###################### acl setting ###############################
 acl mobile_domain hdr_dom(host)   -i mobile.wang.org
###################### acl hosts #################################
 default_backend pc_hosts 
################### backend hosts #################################
backend mobile_hosts
 mode http
 server web1 10.0.0.17:80 check inter 2000 fall 3 rise 5
backend pc_hosts
 mode http
  #http-request set-header X-forwarded-Port   %[dst_port] 也可加在此处
  #http-request add-header X-forwarded-Proto https if { ssl_fc } 
 server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
  
[root@centos7 ~]#ss -ntl
State     Recv-Q Send-Q         Local Address:Port   Peer Address:Port         
     
LISTEN     0      100                 127.0.0.1:25                 *:*           
       
LISTEN     0      128                  10.0.0.7:443               *:*           
       
LISTEN     0      128                         *:9999               *:*           
       
LISTEN     0      128                  10.0.0.7:80                 *:*           
       
LISTEN     0      128                         *:22                 *:*           
       
LISTEN     0      128                     [::]:22                 [::]:*

3.2.3 修改后端服务器的日志格式

[root@centos27 ~]#vim /etc/httpd/conf/httpd.conf 
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X
Forwarded-Port}i\" \"%{X-Forwarded-Proto}i\"" combined  
6.11.4 验证 Https

3.2.4 验证 Https

[root@centos6 ~]#curl -IkL http://www.wang.org
HTTP/1.1 302 Found
content-length: 0
location: https://www.wang.org/
cache-control: no-cache
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:31 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:13 GMT
etag: "a-5a244f01f8adc"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
[root@centos6 ~]#curl -Ik https://www.wang.org
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:50 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:28 GMT
etag: "a-5a244f0fd5175"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
#查看后端服务器的访问日志
[root@centos27 ~]#tail /var/log/httpd/access_log
10.0.0.7 - - [04/Apr/2020:10:40:17 +0800] "HEAD / HTTP/1.1" 200 - "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 
libidn/1.18 libssh2/1.4.2" "443" "https"

四. 画出2出架构图,写出3的关键点(重点配置)

在这里插入图片描述

五. 做题要求,每题首先使用脑图工具(亿图)画出原理架构图。

在这里插入图片描述

六. 完成keepalived的单播非抢占多主机高可用IP, 抢占邮件通知。

默认keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
在这里插入图片描述

6.1 vip单播配置

注意:启用 vrrp_strict 时,不能启用单播

#在所有节点vrrp_instance语句块中设置对方主机的IP,建议设置为专用于对应心跳线网络的地址,而非使
用业务网络
unicast_src_ip <IPADDR>  #指定发送单播的源IP
unicast_peer {
   <IPADDR>     #指定接收单播的对方目标主机IP
   ......
}

范例:

#master 主机配置
[root@ka1-centos8 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id ka1.wang.org
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_instance VI_1 {
   state MASTER
   interface eth0
   virtual_router_id 66
   priority 100
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 123456
   }
   virtual_ipaddress {
        10.0.0.10/24 dev eth0 label eth0:1
   }
   unicast_src_ip 10.0.0.8     #本机IP
   unicast_peer{
   10.0.0.18 #指向对方主机IP
   10.0.0.28 #如果有多个keepalived,再加其它节点的IP
   }
}
[root@ha1-centos8 ~]#hostname -I
10.0.0.8 10.0.0.10 
#slave 主机配置
[root@ka2-centos8 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id ka2.wang.org
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_instance VI_1 {
   state SLAVE
   interface eth0
   virtual_router_id 66
   priority 80
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 123456
   }
   virtual_ipaddress {
        10.0.0.10/24 dev eth0 label eth0:1
   }
   unicast_src_ip 10.0.0.18       #本机IP
   unicast_peer {
   10.0.0.8 #指向对方主机IP
   }
}
[root@ka2-centos8 ~]#hostname -I
10.0.0.18 

范例:抓包观察

root@centos6 ~]#tcpdump -i eth0 -nn src host 10.0.0.8 and dst host 10.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:37:48.069158 IP 10.0.0.8 > 10.0.0.18: VRRPv2, Advertisement, vrid 66, prio 
100, authtype simple, intvl 1s, length 20
23:37:49.070013 IP 10.0.0.8 > 10.0.0.18: VRRPv2, Advertisement, vrid 66, prio 
100, authtype simple, intvl 1s, length 20
23:37:50.071144 IP 10.0.0.8 > 10.0.0.18: VRRPv2, Advertisement, vrid 66, prio 
100, authtype simple, intvl 1s, length 20

6.2 Keepalived 通知脚本配置

当keepalived的状态变化时,可以自动触发脚本的执行,比如:发邮件通知用户
默认以用户keepalived_script身份执行脚本,如果此用户不存在,以root执行脚本可以用下面指令指定脚本执行用户的身份

global_defs {
 ......
 script_user <USER>
 ......
}

6.2.1 通知脚本类型

  • 当前节点成为主节点时触发的脚本
notify_master <STRING>|<QUOTED-STRING>
  • 当前节点转为备节点时触发的脚本

notify_backup |

  • 当前节点转为“失败”状态时触发的脚本

notify_fault |

  • 通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知

notify |

  • 当停止VRRP时触发的脚本

notify_stop |

6.2.2 脚本的调用方法

在 vrrp_instance VI_1 语句块的末尾加下面行

notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"

6.2.3 实战案例1:实现 Keepalived 状态切换的通知脚本

以下脚本支持RHEL和Ubuntu系统

#在所有 keepalived节点配置如下
[root@ka1 ~]#cat /etc/keepalived/notify.sh 
#!/bin/bash
#
#********************************************************************
#Author:           wangxiaochun
#QQ:               29308620
#Date:             2020-02-31
#FileName:         notify.sh
#URL:               http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2020 All rights reserved
#********************************************************************
contact='root@wangxiaochun.com'
email_send='29308620@qq.com'
email_passwd='dgezyimkdswwbhea'
email_smtp_server='smtp.qq.com'
. /etc/os-release
msg_error() {
  echo -e "\033[1;31m$1\033[0m"
}
msg_info() {
  echo -e "\033[1;32m$1\033[0m"
}
msg_warn() {
  echo -e "\033[1;33m$1\033[0m"
}
color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $" OK "    
    elif [ $2 = "failure" -o $2 = "1" ] ;then 
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo
}
install_sendemail () {
    if [[ $ID =~ rhel|centos|rocky ]];then
       rpm -q sendemail &> /dev/null || yum install -y sendemail
    elif [ $ID = 'ubuntu' ];then
       dpkg -l |grep -q sendemail || { apt update; apt install -y libio
socket-ssl-perl libnet-ssleay-perl sendemail ; } 
    else
       color "不支持此操作系统,退出!" 1
        exit
    fi
}
send_email () {
   local email_receive="$1"
   local email_subject="$2"
   local email_message="$3"
   sendemail -f $email_send -t $email_receive -u $email_subject -m
$email_message -s $email_smtp_server -o message-charset=utf-8 -o tls=yes -xu
$email_send -xp $email_passwd
   [ $? -eq 0 ] && color "邮件发送成功!" 0 || color "邮件发送失败!" 1
}
notify() {
    if [[ $1 =~ ^(master|backup|fault)$ ]];then
        mailsubject="$(hostname) to be $1, vip floating"
        mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be 
$1"
       send_email "$contact" "$mailsubject" "$mailbody"
   else
        echo "Usage: $(basename $0) {master|backup|fault}"
        exit 1
   fi
}
install_sendemail 
notify $1
[root@ka1 ~]#chmod a+x /etc/keepalived/notify.sh 
[root@ka1 ~]#vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
 ......
 virtual_ipaddress {
   10.0.0.10 dev eth0 label eth0:1
 }
 notify_master "/etc/keepalived/notify.sh master"
 notify_backup "/etc/keepalived/notify.sh backup"
 notify_fault "/etc/keepalived/notify.sh fault"
}
#模拟master故障
[root@ka1-centos8 ~]#killall keepalived

6.2.4 实战案例2:实现 Keepalived 状态切换的通知脚本

下面仅支持RHEL系统

6.2.4.1 邮件配置

案例:QQ邮箱配置

[root@centos8 ~]# vim /etc/mail.rc
#在最后面添加下面行
set from=29308620@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=29308620@qq.com
set smtp-auth-password=xxx
set smtp-auth=login
set ssl-verify=ignore

范例:163 邮箱配置

[root@centos8 ~]#vi /etc/mail.rc
set from=xxx@163.com #之前设置好的邮箱地址
set smtp=smtp.163.com #邮件服务器
set smtp-auth-user=xxx@163.com #之前设置好的邮箱地址
set smtp-auth-password=QXFIOQXEJNSVSDM #授权码
set smtp-auth=login #默认login即可

范例:发送测试邮件

[root@centos8 ~]# yum -y install mailx 
[root@centos8 ~]# echo "Test Mail"| mail -s Warning root@wangxiaochun.com

6.2.4.2 创建通知脚本

#在所有 keepalived节点配置如下
[root@ka1-centos8 ~]#cat /etc/keepalived/notify.sh 
#!/bin/bash
#
contact='root@wangxiaochun.com'
notify() {
 mailsubject="$(hostname) to be $1, vip floating"
 mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
 echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
 notify master
 ;;
backup)
 notify backup
 ;;
fault)
 notify fault
 ;;
*)
 echo "Usage: $(basename $0) {master|backup|fault}"
 exit 1
 ;;
esac
[root@ka1-centos8 ~]#chmod a+x /etc/keepalived/notify.sh 
[root@ka1-centos8 ~]#vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
 ......
 virtual_ipaddress {
   10.0.0.10 dev eth0 label eth0:1
 }
 notify_master "/etc/keepalived/notify.sh master"
 notify_backup "/etc/keepalived/notify.sh backup"
 notify_fault "/etc/keepalived/notify.sh fault"
}
#模拟master故障
[root@ka1-centos8 ~]#killall keepalived
查看邮箱收到邮件如下:

七. 完成lvs + keepalived 高可用配置

在这里插入图片描述

7.1 实战案例:实现单主的 LVS-DR 模式

准备web服务器并使用脚本绑定VIP至web服务器lo网卡

#准备两台后端RS主机
[root@rs1 ~]#cat lvs_dr_rs.sh
#!/bin/bash
#Author:wangxiaochun
#Date:2017-08-13
vip=10.0.0.10
mask='255.255.255.255'
dev=lo:1
rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
service httpd start &> /dev/null && echo "The httpd Server is Ready!"
echo "<h1>`hostname`</h1>" > /var/www/html/index.html
case $1 in
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
   ifconfig $dev $vip netmask $mask #broadcast $vip up
    #route add -host $vip dev $dev
    echo "The RS Server is Ready!"
   ;;
stop)
   ifconfig $dev down
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    echo "The RS Server is Canceled!"
   ;;
*) 
    echo "Usage: $(basename $0) start|stop"
    exit 1
   ;;
esac
[root@rs1 ~]#bash lvs_dr_rs.sh start 
The httpd Server is Ready!
The RS Server is Ready!
[root@rs1 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group 
default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
   inet 10.0.0.10/32 scope global lo:1
       valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP 
group default qlen 1000
   link/ether 00:0c:29:32:80:38 brd ff:ff:ff:ff:ff:ff
   inet 10.0.0.7/24 brd 10.0.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
   inet6 fe80::20c:29ff:fe32:8038/64 scope link 
       valid_lft forever preferred_lft forever
[root@rs2 ~]#bash lvs_dr_rs.sh start 
The httpd Server is Ready!
The RS Server is Ready!
[root@rs2 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group 
default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
   inet 10.0.0.10/32 scope global lo:1
       valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP 
group default qlen 1000
   link/ether 00:0c:29:33:b4:1a brd ff:ff:ff:ff:ff:ff
   inet 10.0.0.17/24 brd 10.0.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
   inet6 fe80::20c:29ff:fe33:b41a/64 scope link 
       valid_lft forever preferred_lft forever
#测试直接访问两台RS
[root@centos6 ~]#curl 10.0.0.7
<h1>rs1.wang.org</h1>
[root@centos6 ~]#curl 10.0.0.17
<h1>rs2.wang.org</h1>

配置keepalived

#ka1节点的配置
[root@ka1-centos8 ~]#cat   /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalived@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id ka1.wang.org
 vrrp_mcast_group4 224.0.100.10
 }
vrrp_instance VI_1 {
 state MASTER
 interface eth0
 virtual_router_id 66
 priority 100
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 123456
 }
 virtual_ipaddress {
 10.0.0.10/24 dev eth0 label eth0:1
 }
 notify_master "/etc/keepalived/notify.sh master"
 notify_backup "/etc/keepalived/notify.sh backup"
 notify_fault "/etc/keepalived/notify.sh fault"
   }
virtual_server 10.0.0.10 80 {
 delay_loop 3
 lb_algo rr
 lb_kind DR
 protocol TCP
 sorry_server 127.0.0.1 80
 real_server 10.0.0.7 80 {
 weight 1
 HTTP_GET {               #应用层检测
 url {
 path /
 status_code 200
 }
 connect_timeout 1
 nb_get_retry 3
 delay_before_retry 1
 }
 }
 real_server 10.0.0.17 80 {
 weight 1
       TCP_CHECK {              #另一台主机使用TCP检测
       connect_timeout 5
       nb_get_retry 3
       delay_before_retry 3
             connect_port 80
 }
   }
}
#ka2节点的配置,配置和ka1基本相同,只需修改三行
[root@ka2-centos8 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalived@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id ka1.wang.org             #修改此行
 vrrp_mcast_group4 224.0.100.10
 }
vrrp_instance VI_1 {
 state BACKUP #修改此行
 interface eth0
 virtual_router_id 66
 priority 80 #修改此行
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 123456
 }
 virtual_ipaddress {
 10.0.0.10/24 dev eth0 label eth0:1
 }
 notify_master "/etc/keepalived/notify.sh master"
 notify_backup "/etc/keepalived/notify.sh backup"
 notify_fault "/etc/keepalived/notify.sh fault"
   }
virtual_server 10.0.0.10 80 {
 delay_loop 3
 lb_algo rr
 lb_kind DR
 protocol TCP
 sorry_server 127.0.0.1 80
 real_server 10.0.0.7 80 {
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 1
 nb_get_retry 3
 delay_before_retry 1
 }
 }
 real_server 10.0.0.17 80 {
 weight 1
       TCP_CHECK {
       connect_timeout 5
       nb_get_retry 3
       delay_before_retry 3
             connect_port 80
 }
   }
}

访问测试结果

[root@centos6 ~]#curl 10.0.0.10
<h1>rs1.wang.org</h1>
[root@centos6 ~]#curl 10.0.0.10
<h1>rs2.wang.org</h1>
[root@ka1-centos8 ~]#dnf -y install ipvsadm
[root@ka1-centos8 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.10:80 rr
  -> 10.0.0.7:80                 Route   1      0          0         
  -> 10.0.0.17:80                 Route   1      0          0 

模拟故障

#第一台RS1故障,自动切换至RS2
[root@rs1 ~]#chmod 0 /var/www/html/index.html 
[root@centos6 ~]#curl 10.0.0.10
<h1>rs2.wang.org</h1>
[root@centos6 ~]#curl 10.0.0.10
<h1>rs2.wang.org</h1>
[root@ka1-centos8 ~]#dnf -y install ipvsadm
[root@ka1-centos8 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.10:80 rr
  -> 10.0.0.17:80                 Route   1      0          3  
#后端RS服务器都故障,启动Sorry Server
[root@rs2 ~]#systemctl stop httpd
[root@centos6 ~]#curl 10.0.0.10
Sorry Server on ka1
[root@ka1-centos8 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.10:80 rr
  -> 127.0.0.1:80                 Route   1      0          0  
#ka1故障,自动切换至ka2
[root@ka1-centos8 ~]#killall keepalived
[root@centos6 ~]#curl 10.0.0.10
Sorry Server on ka2
#恢复都有后端 RS
[root@rs1 ~]#chmod 644 /var/www/html/index.html
[root@rs2 ~]#systemctl start httpd
[root@centos6 ~]#curl 10.0.0.10
<h1>rs1.wang.org</h1>
[root@centos6 ~]#curl 10.0.0.10
<h1>rs2.wang.org</h1>
[root@ka1-centos8 ~]#hostname -I
10.0.0.8 
[root@ka2-centos8 ~]#hostname -I
10.0.0.18 10.0.0.10 
#恢复ka1服务器,又抢占回原来的VIP
[root@ka1-centos8 ~]#systemctl start keepalived.service 
[root@ka1-centos8 ~]#hostname -I
10.0.0.8 10.0.0.10 
[root@ka2-centos8 ~]#hostname -I
10.0.0.18 
[root@centos6 ~]#curl 10.0.0.10
<h1>rs1.wang.org</h1>
[root@centos6 ~]#curl 10.0.0.10
<h1>rs2.wang.org</h1>

7.2 实战案例:实现双主的 LVS-DR 模式

在这里插入图片描述

[root@ka1-centos8 ~]#vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from keepalived@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id ka1.wang.org   #另一个节点为ka2.wang.org
 vrrp_mcast_group4 224.0.100.10
 }
 
vrrp_instance VI_1 {
 state MASTER     #在另一个结点上为BACKUP
 interface eth0
 virtual_router_id 66
 priority 100         #在另一个结点上为80
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 123456
 }
 virtual_ipaddress {
 10.0.0.10/24 dev eth0 label eth0:1 #指定VIP
 }
}
vrrp_instance VI_2 {
 state BACKUP     #在另一个结点上为MASTER
 interface eth0
 virtual_router_id  88
 priority 80         #在另一个结点上为100
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 123456
 }
 virtual_ipaddress {
 10.0.0.20/24 dev eth0 label eth0:2 #指定VIP2
 }
}
virtual_server 10.0.0.10 80 {  
 delay_loop 6
 lb_algo rr
 lb_kind DR
 protocol TCP
 sorry_server 127.0.0.1 80
 real_server 10.0.0.7 80 {  #指定RS1地址
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 3
 nb_get_retry 3
 delay_before_retry 3
 }
 }
 real_server 10.0.0.17 80 {   #指定RS2地址
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 3
 nb_get_retry 3
 delay_before_retry 3
 }
 } 
}
virtual_server 10.0.0.20 80 { #指定VIP2
 delay_loop 6
 lb_algo rr
 lb_kind DR
 protocol TCP
 sorry_server 127.0.0.1 80
 real_server 10.0.0.27 80 { #指定RS3地址
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 3
 nb_get_retry 3
 delay_before_retry 3
 }
 }
 real_server 10.0.0.37 80 {   #指定RS4地址
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 3
 nb_get_retry 3
 delay_before_retry 3
 }
 } 
}

范例: 双主分别实现httpd和mysql服务的调度
在这里插入图片描述

[root@ka1 conf.d]#cat web1.conf 
vrrp_instance web1 {
   state MASTER
   interface eth0
   virtual_router_id 66
   priority 100
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 123456
   }
   virtual_ipaddress {
 10.0.0.100/24 dev eth0 label eth0:100
   }
 notify_master "/etc/keepalived/notify.sh master"                             
                                                     
   notify_backup "/etc/keepalived/notify.sh backup"
   notify_fault "/etc/keepalived/notify.sh fault"
}
[root@ka1 conf.d]#cat lvs_.conf 
lvs_mysql.conf lvs_web1.conf   
[root@ka1 conf.d]#cat lvs_web1.conf 
virtual_server 10.0.0.100 80 {
 delay_loop 3
 lb_algo rr
 lb_kind DR
 protocol TCP
 sorry_server 127.0.0.1 80
 real_server 10.0.0.7 80 {
 weight 1
 HTTP_GET {
 url {
 path /monitor.html
 status_code 200
 }
 connect_timeout 1
 nb_get_retry 3
 delay_before_retry 1
 }
 }
 real_server 10.0.0.17 80 {
 weight 1
       TCP_CHECK {
       connect_timeout 5
       nb_get_retry 3
       delay_before_retry 3
             connect_port 80
 }
   }
}
[root@ka1 conf.d]#cat mysql_vip.conf
vrrp_instance mysql{
   state BACKUP
   interface eth0
   virtual_router_id 88
   priority 80
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 123456
   }
   virtual_ipaddress {
 10.0.0.200/24 dev eth0 label eth0:200
   }
}
[root@ka1 conf.d]#cat lvs_mysql.conf
virtual_server 10.0.0.200 3306 {
 delay_loop 3
 lb_algo rr
 lb_kind DR
 protocol TCP
 real_server 10.0.0.7 3306 {
 weight 1
 TCP_CHECK {
 connect_timeout 5
 nb_get_retry 3
 delay_before_retry 3
             connect_port 3306
 }
 }
 real_server 10.0.0.17 3306 {
 weight 1
       TCP_CHECK {
       connect_timeout 5
       nb_get_retry 3
       delay_before_retry 3
             connect_port 3306
 }
   }
}
#注意:在后端服务器要实现两个VIP的配置
[root@web1 ~]#ip a show lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group 
default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
   inet 10.0.0.100/32 scope global lo:1
       valid_lft forever preferred_lft forever
   inet 10.0.0.200/32 scope global lo:2
       valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
       
       
[root@ka1 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.100:80 rr
  -> 10.0.0.7:80                 Route   1      0          0         
  -> 10.0.0.17:80                 Route   1      0          0         
TCP  10.0.0.200:3306 rr
  -> 10.0.0.7:3306               Route   1      0          0         
  -> 10.0.0.17:3306               Route   1      0          0    
  
  
#测试
[root@client ~]#while true;do mysql -utest -p123456 -h10.0.0.200 -e 'show 
variables like "%hostname%"';curl 10.0.0.100;sleep 0.5;done
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| hostname     | web1.wang.org |
+---------------+-----------------+
10.0.0.17 
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| hostname     | web2.wang.org |
+---------------+-----------------+
10.0.0.7 

7.3 实战案例:实现单主的 LVS-DR 模式,利用FWM绑定成多个服务为一个集群服务

参考文档: 注意有bug

/usr/share/doc/keepalived/keepalived.conf.fwmark

范例:

#两个节点都执行以下操作
[root@ka1-centos8 ~]#iptables -t mangle -A PREROUTING -d 10.0.0.10   -p tcp -m 
multiport --dports 80,443 -j MARK --set-mark 6
[root@ka1-centos8 ~]#vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 global_defs {
 notification_email {
 root@localhost
 }
 notification_email_from kaadmin@localhost
 smtp_server 127.0.0.1
 smtp_connect_timeout 30
 router_id ka1.wang.org #在另一个节点为ka2.wang.org
 vrrp_mcast_group4 224.100.100.100
 }
 
vrrp_instance VI_1 {
 state MASTER #在另一个节点为BACKUP
 interface eth0
 virtual_router_id 66
 priority 100 #在另一个节点为80
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 123456
 }
 virtual_ipaddress {
 10.0.0.10/24 dev eth0 label eth0:1
 }
 track_interface {
 eth0
 }
 notify_master "/etc/keepalived/notify.sh master"
 notify_backup "/etc/keepalived/notify.sh backup"
 notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server fwmark 6 {   #指定FWM为6 
 delay_loop 2
 lb_algo rr
 lb_kind DR
 sorry_server 127.0.0.1 80  #注意端口必须指定
 real_server 10.0.0.7 80 {  #注意端口必须指定
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 2
 nb_get_retry 3
 delay_before_retry 3
 }
 }
 real_server 10.0.0.17 80 { #注意端口必须指定
 weight 1
 HTTP_GET {
 url {
 path /
 status_code 200
 }
 connect_timeout 2
 nb_get_retry 3
 delay_before_retry 3
 }
 }
}
#在RS1和RS2运行下面脚本
[root@rs1 ~]#cat lvs_dr_rs.sh 
#!/bin/bash
#Author:wangxiaochun
#Date:2017-08-13
vip=10.0.0.10
vip2=10.0.0.20
mask='255.255.255.255'
dev=lo:1
dev2=lo:2
rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
service httpd start &> /dev/null && echo "The httpd Server is Ready!"
echo "<h1>`hostname`</h1>" > /var/www/html/index.html
case $1 in
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
   ifconfig $dev $vip netmask $mask #broadcast $vip up
   ifconfig $dev2 $vip2 netmask $mask #broadcast $vip up
    #route add -host $vip dev $dev
    echo "The RS Server is Ready!"
   ;;
stop)
   ifconfig $dev down
   ifconfig $dev2 down
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    echo "The RS Server is Canceled!"
   ;;
*) 
    echo "Usage: $(basename $0) start|stop"
    exit 1
   ;;
esac
[root@rs1 ~]#bash lvs_dr_rs.sh start
[root@rs2 ~]#bash lvs_dr_rs.sh start
#访问测试
[root@centos6 ~]#curl 10.0.0.10;curl -k https://10.0.0.20
<h1>rs1.wang.org</h1>
<h1>rs2.wang.org</h1>

八. 完成lvs + nginx 高可用配置

在这里插入图片描述

#!/bin/bash
VIP=172.20.36.222
case "$1" in
start)
       /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
       /sbin/route add -host $VIP dev lo:0
       echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
       sysctl -p >/dev/null 2>&1
       echo "RealServer Start OK"
       ;;
stop)
       /sbin/ifconfig lo:0 down
       /sbin/route del $VIP >/dev/null 2>&1
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
       echo "RealServer Stoped"
       ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac
exit 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/167039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】【Pytorch】12.损失函数与反向传播

【学习笔记】【Pytorch】12.损失函数与反向传播一、损失函数的介绍1.L1Loss类的使用代码实现2.MSELoss类的使用3.损失函数在模型中的实现二、反向传播一、损失函数的介绍 参考&#xff1a; 损失函数&#xff08;loss function&#xff09; pytorch loss-functions 文档 作用&…

【JavaEE】基于TCP的客户端服务器程序

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【JavaEE】 ✈️✈️本篇内容:基于TCP的客户端服务器程序。 &#x1f680;&#x1f680;代码存放仓库gitee&#xff1a;JavaEE初阶代码存放&#xff01; ⛵⛵作者…

【JavaEE初阶】第二节.进程篇

文章目录 前言 一、操作系统 二、进程 2.1 进程的概念 2.2 进程的管理​​​​​​​​​​​​​​ 2.3 PCB 2.3.1 PCB里面的一些属性 2.3.2 进程的调度 2.3.3 进程的虚拟地址空间 2.3.4 进程间通信 总结 前言 本节内容我们继续对JavaEE的有关内容进行学习&#xff0c;…

汽车智能化,集度做加法

CES2023刚刚落下帷幕&#xff0c;这场名为“国际消费电子展”的业界盛会&#xff0c;近几年重心正明显转向智能汽车及其周边产业链。在2022年的CES上&#xff0c;集度与英伟达宣布合作&#xff0c;也透露了智能汽车研发的相关计划。而在本届CES之前、2022年末的广州车展上&…

一个关于image访问图片跨域的问题

一、背景 项目中遇到一个问题&#xff0c;同一个图片在 dom 节点中使用了 img 标签来加载&#xff0c;同时由于项目使用了 ThreeJS 3D 渲染引擎&#xff0c;在加载纹理时使用了 TextureLoader 来加载了同一张图片&#xff0c;而由于图片是在阿里云服务器上的&#xff0c;所以最…

SourceTree 拉取、重置提交、回滚、变基与合并

SourceTree的重置当前分支到此次提交 使用场景&#xff1a;“我想把已提交未推送的修改撤销” 使用模式说明软合并软合并是指将此次提交回滚到指定提交位置&#xff0c;但这个过程中会将修改过的文件暂存到暂存区。混合合并混合合并是指将此次提交回滚到指定的位置&#xff0c…

本来挺喜欢刷《剑指offer》的.......(第十一天)

跟着博主一起刷题 这里使用的是题库&#xff1a; https://leetcode.cn/problem-list/xb9nqhhg/?page1 目录剑指 Offer 66. 构建乘积数组剑指 Offer 68 - I. 二叉搜索树的最近公共祖先剑指 Offer 68 - II. 二叉树的最近公共祖先剑指 Offer 66. 构建乘积数组 剑指 Offer 66. 构建…

使用react-bmapgl绘制区域并判断是否重叠

需求如下&#xff1a; 在react项目中使用百度地图实现区域&#xff08;电子围栏&#xff09;的绘制绘制的区域类型为&#xff1a;1、多边形 2、圆形可绘制多个区域区域不能有重叠可重新编辑区域 代码如下: index.tsx import { useCallback, useEffect, useState } from rea…

Python入门实践(二)——变量的使用

文章目录变量1、变量的命名和使用1.1、避免命名错误2、字符串2.1、修改字符串大小写2.2、合并&#xff08;拼接&#xff09;字符串2.3、使用制表符或换行符来添加空白2.4、删除空白3、数字3.1、整数3.2、浮点数3.3、使用str()避免类型错误4、注释变量是对一种数据结构的命名&am…

2023年基建工程(设计规划施工)经验分享,超多干货

为了彻底打通从工程外业勘探调查、数据资料整理&#xff0c;到内业详细设计之间的一系列障碍&#xff0c;结合工程外业调查的特点&#xff0c;基于安卓&#xff08;Android&#xff09;操作系统&#xff0c;精心打磨推出了“外业精灵”移动端应用软件。 该系统把工程外业探勘、…

MPP数据库简介及架构分析

目录什么是MPP&#xff1f;特性并行处理超大规模数据仓库真正适合什么典型的分析工作量数据集中化线性可伸缩性MPP架构技术特性数据库架构分析Shared EverythingShared DiskShare MemoryShared NothingShared Nothing数据库架构优势什么是MPP&#xff1f; MPP (Massively Paral…

分享88个C源码,总有一款适合您

C源码 分享88个C源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后可以看到。 源码下载链接&#xff1a;https://pan.baidu.com/s/1TT87gt66kn5BtLqgRUTlUQ?pwdwje5 提取码…

Java图形化界面---JOptionPane

目录 一、JOptionPane的介绍 二、JOptionalPane的使用 &#xff08;1&#xff09;消息对话框 &#xff08;2&#xff09; 确认对话框 &#xff08;3&#xff09;输入对话框 &#xff08;4&#xff09;选项对话框 一、JOptionPane的介绍 通过JOptionPane可以非常方便地创建…

SpringCloud复习之Sleuth+Zipkin链路追踪实战

文章目录写作背景为什么要有链路监控SpringCloud SleuthZipkin能做什么上手实战启动一个Zipkin Server微服务集成SleuthZipkin写作背景 前面复习了SpringCloud Netflix的几个核心组件&#xff0c;包括Eureka、Ribbon、Feign、Hystrix、Zuul&#xff0c;并进行了Demo级别的实战…

高精度减法【c++】超详细讲解

前言 大家学过高精度加法之后&#xff0c;可能已经知道高精度减法的实现方法了吧 如果你还没有学过高精度加法的话&#xff0c;请点击这里&#xff08;很详细的&#xff09;—>高精度加法【C实现】详解 最大的问题 最大的问题莫过于负数问题了。其他方法和加法一样。 负…

4.二级缓存解析

文章目录1. 二级缓存配置2. 二级缓存结构3. 二级缓存命中条件4. 缓存空间的理解5. 二级缓存执行流程二级缓存也称作是应用级缓存&#xff0c;与一级缓存不同的&#xff0c;是它的作用范围是整个应用&#xff0c;而且可以跨线程使用。所以二级缓存有更高的命中率&#xff0c;适合…

从南丁格尔图到医学发展史

可视化中&#xff0c;前端用于表现不同类目的数据在总和中的占比的场景&#xff0c;往往会采用饼图。 针对数据大小相近&#xff0c;南丁格尔图的呈现会更加美观。 南丁格尔图&#xff0c;又称玫瑰图&#xff0c;是由弗罗伦斯南丁格尔发明。 弗洛伦斯南丁格尔 开创了护理事业…

二、django中的路由系统

django中的路由系统 django中路由的作用和路由器类似&#xff0c;当一个用户请求Django站点的一个页面时&#xff0c;是路由系统通过对url的路径部分进行匹配&#xff0c;一旦匹配成功就导入并执行对应的视图来返回响应。 django如何处理请求 当一个请求来到时&#xff0c;d…

SpringSecurityOauth2架构Demo笔记

总体分为SpringSecurityOauth2授权码模式演示和密码模式演示 一直下一步,依赖手动导入,SpringBoot版本改成2.2.5.RELEASE,JDK版本1.8 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xml…

Open3D 点云投影至指定球面(Python版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 假设球体的相关参数:中心为 C ( x c , y c , z c ) C(x_c,y_c,z_c)