Day61-Nginx反向代理与负载均衡高可用服务keepalved精讲
- 1.什么高可用集群?
- 2.高可用集群的企业场景。
- 3.高可用使用原则?
- 4.高可用开源软件
-
- [4.1 heartbeat](#4.1 heartbeat)
- [4.2 keepalived](#4.2 keepalived)
- 5.Keepalived高可用服务搭建
-
- [5.1 规划](#5.1 规划)
- [5.2 部署web01](#5.2 部署web01)
- [5.3 部署web02](#5.3 部署web02)
- [5.4 部署lb02](#5.4 部署lb02)
- [5.5 从lb01拷贝配置](#5.5 从lb01拷贝配置)
- [5.6 lb01,lb02分别安装keepalived](#5.6 lb01,lb02分别安装keepalived)
- [5.7 Keepalived配置文件说明*****](#5.7 Keepalived配置文件说明*****)
- [5.8 配置 lb01 keepalved.conf](#5.8 配置 lb01 keepalved.conf)
- [5.9 配置 lb02 keepalved.conf](#5.9 配置 lb02 keepalved.conf)
- [5.10 单实例场景与多实例](#5.10 单实例场景与多实例)
- [5.11 多实例lb01](#5.11 多实例lb01)
- [5.12 多实例lb02](#5.12 多实例lb02)
- [5.13 Keepalived高可用服务器对裂脑问题](#5.13 Keepalived高可用服务器对裂脑问题)
- [5.14 解决服务监听的网卡上不存在IP地址问题](#5.14 解决服务监听的网卡上不存在IP地址问题)
- [5.15 解决高可用服务只是针对物理服务器问题](#5.15 解决高可用服务只是针对物理服务器问题)
1.什么高可用集群?
2.高可用集群的企业场景。
3.高可用使用原则?
能用负载均衡就不用高可用。
高可用对浪费一台机器。
4.高可用开源软件
4.1 heartbeat
- ifconfig 别名的方式。 格式eth0:0
- 3个配置文件
ha.cf 基本配置
haresources 资源配置
aukeys 认证 - 用于带有资源数据的高可用对之间。
- heartbeat+drbd+mysql
drbd基于block复制(镜像)
4.2 keepalived
- ip配置,辅助IP
- 只有一个配置文件keepalived.conf
- 没有数据流动的的高可用对之间
- 如果有数据流动,自行解决。
- Keepalived高可用软件介绍
- Keepalived服务的三个重要功能
1.管理LVS负载均衡
2.对LVS节点做健康检查(基于端口和URL)
3.VRRP高可用功能 - Keepalived高可用故障切换转移原理
5.Keepalived高可用服务搭建
5.1 规划
HOSTNAME | IP | 说明 |
---|---|---|
lb01 | 10.0.0.5 | Keepalived主服务器(Nginx主负载均衡器) |
lb02 | 10.0.0.6 | Keepalived备服务器(Nginx辅负载均衡器) |
web01 | 10.0.0.7 | web01服务器(第11章搭建好的) |
web02 | 10.0.0.8 | web02服务器(第11章搭建好的) |
5.2 部署web01
bash
[root@web01 conf.d]# cat 02_www.etiantian.org.conf
server {
listen 80;
server_name www.etiantian.org;
root /data/www;
location / {
index index.html;
}
}
[root@web01 conf.d]# mkdir -p /data/www
[root@web01 conf.d]# echo web01 >/data/www/index.html
[root@web01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 conf.d]# systemctl restart nginx
[root@web01 conf.d]# grep www /etc/hosts
[root@web01 conf.d]# curl -H "host:www.etiantian.org" 10.0.0.7
web01
5.3 部署web02
bash
[root@web01 conf.d]# cat 02_www.etiantian.org.conf
server {
listen 80;
server_name www.etiantian.org;
root /data/www;
location / {
index index.html;
}
}
[root@web02 conf.d]# mkdir -p /data/www
[root@web02 conf.d]# echo web02 >/data/www/index.html
[root@web02 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web02 conf.d]# systemctl restart nginx
[root@web02 conf.d]# curl -H "host:www.etiantian.org" 10.0.0.8
web02
5.4 部署lb02
安装nginx
bash
[root@lb02 ~]# cat /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
priority=1
yum install yum-plugin-priorities -y
yum install nginx -y
systemctl start nginx
systemctl enable nginx
5.5 从lb01拷贝配置
bash
[root@lb02 ~]# scp -rp 172.16.1.5:/etc/nginx /etc/
[root@lb02 conf.d]# cat 03_www.etiantian.org.conf
upstream www {
server 172.16.1.7 weight=1 ; #默认80端口
server 172.16.1.8 weight=1; #默认80端口
}
server {
listen 80;
server_name www.etiantian.org;
location / {
proxy_pass http://www;
proxy_set_header Host $http_host;
}
}
nginx -t
systemctl restart nginx
#vip 10.0.0.6 测试负载成功
[root@lb02 conf.d]# curl -H "host:www.etiantian.org" 10.0.0.6
web01
[root@lb02 conf.d]# curl -H "host:www.etiantian.org" 10.0.0.6
web02
5.6 lb01,lb02分别安装keepalived
bash
[root@lb01 ~]# yum install keepalived -y
[root@lb01 ~]# systemctl start keepalived
[root@lb01 ~]# ps -ef|grep keep|grep -v grep
root 1455 1 0 16:36 ? 00:00:00 /usr/sbin/keepalived -D
root 1456 1455 0 16:36 ? 00:00:00 /usr/sbin/keepalived -D
root 1457 1455 0 16:36 ? 00:00:00 /usr/sbin/keepalived -D
[root@lb01 ~]# systemctl stop keepalived
[root@lb01 ~]# rpm -qa keepalived
keepalived-1.3.5-19.el7.x86_64
5.7 Keepalived配置文件说明*****
TOP HIERACHY
GLOBAL CONFIGURATION 全局配置
VRRPD CONFIGURATION VRRP配置
LVS CONFIGURATION(管理LVS的,nginx此处删掉)
bash
[root@lb01 keepalived]# cat keepalived.conf
global_defs {
router_id lb01 #<==id为lb01,不同的keepalived.conf此ID要唯一。
}
vrrp_instance VI_1 { #<==实例名字为VI_1,相同实例的备节点名字要和这个相同。
state MASTER #<==状态为MASTER,备节点状态需要为BACKUP。
interface eth0 #<==通信接口为eth0,此参数备节点设置和主节点相同。
virtual_router_id 51 #<==实例ID为55,keepalived.conf里唯一。
priority 150 #<==优先级为150,备节点的优先级必须比此数字低。
advert_int 1 #<==通信检查间隔时间1秒。
authentication {
auth_type PASS #<==PASS认证类型,此参数备节点设置和主节点相同。
auth_pass 1111 #<==密码是1111,此参数备节点设置和主节点相同。
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
#<==虚拟IP,即VIP,子网掩码为24位,绑定接口为eth0,别名为eth0:3,此参数备节点设置和主节点相同。
}
}
#提示:此处设置的虚拟IP为10.0.0.3,即网站域名绑定的IP。
5.8 配置 lb01 keepalved.conf
bash
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
}
systemctl restart keepalived
ifconfig|egrep '10.0.0.3|10.0.0.4'
5.9 配置 lb02 keepalved.conf
bash
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
}
systemctl restart keepalived
ifconfig|egrep '10.0.0.3|10.0.0.4'
停止一端服务器。看另一端IP接管情况
5.10 单实例场景与多实例
lb02:
bash
10.0.0.3 www.520.com mirrors.etiantian.org zh.etiantian.org phpmyadmin.etiantian.org
10.0.0.3 www.etiantian.org blog.etiantian.org
lb01:热备
浪费机器
两边跑服务;
lb02:
bash
10.0.0.3 www.520.com mirrors.etiantian.org zh.etiantian.org phpmyadmin.etiantian.org
lb01:
bash
10.0.0.4 www.etiantian.org blog.etiantian.org
某一台宕机,总流量能被撑住即可。
5.11 多实例lb01
bash
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:4
}
}
5.12 多实例lb02
bash
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:4
}
}
测试略。
切换:
1.切换VIP
2.动nginx???没有 一开始处于启动状态。。
5.13 Keepalived高可用服务器对裂脑问题
裂脑
1)什么是裂脑?
由于某些原因,导致两台高可用服务器对在指定时间内,无法检测到对方的心跳消息,各自取得资源及服务的所有权,而此时的两台高可用服务器对都还活着并在正常运行,这样就会导致同一个IP或服务在两端同时存在而发生冲突,最严重的是两台主机占用同一个VIP地址,当用户写入数据时可能会分别写入到两端,这可能会导致服务器两端的数据不一致或造成数据丢失,这种情况就被称为裂脑。
2)裂脑的原因
- 高可用服务器对之间心跳线链路故障,导致无法正常通信。
心跳线坏了(包括断了,老化)
网卡及相关驱动坏了,IP 配置及冲突问题(网卡直连)
心跳线间连接的设备故障(网卡及交换机)
仲裁的机器出问题(采用仲裁的方案) - 高可用服务器对上开启了iptables防火墙阻挡了心跳消息传输。
- 高可用服务器对上心跳网卡地址等信息配置不正确,导致发送心跳失败。
- keepalived配置问题。
3)解决裂脑的常见方案
-
同时使用串行电缆和以太网电缆连接,同时用两条心跳线路
-
当检测到裂脑时强行关闭一个心跳节点(这个功能需特殊设备支持,如Stonith 、fence)。相当于备节点接收不到心跳消息,发送关机命令通过单独的线路关闭主节点的电源。
fence
Stonith shut the other node in the head.爆头
-
做好对裂脑的监控报警(如邮件及手机短信等或值班),在问题发生时人为第时间介入仲裁,降低损失。例如,百度的监控报警短信就有上行和下行的区别。报警信息报到管理员手机上,管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器,让服务器根据指令自动处理相应故障,这样解决故障的时间更短。
当然,在实施高可用方案时,要根据业务实际需求确定是否能容忍这样的损失。对于一般的网站常规业务,这个损失是可容忍的。
4)裂脑实践
5.14 解决服务监听的网卡上不存在IP地址问题
如果配置使用"listen 10.0.0.3:80;"的方式指定IP监听服务,而本地的网卡上没有10.0.0.3这个IP,Nginx就会报错:
bash
[root@lb01 server]# nginx
nginx: [emerg] bind() to 10.0.0.3:80 failed (99: Cannot assign requested address)
如果要实施双主即主备同时跑不同的服务,配置文件里指定了IP监听,
加入如下内核参数配置:
bash
net.ipv4.ip_nonlocal_bind = 1
#此项表示启动nginx而忽略配置中监听的IP是否存在,它同样适合Haproxy。
5.15 解决高可用服务只是针对物理服务器问题
高可用服务只是针对物理服务器
服务器宕机切换
服务器不宕机,nginx负载服务宕了。。默认VIP是不漂移的。 此时没法分发请求。
功能:
keepalived判断nginx服务是否异常,如果nginx服务异常,实现服务器的切换。
分别在lb01,lb02上配置如下脚本
bash
[root@lb01 scripts]# cat chk_nginx_proxy.sh
#!/bin/sh
#如果nginx服务停止,则关闭keep.
if [ `netstat -lntup|grep nginx|wc -l` -ne 1 ];then
systemctl stop keepalived
fi
[root@lb01 scripts]# chmod +x chk_nginx_proxy.sh
[root@lb01 scripts]# /server/scripts/chk_nginx_proxy.sh ##要可以执行
测试:
bash
[root@lb01 scripts]# pkill nginx
[root@lb01 scripts]# sh chk_nginx_proxy.sh
[root@lb01 scripts]# ps -ef|egrep "nginx|keep"
root 1769 1197 0 18:35 pts/0 00:00:00 grep -E --color=auto nginx|keep
分别在lb01,lb02上配置keepalived.conf
lb01上配置keepalived.conf
bash
[root@lb01 scripts]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_script chk_nginx_proxy {#<==定义vrrp脚本,检测HTTP端口。
script "/server/scripts/chk_nginx_proxy.sh"#<==执行脚本,当nginx服务有问题,就停掉keepalived服务。
interval 2 #<==间隔2秒。
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 53
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
track_script {
chk_nginx_proxy #<==触发检查。
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:4
}
}
lb02上配置keepalived.conf
bash
[root@lb02 scripts]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_script chk_nginx_proxy {#<==定义vrrp脚本,检测HTTP端口。
script "/server/scripts/chk_nginx_proxy.sh"#<==执行脚本,当nginx服务有问题,就停掉keepalived服务。
interval 2 #<==间隔2秒。
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 53
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:3
}
track_script {
chk_nginx_proxy #<==触发检查。
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:4
}
}