一、Nginx+keepalived主从热备模式

该模式,使用1个vip地址,1个公网IP地址,2台ECS机器,1台做主,1台做备,但同时只有1台机器工作,另一台备份机器在主机器不出现故障的时候,永远处于浪费状态。此模式仅起到一个热备避免单点故障效果,没能起到负载效果,比较浪费服务器资源。

该模式如下:

image.png

1.1、测试配置环境如下:

一、2台华为云ECS云主机(centos 8.2),2台ECS云主机均有内网IP和弹性公网IP,2台ECS主机上均安装nginx和keepalived。

  1. azhi-03,内网IP:192.168.0.72,弹性公网IP:124.71.xx.203
  2. azhi-05,内网IP:192.168.0.166,弹性公网IP:139.9.xx.215
  3. 注意,这里的两个弹性公网IP已经绑定在ECS云主机上了,我们平常ssh远程进去操作linux系统用的就是这个弹性公网IP,华为云中绑定了ecs实例的弹性公网IP就不能再用于绑定映射虚拟IP了。

    二、1个独立的弹性公网IP,我们一般是访问一个公网的IP,然后由这个公网IP映射到keepalived的vip上。弹性公网IP价格也很便宜,华为云上购买流程如下:

  4. 登录管理控制台。

  5. 选择“服务列表 > 网络 > 弹性公网IP”。
  6. 单击“购买弹性公网IP”,根据界面提示配置参数。

image.png
因为我有多台ECS主机(均有弹性公网IP),所以我这里就从ECS主机上解绑了一个弹性公网IP(139.9.xx.185)出来当作测试用了,如果自己没有的话可以选择购买。
image.png
三、1个虚拟IP,虚拟IP用于keepalived配置中的vip,虚拟IP可以在华为云控制台上创建,流程如下:

  1. 登录管理控制台。
  2. 选择“服务列表 > 网络 > 虚拟私有云”。
  3. 在左侧导航栏选择“子网”。
  4. 在“子网”列表中,单击子网名称。
  5. 在“IP地址管理”页签中,单击“申请虚拟IP地址”,根据界面提示配置要申请的虚拟IP。
  6. 在“IP地址管理”页签中将上面解绑出来的弹性公网IP绑定到新申请的虚拟IP192.168.0.188上。

image.png
这里顺便多创建了一个内网IP192.168.0.189,待会在下面双主模式中会用到。
如果不是用的云平台,虚拟IP不需要去创建,直接在配置文件中指定即可。

ecs主机名称 主机内网IP 主机公网IP 主机绑定的VIP VIP映射的公网IP 主机角色
azhi-03 192.168.0.72 124.71.xx.203 192.168.0.188 139.9.xx.185 MASTER
azhi-05 192.168.0.166 139.9.xx.215 192.168.0.188 139.9.xx.185 BACKUP

1.2、安装nginx、keepalived

  1. #安装nginx、keepalived
  2. #如果nginx已经安装好了的,下面的nginx就去掉
  3. yum install nginx keepalived -y
  1. #分别修改两台nginx的index界面,方便后面知道跳转到了那台机器上
  2. vim /usr/share/nginx/html/index.html
  3. Welcome to nginx, azhi-03
  4. Welcome to nginx, azhi-05

1.3、配置keepalived高可用,修改主配置文件

a、检测nginx存活状态脚本:vim /etc/keepalived/chk_nginx.sh

  1. #!/bin/bash
  2. counter=$(ps -C nginx --no-heading|wc -l)
  3. if [ "${counter}" = "0" ]; then
  4. systemctl start nginx.service
  5. sleep 2
  6. counter=$(ps -C nginx --no-heading|wc -l)
  7. if [ "${counter}" = "0" ]; then
  8. systemctl stop keepalived.service
  9. fi
  10. fi

chmod +x /etc/keepalived/chk_nginx.sh

b、两台ecs均备份一下keepalived的原始的配置文件

  1. cp /etc/keepalived/keepalived.conf keepalived.conf.bak

c、编辑配置文件:vim /etc/keepalived/keepalived.conf

  1. vrrp_script chk_http_port {
  2. script "/etc/keepalived/chk_nginx.sh"
  3. interval 2
  4. weight -5
  5. fall 2
  6. rise 1
  7. }
  8. vrrp_instance VI_1 {
  9. state MASTER #BACKUP机修改为BACKUP
  10. interface eth0 #注意这里要和自己的网卡一致,建议复制安装后的名称
  11. virtual_router_id 51
  12. priority 100
  13. advert_int 1
  14. authentication {
  15. auth_type PASS
  16. auth_pass 1111
  17. }
  18. virtual_ipaddress {
  19. 192.168.0.188 #填写你创建的虚拟IP
  20. }
  21. }

1.4、启动两台ECS的nginx

  1. 执行以下命令,设置nginx服务开机自启动并启动服务。
  2. systemctl enable nginx
  3. systemctl start nginx.service

1.5、启动两台ECS的keepalived

  1. 执行以下命令,设置keepalived服务开机自启动并启动服务。
  2. systemctl enable keepalived
  3. systemctl start keepalived.service

