LVS+Keepalived+Nginx+ web 四七层负载及高可用集群构建

你要知道现在公司一般的架构都是F5(LVS)+keepalived + nginx + app + DB。 那么为什么不用keepalived + nginx + app + DB 这种架构模式呢?

在keepalived+nginx的主备容灾高可用的架构中,nginx是作为外部访问系统的唯一入口,理论上一台nginx的最大并发量可以高达50000,但是当并发量更大的时候,keepalived+nginx的高可用机制是没办法满足需求的,因为keepalived+nginx的架构中确确实实是一台nginx在工作,只有当master宕机或异常的时候,备份机才会上位。那么如何解决更大的高并发问题呢,也许你会问能不能搭建nginx集群,直接对外提供访问?很显然这是欠妥当的,因为当nginx作为外部的唯一访问入口,没办法直接以集群的形式对外提供服务,没有那么多的公网ip资源可用,既太浪费也不友好。但是在内网环境下,是可以用nginx集群(nginx横向扩展服务集合)的,当然总得有一个对外入口,所以需要在nginx集群之上,在加一层负载均衡器LVS,作为系统的唯一入口。

废话不多说, 我们开始搭建LVS(DR模式)+Keepalived+Nginx+ web 集群吧。

首先我们看一下今天要搭建的集群的基本架构拓扑图, 便于你的理解:

image

然后我们开始真正的集群构建。

一、准备工作

准备:至少6台虚拟机,用于测试。
(当然在实际工作环境中, nginx 服务器是可以横向扩展的, 你可以创建多台nginx服务器。web 服务器也是可以横向扩展的, 你可以创建多台web服务器。)
系统版本:CentOS 7

| 主机名 | IP | 作用 |
| 无 | 192.168.93.200 | 虚拟IP(VIP) |
| lvskeepalived1 | 192.168.93.100 | LVS+ Keepalived Master (LVS将请求负载至nginx1 或者 nginx2) |
| lvskeepalived2 | 192.168.93.101 | LVS+ Keepalived Backup (lvskeepalived1的备机) |
| nginx1 | 192.168.93.110 | Nginx1(将请求负载至后端web1 或者 web2) |
| nginx2 | 192.168.93.111 | Nginx2(将请求负载至后端web1 或者 web2) |
| web1 | 192.168.93.210 | Web1(静态web服务器) |
| web2 | 192.168.93.211 | Web2(静态web服务器) |

二、安装软件及配置

1. 在lvskeepalived1 和 lvskeepalived2 机器上面安装 ipvsadm 和 keepalived:

yum -y install ipvsadm keepalived

查看两台负载均衡机器是否支持lvs:

lsmod |grep ip_vs
image

如果上述命令没有任何结果,则执行ipvsadm命令启动ipvs之后,再通过上述命令进行查看即可。

2. 在nginx1 和 nginx2 机器上面安装nginx

yum -y install nginx

3. 在web1 和 web2 上面安装apache

yum -y install httpd

配置网页:

实际配置网页内容应该一样,但是为了演示nginx负载均衡效果,我们将网页内容一个配置成web1, 一个配置成web2。

#在web1配置如下:
cd /var/www/html
echo "web1" > index.html
systemctl restart httpd

#在web2配置如下:
cd /var/www/html
echo "web2" > index.html
systemctl restart httpd

4. 配置keepalived
1)在lvskeepalived1也就是master 机器上面配置:

vim /etc/keepalived/keepalived.conf
# Global Configuration
global_defs {
lvs_id director1  # 指定lvs的id
}
# VRRP Configuration
vrrp_instance LVS {
state MASTER    # 指定当前节点为master节点
interface ens33    # 这里是网卡的名称,通过ifconfig或者ip addr可以查看
virtual_router_id 51    # 这里指定的是虚拟路由id,master节点和backup节点需要指定一样的
priority 151    # 指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点
advert_int 1    # 指定发送VRRP通告的间隔,单位是秒
authentication {
auth_type PASS    # 鉴权,默认通过
auth_pass 123456    # 鉴权访问密码
}

virtual_ipaddress {
192.168.93.200    # 指定了虚拟ip
}

}

