Nginx之反向代理及其高可用keepalived+LVS

时间:2022-12-19 10:51:33

 

集群的特点

1、高性能 high performance
只有当并发或总请求数量超过单台服务器的承受能力时,服务器集群才会体现出优势
2、价格有效性cost-effectiveness
在达到同样性能需求的条件下,采用计算机集群架构比采用同等运算能力大型计算机具有更高的性价比
3、可伸缩性(scalability)
4、可管理性 manageability
5、可编程性 programmability


Linux集群主要分以下几类

负载均衡集群  (Load Balance Cluster)        LBC或者LB
高可用集群 ( High Availability Cluster) HAC
科学计算集群 (High Performance Computing Cluster) HPC
网格计算 (Grid computer)

 

负载均衡集群 & 高可用集群

负载均衡集群(Load Balance Cluster) 的作用
  1、分担用户访问请求或数据流量
  2、保持业务连续性,即7*24高可用服务(宕机不能太多)
应用: web服务,以及数据库从库,及其他应用业务
典型开源软件 lvs nginx haproxy (lighted)

高可用集群( High Availability Cluster) 作用(建议能做HB就不做HAC)
  1、当一台服务器宕机时,另一台接管(ip资源和服务器资源)
  2、负载均衡器之间,主数据库及主存储之间
典型的开源软件 keepalive heartbeat

互联网企业常用开源集群软件有 nginx、lvs、haproxy、keeplived,heartbeat
互联网企业常用商业集群硬件有F5\Netscaler(citrix)\Radware\A10等,相当于haproxy工作模式

 

 实战配置一个nginx反向代理

新安装两台nginx server(略)
#
cat nginx.conf.default | egrep -v "#|^$" >nginx.conf

nginx配置如下
worker_processes
1;
events {
worker_connections
1024;
}
http {
include mime.types;
default_type application
/octet-stream;
sendfile on;
keepalive_timeout
65;
upstream www.server_pools {
=> www.server_pools可自定义
server
192.168.0.82 weight=1;
server
192.168.0.83 weight=1;
#      server
192.168.0.* weight=1 backup; 高可用设置
}
server {
=>server标签,代理主机,proxy_pass抛给upstream
listen
80;
server_name www.gtms.org;
location
/ {
proxy_pass http:
//www.server_pools;
}
}
}
upstream (ngx_http_upstream_module) http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html 
  nginx负载均衡模块,定义有哪些节点,调度算法是什么
  Example Configuration
upstream backend { server backend1.example.com weight
=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;

server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup; }

server {
location / {
proxy_pass http://backend;
} }

http_proxy(ngx_http_proxy_module)http:
//nginx.org/en/docs/http/ngx_http_proxy_module.html
负责请求的转发,例如proxy_pass 发给定义好的指定upstream
Example Configuration
location
/ { proxy_pass http://localhost:8000;
proxy_set_header Host $host;  将header中的url传给后端server
proxy_set_header X-Forwarded-For $remote_addr;  将客户端真实IP传给后端server
}

nginx让后端apache记录真实IP的方法
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-For}i\"" common

找一台机器配置好hosts进行测试
[root@node87 ~]# for i in `seq 1000`;do curl www.gtms.org;sleep 1;done
82www.gtms.org
83www.gtms.org
82www.gtms.org
83www.gtms.org
82www.gtms.org
83www.gtms.org
82www.gtms.org
83www.gtms.org
82www.gtms.org
83www.gtms.org
82www.gtms.org



 

upstream (ngx_http_upstream_module)详解

Nginx的负载均衡功能依赖于此模块,支持的代理方式有proxy_pass(作为java代理)、fastcgi_pass、memcached_pass,新版的有所增加,本次针对proxy_pass代理方式讲解
ngx_http_upstream_module允许nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应的upstream组的名字上。
具体写法为“proxy_pass http:
//www_server_pools”,其中www_server_pools就是一个upstream节点服务器组的名字

upstream模块内部标签参数说明
server 192.168.0.90       weight=5;
server backend2.example.com:8080;
        #负载均衡RS节点,可以是IP 或是域名。高并发场景可使用域名,使用DNS做负载均衡,weight代表权重,默认为1 
server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
        #max_fails=3, 尝试连接rs失败的次数,配合proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, and memcached_next_upstream等使用。
        当nginx接收rs返回这三个参数定义的状态码时,会将这个请求转发给正常的rs,例如404,502,503,默认值为1,企业场景,建议2-3次,京东一次,蓝讯10次

server backup1.example.com  backup;
        #热备配置(rs高可用),当前面激活的rs都失败后会自动启动。注意,当ip_hash算法时,rs状态不能是weight或backup。(haproxy可以设置几台down了,back启动)
fail_timeout=30s;

        #在max_fails定义的失败次数后,距下次检查的间隔时间,默认10s。常规2-3s。比如京东3s,蓝讯3s
server backup1.example.com  down;

        #down标志着rs不可用,可以配和ip_hash使用

max_conns=number      
        #单个rs最大并发连接数限制,防止过载

route=string        
        #设置server路由的名字

slow_start=time      
        #宕机的rs从恢复开始,多长时间内被认为是健康的

proxy_next_upstream健康检查