1.6、将虚拟IP绑定到两台ECS实例上

image.png

1.7、重启并查看绑定结果

  1. 执行reboot分别重启azhi-03和azhi-05。
  2. 执行以下命令,查看虚拟IP是否有绑定到azhi-03的eth0网卡上。ip addr show,如图,表示虚拟IP已经绑定到azhi-03的eth0网卡上。

image.png

  1. 分别通过ECS自身的弹性公网IP和1个独立的弹性公网IP访问nginx:

image.png
image.png
image.png

1.8、测试暂停azhi-03上的keepalived

在zhi-03上执行

  1. systemctl stop keepalived.service

查看服务器zhi-05是否有接管虚拟IP

  1. ip addr show

如下图,可以看到azhi-05号云主机已经接管了虚拟IP192.168.0.188了
image.png
再将通过独立的弹性公网IP访问nginx:
如下图,此时弹性公网IP已经指向了azhi-05这台云主机了
image.png
由上可见,nginx的主从热备模式下只需要两台主机绑定同一个虚拟IP,并用一个公网IP绑定到虚拟IP即可。

二、Nginx+keepalived双主模式

该模式,使用2个vip地址,2个公网IP地址,2台ecs机器互为主备,同时会有2台机器工作,当其中一台机器出现故障时,两台机器的所有请求都转移到一台机器进行负担,非常适合于高可用的架构环境。

该模式如下:

image.png

2.1、测试环境如下:

在前面nginx主从热备的模式基础上,我们只需多加一个新的弹性公网IP(139.9.xx.124)和新的虚拟IP192.168.0.189进行配置即可,注意新加的虚拟IP也要绑定到新的弹性公网IP(139.9.xx.124)和ECS实例(azhi-03,azhi-05)上,如下图:
image.png
此时,ecs主机情况如下:

ecs主机名称 主机内网IP 主机公网IP 主机绑定的VIP VIP映射的公网IP 主机角色
azhi-03 192.168.0.72 124.71.xx.203 192.168.0.188
192.168.0.189
139.9.xx.185
139.9.xx.124
MASTER
BACKUP
azhi-05 192.168.0.166 139.9.xx.215 192.168.0.188
192.168.0.189
139.9.xx.185
139.9.xx.124
BACKUP
MASTER

2.2、两台ECS主机上都多添加一个实例节点

vim /etc/keepalived/keepalived.conf

  1. vrrp_instance VI_2 {
  2. state BACKUP #BACKUP机修改为MASTER
  3. interface eth0 #注意这里要和自己的网卡一致,建议复制安装后的名称
  4. virtual_router_id 52 #注意这里要和上一组51区分开来
  5. priority 99 #BACKUP机修改为100
  6. advert_int 1
  7. authentication {
  8. auth_type PASS
  9. auth_pass 1111
  10. }
  11. virtual_ipaddress {
  12. 192.168.0.189 #填写你创建的虚拟IP
  13. }
  14. }

2.3、重新启动两台nginx、keepalived后进行查看结果

如下图:通过x.x.x.185的这个弹性公网IP访问nginx依旧是转发到azhi-03
image.png
而通过x.x.x.124这个独立的弹性公网IP访问nginx则会转发到azhi-05号机
image.png
至此,azhi-03和azhi-05两台ecs上的nginx都互为主备同时进行工作了,也达到了我们想要的效果。
也由此可以看出,主主模式下是需要2个独立的公网IP和2个内网虚拟IP地址便可以完成了。

三、Nginx+keepalived双主模式+DNS轮询

3.1、在2.1中,双主模式使用了2个vip,并对外提供了2个公网IP以供外网访问,我们在访问时便可以用2个公网ip进行访问,但有的同学想通过一个相同的域名进行访问,由域名自动轮询到2个公网IP上。这种其实也很简单,我们只需做域名DNS解析即可,具体是在你的域名中添加两条弹性公网IP的A记录解析即可。

如下图:

image.png
阿里云dns解析配置如下:
image.png
开启权重并对dns的轮询权重进行配置
image.png
配置完成如下图
image.png

3.2、通过域名进行访问

通过域名访问nginx,dns轮询解析并返回了一个公网IP(x.x.x.185),公网IP(x.x.x.185)映射到vip(192.168.0.188),最终访问了azhi-03
image.png
再次刷新界面,dns轮询解析并返回了一个公网IP(x.x.x.124),公网IP(x.x.x.124)映射到vip(192.168.0.189),最终访问了azhi-05
image.png
由此实现了访问相同的一个域名,DNS根据权重轮询返回公网IP从而达到我们相要的负载效果。
注意,如果在测试过程中,发现偶尔会出现DNS解析结果和权重配置不符的现象,这属于一种正常现象。
因为加权轮询是一个粗粒度的解析流量调度方式,它针对的是localdns的请求,而localdns在TTL时间内是只会向权威DNS(云解析DNS)请求一次,即在TTL时间内,使用相同localdns下的所有用户获取到的都是同一个解析结果。

3.3、至此,nginx的几种高可用方案也算是完美的完成了。