# Virtual Server Configuration - for www server
# 后台真实主机的配置
virtual_server 192.168.93.200 80 {
delay_loop 1    # 健康检查的时间间隔
lb_algo rr    # 负载均衡策略,这里是轮询
lb_kind DR    # 调度器类型,这里是DR
persistence_time 1    # 指定了持续将请求打到同一台真实主机的时间长度
protocol TCP    # 指定了访问后台真实主机的协议类型

  # Real Server 1 configuration
  # 指定了真实主机1的ip和端口 , 也就是Nginx1的IP和端口
real_server 192.168.93.110 80 {
weight 1    # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10    # 指定了进行心跳检查的超时时间
nb_get_retry 3    # 指定了心跳超时之后的重复次数
delay_before_retry 3    # 指定了在尝试之前延迟多长时间
}
}

  # Real Server 2 Configuration
  # 指定了真实主机2的ip和端口 , 也就是Nginx2的IP和端口
real_server 192.168.93.111 80 {
weight 1    # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10    # 指定了进行心跳检查的超时时间
nb_get_retry 3    # 指定了心跳超时之后的重复次数
delay_before_retry 3    # 指定了在尝试之前延迟多长时间
}
}
}

2)在lvskeepalived2也就是backup 机器上面配置keepalived:
只和master 有以下三处不同:
lvs_id director1 改成 lvs_id director2
state MASTER 改成 state BACKUP
priority 151 改成 priority 101

vim /etc/keepalived/keepalived.conf
# Global Configuration
global_defs {
lvs_id director2  # 指定lvs的id
}

# VRRP Configuration
vrrp_instance LVS {
state BACKUP # 指定当前节点为master节点
interface ens33    # 这里是网卡的名称,通过ifconfig或者ip addr可以查看
  virtual_router_id 101    # 这里指定的是虚拟路由id,master节点和backup节点需要指定一样的
priority 101    # 指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点
advert_int 1    # 指定发送VRRP通告的间隔,单位是秒
authentication {
auth_type PASS    # 鉴权,默认通过
auth_pass 123456    # 鉴权访问密码
}

virtual_ipaddress {
192.168.93.200    # 指定了虚拟ip
}

}

# Virtual Server Configuration - for www server
# 后台真实主机的配置
virtual_server 192.168.93.200 80 {
delay_loop 1    # 健康检查的时间间隔
lb_algo rr    # 负载均衡策略,这里是轮询
lb_kind DR    # 调度器类型,这里是DR
persistence_time 1    # 指定了持续将请求打到同一台真实主机的时间长度
protocol TCP    # 指定了访问后台真实主机的协议类型

  # Real Server 1 configuration
  # 指定了真实主机1的ip和端口 , 也就是Nginx1的IP和端口
real_server 192.168.93.110 80 {
weight 1    # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10    # 指定了进行心跳检查的超时时间
nb_get_retry 3    # 指定了心跳超时之后的重复次数
delay_before_retry 3    # 指定了在尝试之前延迟多长时间
}
}

  # Real Server 2 Configuration
  # 指定了真实主机2的ip和端口 , 也就是Nginx2的IP和端口
real_server 192.168.93.111 80 {
weight 1    # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10    # 指定了进行心跳检查的超时时间
nb_get_retry 3    # 指定了心跳超时之后的重复次数
delay_before_retry 3    # 指定了在尝试之前延迟多长时间
}
}
}

5. 配置Nginx
1)在nginx1 和 nginx2 机器上面配置负载均衡:(两台机器一模一样的配置)
实现将访问本机80端口的请求轮询定向到后端的两台apache服务器:
我们这里只演示两台apache web 服务器, 你也可以配置多台。

vim /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log  main;
sendfile            on;
tcp_nopush          on;
tcp_nodelay         on;
keepalive_timeout   65;
types_hash_max_size 2048;
include             /etc/nginx/mime.types;
default_type        application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