server {
listen
80;
server_name www.gtms.org;
location
/{
proxy_pass http:
//static_pools;
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
#设定nginx代理请求后端real server时,请求出错时,再请求下一个服务器

 

 

upstream模块调度算法

静态  rr  wrr  iphash 负载均衡器根据自身设定的规则进行分配,不考虑后端节点服务器的情况 
iphash(可以实现会话保持,hash用户ip,同一ip来源分 配同一节点,可以解决session共享问题,但是nat上网模式导致负载不均)。
此外:url_hash 访问的URL HASH缓存,主要用于web缓存 (当有cache问题或新增cache时,整个缓存群重新计算,根据cache数量取模的,存储压力瞬间增加)。
一致性hash算法(consistent_hash)解决此问题,较小动荡,以及能平衡cache群。nginx本身不支持一致性hash算法,其分支taobao的tengine支持
动态 least_conn fair
fair 根据后端节点服务器的响应时间分配请求,相应时间短的优先分配。默认不支持,必须下载nginx的相关模块upstream_fair
实例 upstream server_pool
{
server
192.168.0.1
server
192.168.0.2
fair;

}
least_conn根据后端节点的连接数来决定分配情况,哪个连接数少就分配

 

http_proxy(ngx_http_proxy_module)详解

Nginx之反向代理及其高可用keepalived+LVSNginx之反向代理及其高可用keepalived+LVS
     proxy_bind
proxy_buffer_size
proxy_buffering
proxy_buffers
proxy_busy_buffers_size
proxy_cache
proxy_cache_background_update
proxy_cache_bypass
proxy_cache_convert_head
proxy_cache_key
proxy_cache_lock
proxy_cache_lock_age
proxy_cache_lock_timeout
proxy_cache_max_range_offset
proxy_cache_methods
proxy_cache_min_uses
proxy_cache_path
proxy_cache_purge
proxy_cache_revalidate
proxy_cache_use_stale
proxy_cache_valid
proxy_connect_timeout
proxy_cookie_domain
proxy_cookie_path
proxy_force_ranges
proxy_headers_hash_bucket_size
proxy_headers_hash_max_size
proxy_hide_header
proxy_http_version
proxy_ignore_client_abort
proxy_ignore_headers
proxy_intercept_errors
proxy_limit_rate
proxy_max_temp_file_size
proxy_method
proxy_next_upstream
proxy_next_upstream_timeout
proxy_next_upstream_tries
proxy_no_cache
proxy_pass
proxy_pass_header
proxy_pass_request_body
proxy_pass_request_headers
proxy_read_timeout
proxy_redirect
proxy_request_buffering
proxy_send_lowat
proxy_send_timeout
proxy_set_body
proxy_set_header
proxy_ssl_certificate
proxy_ssl_certificate_key
proxy_ssl_ciphers
proxy_ssl_crl
proxy_ssl_name
proxy_ssl_password_file
proxy_ssl_server_name
proxy_ssl_session_reuse
proxy_ssl_protocols
proxy_ssl_trusted_certificate
proxy_ssl_verify
proxy_ssl_verify_depth
proxy_store
proxy_store_access
proxy_temp_file_write_size
proxy_temp_path
Embedded Variables
http://nginx.org/en/docs/http/ngx_http_proxy_module.html

常用模块

proxy_pass
把用户的请求转向到反向代理定义的upstream服务器池proxy_pass http:
//server_pools;
proxy_set_header
  proxy_set_header Host $host;
    设置http请求header项传给后端服务器,使携带request head信息。多虚拟主机时,识别出虚拟主机如果不带可能返回和请求内容不一致的网页。  proxy_set_header X-Forwarded-For $remote_addr;
    在代理向后端服务器发送的http请求头中加入X
-Forward-For字段信息,用于后端服务器程序、日志等接收记录真实用户的IP,而不是代理服务器的IP。
proxy_connect_timeout
  Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.
  表示与后端服务器连接的超时时间,即发起握手等候相应的超时时间
proxy_send_timeout
  Sets a timeout for transmitting a request to the proxied server. The timeout is set only between two successive write operations, not for the transmission of the whole request.
  If the proxied server does not receive anything within this time, the connection is closed.

  表示RS的数据回传时间,即在规定的时间内,RS必须传完所有数据,否则,将断开连接
proxy_read_timeout
  Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response.
  If the proxied server does not transmit anything within this time, the connection is closed.
  设置从RS获取信息的时间,表示连接建立成功后,等待RS的响应时间,其实就是已经进入后端队列中等候处理的时间

proxy_buffer_size
  Sets the size of the buffer used for reading the first part of the response received from the proxied server.
  This part usually contains a small response header. By default, the buffer size is equal to one memory page.
  This is either 4K or 8K, depending on a platform. It can be made smaller, however.
  设置缓冲区大小,通常包含后端服务器的头部信息
proxy_buffers
  Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection.
  By default, the buffer size is equal to one memory page. This is either 4K or 8K, depending on a platform.
  设置缓冲区大小和数量
proxy_busy_buffers_size
  When buffering of responses from the proxied server is enabled, limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read.
  In the meantime, the rest of the buffers can be used for reading the response and, if needed, buffering part of the response to a temporary file.
  By default, size is limited by the size of two buffers set by the proxy_buffer_size and proxy_buffers directives.
  设置用于系统繁忙时可以使用的buffer大小,推荐为proxy_buffers*2

proxy_temp_file_write_size

  Limits the size of data written to a temporary file at a time, when buffering of responses from the proxied server to temporary files is enabled.
  By default, size is limited by two buffers set by the proxy_buffer_size and proxy_buffers directives.
  The maximum size of a temporary file is set by the proxy_max_temp_file_size directive.
  指定proxy缓存临时文件的大小


可以在conf文件中以include方式加载参数
upstream www_server_pools {
server 192.168.0.82 weight=3;
server 192.168.0.83;
}
server {
listen 80;
server_name www.gtms.org;
location /{
proxy_pass http://www_server_pools;
proxy_set_header Host   $host;
proxy_set_header X-Forwarded-For $remote_addr;
include proxy.conf;
}
}
#cat proxy.conf
  proxy_set_header Host   $host;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_connect_timeout 60;
  proxy_send_timeout 60;
  proxy_read_timeout 60;
  proxy_buffer_size 4k;
  proxy_buffers 4 32k;
  proxy_busy_buffers_size 64k
  proxy_temp_file_write_size 64k

 

 proxy_pass指令介绍

proxy_pass指令介绍:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
部分使用示例
1、将匹配URI为name的请求抛给http://127.0.0.1/remote/
location /name/ {
    proxy_pass http://127.0.0.1/remote/; }  #斜线很重要
2、将匹配URI为some/path的请求抛给http://127.0.0.1
location /some/path/ {
   proxy_pass http://127.0.0.1/; }
3、将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1;
location /name/ {
    rewrite    /name/([^/]+) /users?name=$1 break;
    proxy_pass http://127.0.0.1;


案例配置实战
(程序无法分离情况(域名拆不开),使用upstream实现动静态分离)

当用户请求url/upload/xx地址时实现由upload上传服务器池处理请求
当用户请求url/static/xx地址时实现由静态服务器池处理请求
除此外,其他请求默认动态服务器池处理请求

方案一 location语句实现的方案,匹配目录
  upstream static_pools {server ip:80 weight=1;}  #static_pools为静态服务器池,有一个服务器,地址为ip,80端口
  upstream upload_pools {server ip:80 weight=1;}  #upload_pools为上传服务器池,有一个服务器,地址为ip,80端口
  upstream default_pools {serverip:80 weight=1;}  #default_pools为默认动态服务器池,有一个服务器,地址为ip,80端口

server {
    listen    80;
    server_name    www.gtms.org;
    
    location / {
      proxy_pass http:// default_pools;             #默认走动态,功能最全
      include proxy.conf
      }
    location /static/ {
      proxy_pass http:// static_pools;        #匹配到static,访问static服务器
      include proxy.conf
      }
    location /upload/ {
      proxy_pass http://upload_pools;        #匹配到upload,访问upload服务器
      include proxy.conf
       }

方案二 if语句实现的方案,匹配目录
if ($request_uri  ~*  "^/static/(.*)$")  {proxy_pass http://static_pools/$1;}
if ($request_uri  ~*  "^/upload/(.*)$")  {proxy_pass http://upload_pools/$1;}
location / {
proxy_pass http://default_pools/$1;
include proxy.conf
}
应用场景
在企业中,有时只希望一个域名对外提供服务,不希望使用多个域名对应同一个产品业务,此时需要在代理服务器上通过配置规则,使得匹配不同规则的请求会交给不同的RS池处理,这类业务有:
1、业务域名没有拆分或者不希望拆分,但是希望实现动静分离,多业务分离
2、不同的服务端设备(例如:手机和PC端)使用同一个域名访问同一个业务网站,就需要设置将不同设备的用户请求交给后端不同的服务器处理,以便得到最佳的用户体验


根据浏览器选择不同的服务器$http_user_agent
location / {
    if ($http_user_agent ~* "MSIE")  {proxy_pass http://static_pools;}
    if (http_user_agent ~* "Chrome") {proxy_pass http://upload_pools;}
proxy_pass http://default_pools;
}
根据客户端选择不同的服务器http_user_agent
location / {
    if ($http_user_agent ~* “android”) {proxy_pass http://android_pools;}
    if ($http_user_agent ~* “iphone”)   {proxy_pass http://ipone_pools;}
proxy_pass http://pc_pools;  默认找此
include extra/proxy.conf;
}

根据扩展名实现代理转发

location方法
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|css|js)$  {proxy pass http://static_pools;
include proxy.conf;}
location ~ .*.(php|php3|php5)$ { proxy pass http://dynamic_pools;
include proxy.conf;}
if语句实现的方案
if ($request_uri  ~*  ".*\.(php|php5)$")
{proxy_pass http://php_server_pools;}
if ($request_uri  ~*  ".*\.(jsp|jsp*|do|do*)$")
{proxy_pass http:java_server_pools;}

 

nginx服务器内核参数生产配置

可参考linux服务器内核参数优化
以下参数优化适合apache、nginx、squid多种web应用,特殊业务可能需要微调
所谓内核优化,主要是在linux系统中针对业务服务器应用而进行的系统内核参数优化,优化并无特定的标准,下面是常见的生产环境linux的内核参数优化为例讲解,供参考
/etc/sysctl.conf sysctl -p生效
net.ipv4.tcp_fin_timeout
= 2
net.ipv4.tcp_tw_reuse
= 1
net.ipv4.tcp_tw_recycle
= 1
net.ipv4.tcp_syncookies
= 1
net.ipv4.tcp_keepalive_time
= 600
net.ipv4.ip_local_port_range
= 4000 65000
net.ipv4.tcp_max_syn_backlog
= 16384
net.ipv4.tcp_max_tw_buckets
= 36000
net.ipv4.route.gc_timeout
= 100
net.ipv4.tcp_syn_retries
= 1
net.ipv4.tcp_synack_retries
= 1
net.core.somaxconn
= 16384
net.core.netdev_max_backlog
= 16384
net.ipv4.tcp_max_orphans
= 16384
#以下参数是对iptables防火墙的优化,防火墙不开会提示,可以忽略不理。
net.ipv4.ip_conntrack_max
= 25000000
net.ipv4.netfilter.ip_conntrack_max
=25000000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established
=180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait
=120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait
=60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait
=120

 

 

 

Keepalived高可用集群

Keepalived服务介绍( www.keepalived.org)

Keepalived起初是专为LVS设计的,专门用来监控LVS集群系统中各个服务节点的状态,后来又加入了VRRP的功能,因此除了配合LVS服务外,也可以为其他服务(nginx haproxy)的高可用软件
VRRP是Virtual Router Redunancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由出现的单点故障问题,他能够保证网络的不间断、稳定的运行。
所以,Keepalived一方面具有LVS cluster nodes healthecks功能,另一方面也具有LVS directors failover功能。

VRRP协议

  VRRP协议,全称Virtual Router Reduncancy Protocol,中文名,虚拟路由器冗余协议,VRRP的出现就是为了解决静态路由的单点故障,VRRP是通过一种竞选协议机制来将路由任务交给某台VRRP路由器。

  • VRRP协议,全称Virtual Router Redundancy Protocol,虚拟路由器冗余协议,VRRP的出现就是为了解决静态路由的单店故障
  • VRRP是通过一种竞选协议机制来将路由任务交给某台VRRP路由器。
  • VRRP是通过IP多播方式实现通信
  • 主发包,备接包,当备接不到主发的包的时候,就启动接管程序接管主的资源,备可以有多个,通过优先级竞选
  • VRRP使用了加密协议

 

 

Keepalived服务有两大用途:healthcheck、failover

1、LVS directors failover 失败接管功能
  ha failover功能:实现LB Master主机和Backup主机故障转移和自动切换。
  这是针对有两个负载均衡器Director同时工作而采取的故障转移措施。
  当主负载均衡器(master)失效或出现故障时,备份负载均衡器(BACKUP)将会自动接管主负载均衡器的所有工作(VIP资源及相应服务);
  一旦主负载均衡器(MASTER)故障修复,master又会接管回它原来处理的工作,而备份负载均衡器(backup)会释放master失效时它接管的工作,此时两者将恢复到最初各自的角色状态。
2、LVS cluster nodes healthchecks 健康检查功能
a、keepalived.conf里配置就可以实现LVS功能
b、keepalived可以对LVS下面的集群阶段做健康检查
  RS healthcheck功能:负载均衡定期检查RS的可用性决定是否给其分发请求
  当虚拟服务其中的某个甚至是几个真实服务器同时发生故障无法提供服务时,负载均衡器会自动将失效的RS服务器从转发队列中清除出去,从而保证用户的访问不受影响;
  当故障的RS服务器被修复以后,系统又会自动地把他们加入转发队列,分发请求提供正常服务。

 

keepalived工作原理

keepalived高可用对之间是通过VRRP协议通信的,VRRP协议是通过竞争机制来确定主备的。
主的优先级高于备,因此,工作时会获得所有资源,备节点处于等待状态,当主挂了的时候,备节点接管主节点的资源,然后顶替主节点对外提供服务器。VRRP协议是通过IP多播包的方式
224.0.0.18)发送的。
在keepalived之间,只有作为主的服务器会一直发送VRRP广播包,告诉备他还活着,此时备不会抢占主。
当主不可用时,即备监听不到主发送的广播包时,就会启动相关服务接管资源,保证业务的连续性,接管速度可以小于1秒。VRRP使用加密协议加密发送广播包

 

keepalived安装与配置

在两台nginx proxy上安装,实现高可用,当一台出现宕机时,备机接管

# ln -s /usr/src/kernels/2.6.32-573.el6.x86_64/ /usr/src/linux如果没有,通过yum install kernel-devel -y安装 暂时用不到,配lvs时用到,因为通过内核管理lvs

#yum install openssl-devel –y
#tar -xzvf keepalived-1.2.20.tar.gz
#cd keepalived-1.2.20
#./configure
#make && make install
Keepalived configuration
------------------------
Keepalived version :
1.2.22
Compiler :
gcc
Compiler flags :
-g -O2
Extra Lib :
-lssl -lcrypto -lcrypt
Use IPVS Framework : Yes
==>LVS功能
IPVS
sync daemon support : Yes ==>LVS功能
IPVS use libnl : No
fwmark socket support : Yes
Use VRRP Framework : Yes
Use VRRP VMAC : Yes
===VRRP功能
Use VRRP authentication : Yes
SNMP keepalived support : No
SNMP checker support : No
SNMP RFCv2 support : No
SNMP RFCv3 support : No
SHA1 support : No
Use Debug flags : No
libnl version : None
Use IPv4 devconf : No
Use libiptc : No
Use libipset : No

配置规范启动
#
/bin/cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/ ==>生成启动脚本命令
#
/bin/cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/ ==>配置启动脚本参数(Options for keepalived)
#
mkdir /etc/keepalived ==>创建默认的配置文件路径
#
/bin/cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived ==>conf模板文件拷至上述路径
#
/bin/cp /usr/local/sbin/keepalived /usr/sbin

#/etc/init.d/keepalived Usage: /etc/init.d/keepalived {start|stop|reload|restart|condrestart|status}

# ps -ef | grep keepalivedroot 8219 1 0 21:43 ? 00:00:00 keepalived -D
root
8221 8219 0 21:43 ? 00:00:00 keepalived -D
root
8222 8219 0 21:43 ? 00:00:00 keepalived -D

#vi /etc/keepalived/keepalived.conf    # man keepalived.conf配置文件帮助
1 ! Configuration File for keepalived
2
3 global_defs {
4 notification_email {
5 acassen@firewall.loc
6 failover@firewall.loc
7 sysadmin@firewall.loc
8 }
9 notification_email_from Alexandre.Cassen@firewall.loc
10 smtp_server 192.168.200.1
11 smtp_connect_timeout 30 #1到11行,企业里基本不用动
12 router_id LVS_01      #另一台router_id LVS_02,相当于mysql的serverid
13 vrrp_skip_check_adv_addr
14 vrrp_strict
15 vrrp_garp_interval 0
16 vrrp_gna_interval 0
17 }
18 (下面部分除了 20行和23行,2个keepalived一样)
19 vrrp_instance VI_1 { #vrrp实例的ID 实现双主时改(复制如下部分改),大概最多20个实例
20 state MASTER        #另一台state BACKUP
21 interface eth0
22 virtual_router_id 51   #实例的ID 不用改,不然裂脑,实现双主 时改
23 priority 100        #另一台priority 50 (官方建议大50,优先级大接管资源)
24 advert_int 1        #心跳间隔1秒,对方接受不到,立刻接管
25 authentication {
26 auth_type PASS
27 auth_pass 1111
28 }
29 virtual_ipaddress {   #vip配置
30 192.168.0.222/24
33 }
34 }
之后部分是LVS配置,可以删除。


#
/etc/init.d/keepalived start
Starting keepalived: [ OK ]
#ip addr
| grep 192
inet 192.168.0.84/24 brd 192.168.0.255 scope global eth0
inet 192.168.0.222/24 scope global secondary eth0
==>当主keepalived服务停掉后,192.168.0.222这个ip自动漂移到BACKUP上,如果两端都有,说明脑裂了
keepalive添加IP方式是通过ip addr add
192.168.0.222 dev eth0方式添加的ip,所以ifconfig查不到的,用ip add 查看

测试
==nginx proxy通过vip 192.168.0.222服务,当停止主proxy的keepalived时,vip迅速漂移至备机,实现nginx proxy服务高可用
[root@node87 ~]# for i in `seq 100`;do curl 192.168.0.222;date +%s;sleep 1;done
83www.gtms.org
1486551965
82www.gtms.org
1486551966    #切换间隔
83www.gtms.org
1486551970
82www.gtms.org
1486551971
83www.gtms.org
1486551972
82www.gtms.org

keepalived实现服务器级别的接管,nginx服务宕,不会接管。
cat check_web.sh #后台运行并监控此进程,注意脚本名,不要nginx字样。如果检查没有nginx进程,停止keepalived
#
!/bin/sh
while true
do
if [ `ps –ef | grep nginx | grep –v grep | wc -l` -lt 2]
then
/etc/init.d/keepalived stop
fi
sleep 5
done

备机脚本检查裂脑
#可以ping通主,备节点有VIP就认为裂脑
cat check_split_brain.sh
#
!/bin/sh
while true
do
ping -c 2 -W 3 10.0.0.7 &>/dev/null #主机real ip
if [ $? -eq 0 -a `ip add|grep 10.0.0.17|wc -l` -eq 1 ] #主机vip
then
echo "ha is split brain.warning."
else
echo "ha is ok"
fi
sleep 5
done

keepalived日志

默认
/var/log/message# vi /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS
="-D" #修改为==> KEEPALIVED_OPTIONS="-D -S 0 -d" #-S 0(0设备)
#
vi /etc/rsyslog.conf #增加一行
local0.
* /var/log/keepalived.log
#
/etc/init.d/rsyslog restart

 

 

LVS负载均衡

LVS(Linux Virtual Server)介绍

该项目在1998年5月由章文嵩博士组织成立,
是中国国内最早出现的*软件项目之一。

LVS项目介绍 http:
//www.linuxvirtualserver.org/zh/lvs1.html
LVS集群的体系结构 http://www.linuxvirtualserver.org/zh/lvs2.html
LVS集群中的IP负载均衡技术 http://www.linuxvirtualserver.org/zh/lvs3.html
LVS集群的负载调度 http://www.linuxvirtualserver.org/zh/lvs4.html

IPVS(lvs)发展史

  早在2.2内核时,IPVS就已经以内核补丁的形式出现
  从2.
4.23版本开始,IPVS软件就是合并到Linux内核的常用版本的内核补丁的集合。
  从2.
4.24以后IPVS已经成为Linux官方标准内核的一部份。

管理IPVS的方式:
  IPVS     是实现调度的模块,工作在内核层面,使用该软件配置LVS时候,不能直接配置内核中的ipvs
  ipvsadm 管理IPVS的工具,通过keepalived配置文件也可以实现管理IPVS


LVS技术点小结:
  1、真正实现负载调度的工具是IPVS,工作在linux内核层面。
  2、LVS自带的IPVS管理工具是ipvsadm。
  3、keepalived实现管理IPVS及对负载均衡器的高可用。
  4、Red hat工具Piranha WEB管理实现调度的工具IPVS

LVS集群负载均衡器接受服务的所有入站客户端计算机请求,并根据调度算法决定哪个集群节点应该处理回复请求。
负载均衡器(简称LB)有时也被称为LVS Director(简称Director)。



名词解释

VIP    虚拟IP地址     VIP为Direct用于向客户端计算机提供服务的IP地址
RIP 真实IP地址 在集群下面节点上使用的IP地址,是物理IP地址
DIP Director的IP Direct用于连接内外网的IP地址,物理网卡上的IP地址,是负载均衡上的IP
CIP 客户端IP地址 客户端用户请求集群服务器的IP地址,该地址用于发送给集群的请求的源IP

LVS 4种模式

NAT(Network Address Translation)
DR(Direct Routing)
*****互联网公司经常采用的
TUN(IP Tunneling)
FULLNAT(Full Network Address Translation)

 

DR模式-直接路由模式

Direct Routing(VS/DR)
VS
/DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真实服务器将响应后的处理结果直接返回给客户端用户。
同VS/TUN技术一样,VS/DR技术可极大地提高集群系统的伸缩性。而且,这种DR模式没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求
但是要求调度器LB与真实服务器RS都有一块网卡连在同一物理网段上,即必须在同一个局域网环境。

1、通过在调度器LB上修改数据包的目的MAC地址实现转发。注意,源IP地址仍然是CIP,目的IP地址仍然是VIP。
2、请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高(和NAT模式比)。
3、因DR模式是通过MAC地址的改写机制实现的转发,因此,所有RS节点和调度器LB只能在一个局域网LAN中(小缺点)。
4、需要注意RS节点的VIP的绑定(lo:vip/32,lo1:vip/32)和ARP抑制问题。
5、RS节点的默认网关不需要是调度器LB的DIP,而直接是IDC机房分配的上级路由器的IP(这是RS带有外网IP地址的情况),理论讲:只要RS可以出网即可,不是必须要配置外网IP。(建议外网IP)
6、由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求的报文的目的端口(和NAT要区别)。
7、当前,调度器LB支持几乎所有的UNIX,LINUX系统,但目前不支持WINDOWS系统。真实服务器RS节点可以是WINDOWS系统。
8、总的来说DR模式效率很高,但是配置也较麻烦,因此,访问量不是特别大的公司可以用haproxy/nginx取代之。这符合运维的原则:简单、易用、高效。
参考:日PV 1000-2000W或并发请求1万以下都可以考虑用haproxy/nginx(LVS NAT模式)
9、直接对外的访问业务,例如:web服务做RS节点,RS最好用公网IP地址。如果不直接对外的业务,例如:MySQL,存储系统RS节点,最好只用内部IP地址。


 

NAT模式

通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;
真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程。
1
、NAT技术将请求的报文(通过DNAT方式改写)和响应的报文(通过SNAT方式改写),通过调度器地址重写然后在转发给内部的服务器,报文返回时在改写成原来的用户请求的地址。2、只需要在调度器LB上配置WAN公网IP即可,调度器也要有私有LAN IP和内部RS节点通信。
3、每台内部RS节点的网关地址,必须要配成调度器LB的私有LAN内物理网卡地址(LDIP),这样才能确保数据报文返回时仍然经过调度器LB。
4、由于请求与响应的数据报文都经过调度器LB,因此,网站访问量大时调度器LB有较大瓶颈,一般要求最多10-20台节点。
5、NAT模式支持对IP及端口的转换,即用户请求10.0.1.1:80,可以通过调度器转换到RS节点的10.0.1.2:8080(DR和TUN模式不具备的)。
6、所有NAT内部RS节点只需配置私有LAN IP即可。
7、由于数据包来回都需要经过调度器,因此,要开启内核转发net.ipv4.ip_forward = 1,当然也包括iptables防火墙的forward功能(DR和TUN模式不需要)。

 

TUN模式

采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。
为了解决这个问题,调度器把请求报 文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 VS/TUN技术后,集群系统的最大吞吐量可以提高10倍。
1
、负载均衡器通过把请求的报文通过IP隧道(ipip隧道,高级班讲这个)的方式(请求的报文不经过原目的地址的改写(包括MAC),而是直接封装成另外的IP报文)转发至真实服务器,而真实服务器将响应处理后直接返回给客户端用户。2、由于真实服务器将响应处理后的报文直接返回给客户端用户,因此,最好RS有一个外网IP地址,这样效率才会更高。理论上:只要能出网即可,无需外网IP地址。
3、由于调度器LB只处理入站请求的报文。因此,此集群系统的吞吐量可以提高10倍以上,但隧道模式也会带来一定的系统开销。TUN模式适合LAN/WAN。
4、TUN模式的LAN环境转发不如DR模式效率高,而且还要考虑系统对IP隧道的支持问题。
5、所有的RS服务器都要绑定VIP,抑制ARP,配置复杂。
6、LAN环境一般多采用DR模式,WAN环境可以用TUN模式,但是当前在WAN环境下,请求转发更多的被haproxy/nginx/DNS调度等代理取代。因此,TUN模式在国内公司实际应用的已经很少。跨机房应用要么拉光纤成局域网,要么DNS调度,底层数据还得同步。
7、直接对外的访问业务,例如:web服务做RS节点,最好用公网IP地址。不直接对外的业务,例如:MySQL,存储系统RS节点,最好用内部IP地址。

以上3中模式的特点

1、NAT模式:
入站DNAT,出站SNAT,入站出站都经过LVS,可以修改端口,私有网络。

2、DR模式*****
修改数据包的目的MAC地址,入站经过LVS,出站不经过LVS,直接返回客户,不能改端口,LAN内使用。

3、TUN模式
不改变数据包内容,数据包外部封装一个IP头,入站经过LVS,出站不经过LVS,直接返回客户,不能改端口,LAN
/WAN使用。
LVS和节点之间通过隧道通信。

 

 

3种模式的特点
  VS/NAT VS/TUN VS/DR
Real Server config dr gw Tunneling Non-arp device/tie vip
Server Network private LAN/WAN LAN
Server Number low(1--20) High(100) High(100)
Real Server Gateway LB Own router Own router
优点 地址与端口转换 WAN环境 性能最高
缺点 瓶颈大效率低 需要支持隧道协议 不能跨LAN

 

LVS调度算法:

固定调度算法:rr,wrr,dh(dest hash),sh
动态调度算法:wlc,lc,lblc,lblcr,SED,NQ(后两种官方站点没提到,编译LVS,make过程可以看到rr
|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq)。

一般的网络服务,如http、mail、Mysql等,常用的LVS调度算法为
a、  rr基本轮巡调度算法
b、  wlc加权最小连接调度
c、  wrr加权轮巡调度算法

 

LVS安装配置

Real server:192.168.0.82(nginx) 192.168.0.83(nginx)
LB server   :192.168.0.84 (VIP使用之前keepalived配置的192.168.0.222)

#/etc/init.d/keepalived start            #keepalived启动时会加载ip_vs模块,执行ipvsadm时也会自动加载
#
lsmod | grep ip_vs
ip_vs_rr
1420 3
ip_vs
126534 5 ip_vs_rr
libcrc32c
1246 1 ip_vs
ipv6
335589 282 ip_vs,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6

ip_vs管理软件安装

#yum install ipvsadm -y
#rpm -qa ipvsadm
ipvsadm-1.26-4.el6.x86_64
# ipvsadm --help
ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)
Usage:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine]
ipvsadm -D -t|u|f service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f service-address -r server-address [options]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address]
ipvsadm --set tcp tcpfin udp
ipvsadm --start-daemon state [--mcast-interface interface] [--syncid sid]
ipvsadm --stop-daemon state
ipvsadm -h

Commands:
Either long or short options are allowed.
--add-service -A add virtual service with options
--edit-service -E edit virtual service with options
--delete-service -D delete virtual service
--clear -C clear the whole table
--restore -R restore rules from stdin
--save -S save rules to stdout
--add-server -a add real server with options
--edit-server -e edit real server with options
--delete-server -d delete real server
--list -L|-l list the table
--zero -Z zero counters in a service or all services
--set tcp tcpfin udp set connection timeout values
--start-daemon start connection sync daemon
--stop-daemon stop connection sync daemon
--help -h display this help message

Options:
--tcp-service -t service-address service-address is host[:port]
--udp-service -u service-address service-address is host[:port]
--fwmark-service -f fwmark fwmark is an integer greater than zero
--ipv6 -6 fwmark entry uses IPv6
--scheduler -s scheduler one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,
the default scheduler is wlc.
--pe engine alternate persistence engine may be sip,
not set by default.
--persistent -p [timeout] persistent service 会话保持
--netmask -M netmask persistent granularity mask
--real-server -r server-address server-address is host (and port)
--gatewaying -g gatewaying (direct routing) (default)
--ipip -i ipip encapsulation (tunneling)
--masquerading -m masquerading (NAT)
--weight -w weight capacity of real server
--u-threshold -x uthreshold upper threshold of connections
--l-threshold -y lthreshold lower threshold of connections
--mcast-interface interface multicast interface for connection sync
--syncid sid syncid for connection sync (default=255)
--connection -c output of current IPVS connections
--timeout output of timeout (tcp tcpfin udp)
--daemon output of daemon information
--stats output of statistics information
--rate output of rate information
--exact expand numbers (display exact values)
--thresholds output of thresholds information
--persistent-conn output of persistent connection info
--nosort disable sorting output of service/server entries
--sort does nothing, for backwards compatibility
--ops -o one-packet scheduling
--numeric -n numeric output of addresses and ports

 



LVS配置过程:(ipvsadm --help)#ipvsadm
-C      # 清空之前的配置
#ipvsadm
--set 30 5 60    # ipvsadm --set tcp tcpfin udp #设置超时参数,小优化ipvsadm -L --timeout
#ipvsadm
-A -t 192.168.0.222:80 -s rr #添加一个v server 可加-p 300 会话保持 -t tcp server
#ipvsadm
-L
IP Virtual Server version
1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP
192.168.0.187:http rr
#ipvsadm
-a -t 192.168.0.222:80 -r 192.168.0.82:80 -g #添加-r realserve节点 -g直接路由模式
#ipvsadm
-a -t 192.168.0.222:80 -r 192.168.0.83:80 -g

#ipvsadm
-Ln 查看 #可以加--stats --timeoutIP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.222:80 rr
-> 192.168.0.83:80 Route 1 0 0
-> 192.168.0.83:80 Route 1 0 0




手工配置LVS小结:
ipvsadm
-C
ipvsadm
--set 30 5 60
ipvsadm
-A -t 192.168.0.222:80 -s rr -p 300
ipvsadm
-a -t 192.168.0.222:80 -r 192.168.0.84:80 -g
ipvsadm
-a -t 192.168.0.222:80 -r 192.168.0.85:80 -g
ipvsadm
-Ln
LVS节点删除:
ipvsadm
-D -t 192.168.0.222:80
ipvsadm
-d -t 192.168.0.222:80 -r 192.168.0.82:80


所有RS节点的配置过程:

RS绑定VIP:
ip addr add
192.168.0.222/32 dev lo label lo:1 #建议绑定32位的
route add
-host 192.168.0.222 dev lo
抑制ARP:
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


arp_ignore:定义对目标地址为本地IP的ARP询问不同的应答模式0
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询 请求
2 -
只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7 - 保留未使用
8 -不回应所有(本地地址)的arp查询
arp_announce:对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地
址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.


找一台机器进行测试(hosts配置192.168.0.222 www.gtms.org)
[root@node86 ~]# for i in `seq 100`;do curl 192.168.0.222;date +%s;sleep 1;done
82www.gtms.org
1486557567
83www.gtms.org
1486557568
82www.gtms.org
1486557569
83www.gtms.org
1486557570
82www.gtms.org
1486557571
83www.gtms.org
1486557572

 

从一台nginx server捕获到的信息

[root@node83 ~]# tcpdump -nnn -i eth0 -s 10000 -A host 192.168.0.222  and port 80
tcpdump: verbose output suppressed, use
-v or -vv for full protocol decode
listening on eth0, link
-type EN10MB (Ethernet), capture size 10000 bytes
06:48:20.837760 IP 192.168.0.86.48280 > 192.168.0.222.80: Flags [S], seq 1903210290, win 14600, options [mss 1460,sackOK,TS val 9037827 ecr 0,nop,wscale 6], length 0
E..
<G1@.@.q....V.......Pqp.2......9..[.........
............
06:48:20.837886 IP 192.168.0.86.48280 > 192.168.0.222.80: Flags [S], seq 1903210290, win 14600, options [mss 1460,sackOK,TS val 9037827 ecr 0,nop,wscale 6], length 0
E..
<G1@.@.q....V.......Pqp.2......9..[.........
............
06:48:20.837915 IP 192.168.0.222.80 > 192.168.0.86.48280: Flags [S.], seq 3324728961, ack 1903210291, win 14480, options [mss 1460,sackOK,TS val 10961765 ecr 9037827,nop,wscale 6], length 0
E..
<..@.@..7.......V.P...+V.qp.3..8.f .........
..Ce........
06:48:20.838246 IP 192.168.0.86.48280 > 192.168.0.222.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 9037829 ecr 10961765], length 0
...V.......Pqp.
3.+V......}.....
......Ce
06:48:20.838478 IP 192.168.0.86.48280 > 192.168.0.222.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 9037829 ecr 10961765], length 0
...V.......Pqp.
3.+V......}.....
......Ce
06:48:20.838514 IP 192.168.0.86.48280 > 192.168.0.222.80: Flags [P.], seq 1:177, ack 1, win 229, options [nop,nop,TS val 9037829 ecr 10961765], length 176
E...G3@.@.p\...V.......Pqp.
3.+V............
......CeGET
/ HTTP/1.1
User
-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host:
192.168.0.222
Accept:
*/*

 

LVS集群分发不均

导致负载不均衡的原因可能有
1、如果通过keepalived管理ipvs,persistent参数的配置,可以注释解决
2、lvs自身会话保持参数-p 大公司尽量用cookie替代session
3、lvs调度算法导致
4、后端RS server的会话保持参数keepalive
5、访问量较少,不均衡更明显
6、用户发送的请求时间长短和请求资源多少大小因素

 

LVS故障排查思路

1、调度器配置规则
2、RS节点VIP绑定和arp抑制问题
3、RS节点服务是否正常
4、借助tcpdump,ping工具

 

 

通过keepalived管理ipvs配置(先清除上述配置)

lvs在keepalive配置文件中的设置
virtual_server
192.168.0.222 80 {
delay_loop
6  健康检查时间
lb_algo wrr
lb_kind DR
nat_mask
255.255.255.0
persistence_timeout
50  会话保持长导致负载不均
protocol TCP
real_server
192.168.0.82 80 {
weight
1
TCP_CHECK {
connect_timeout
8  超时时间
nb_get_retry
3    重试次数
delay_before_retry
3  重试间隔
connect_port
80
}
}
real_server
192.168.0.83 80 {
weight
1
TCP_CHECK {
connect_timeout
8
nb_get_retry
3
delay_before_retry
3
connect_port
80
}
}
}