upstream serverList {
server 192.168.93.210:80;  #web server1,后端真实服务器
server 192.168.93.211:80;  #web server2,后端真实服务器
    }

server {
listen 80;
#server_name  localhost; # server_name:是客户端请求的域名地址
#root   html;
#index  index.html index.htm index.php;
location / {
proxy_pass  http://serverList; # 指向负载的列表的模块,如serverList
proxy_redirect     off;
proxy_set_header   Host             $host;
    }
    }

}

2)在nginx1 和 nginx2 机器上面配置虚拟IP: (两台nginx机器, 一模一样的配置)
因为我们使用的lvs调度器是DR模式,前面我们讲到过,这种模式下,对客户端的响应是真实服务器直接返回给客户端的,而真实服务器需要将响应报文中的源ip修改为虚拟ip,这里配置的虚拟ip就是起这个作用的。我们编辑/etc/init.d/lvsrs文件,写入如下内容:

[root@nginx1 nginx]# cd /etc/init.d/
[root@nginx1 init.d]# vim lvsrs
#虚拟的vip 根据自己的实际情况定义
SNS_VIP=192.168.93.200
/etc/rc.d/init.d/functions
case "$1" in
start)
       ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
       /sbin/route add -host $SNS_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)
       ifconfig lo:0 down
       route del $SNS_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

然后更改脚本权限并执行脚本:(两台nginx机器都要执行)

[root@nginx1 init.d]# chmod 755 lvsrs
[root@nginx1 init.d]# ./lvsrs start
image
image

查看ip lo:0 和路由是否添加成功:

image
image
image
image

如果可以看到上述结果,证明 lo:0和路由都已经配置成功。

三、测试

1. 启动Nginx 服务, 验证Nginx负载功能
systemctl start nginx
systemctl enable nginx

测试分别访问nginx1和nginx2的网页, 可以看到请求轮询定向到后端的两台web服务器上, 所以Nginx 负载功能验证成功。

while [ TRUR ]; do curl http://192.168.93.110:80; sleep 2 ; done

image

while [ TRUR ]; do curl http://192.168.93.111:80; sleep 2 ; done

image
2. 启动keepalived

在lvskeepalived1 和 lvskeepalived2 服务器上启动keepalived.

systemctl start keepalived
systemctl enable keepalived

过几秒后可以看到VIP(192.168.93.200) 在master 机器上面:

image
image

通过VIP访问网页:

image
image

访问成功, 可见LVS 成功将请求转发到了后端web server 上。

3. KeepAlived高可用测试
  • 停掉主keepalived:
image

vip漂移至备服务器:

image

此时网页访问:192.168.93.200依然能够正常访问,分发依然正常:

image
image
  • 重启主keepalived

主服务恢复之后;vip又会自动漂移回主服务

image

至此, keepalived 高可用验证成功。

4. LVS监控真实服务测试
  • 查看最新的虚拟ip对应的RealServer的情况
    VIP:192.168.93.200
    Realserver1 IP: 192.168.93.110
    Realserver2 IP: 192.168.93.111
image

可以看出192.168.93.110和192.168.93.111两台真实服务器都还在

  • 访问VIP并使用ipvsadm -lnc查看请求转发情况
    看到lvs将请求转发到110 和 111 两台真实服务器上:
image
  • 测试停掉192.168.93.110的nginx 服务
image
  • 再次查看虚拟ip对应的RealServer的情况
    可以看出192.168.93.110这台已经挂掉的服务器已经被移除了
image
  • 测试访问虚拟ip
image

可以看到网页访问正常。
使用ipvsadm -lnc 查看请求转发情况:
可以看到所有的访问都只会转发到192.168.93.111的真实服务器上

image
  • 恢复192.168.93.110
    lvs又会自动监控并加入192.168.93.110
image
image

至此,验证了LVS 可以监控真实服务器的服务的状态。

通过验证, 我们今天的LVS+Keepalived+Nginx+ web 集群搭建成功!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342