LAN客户端判定哪个路由器应该为其到达目标主机的下一跳网关的方式有动态及静态决策两种方式,其中,常见的动态路由发现方式有如下几种: 1、Proxy ARP —— 客户端使用ARP协议获取其想要到达的目标,而后,由某路由以其MAC地址响应此ARP请求; 2、Routing Protocol —— 客户端监听动态路由更新(如通过RIP或OSPF协议)并以之重建自己的路由表; 3、ICMP IRDP (Router Discovery Protocol) 客户端 —— 客户端主机运行一个ICMP路由发现客户端程序;
动态路由发现协议的不足之处在于它会导致在客户端引起一定的配置和处理方面的开销,并且,如果路由器故障,切换至其它路由器的过程会比较慢。解决此类问题的一个方案是为客户端静态配置默认路由设备,这大大简化了客户端的处理过程,但也会带来单点故障类的问题。默认网关故障时,LAN客户端仅能实现本地通信。
VRRP可以通过在一组路由器(一个VRRP组)之间共享一个虚拟IP(VIP)解决静态配置的问题,此时仅需要客户端以VIP作为其默认网关即可。
图1显示了一个基本的VLAN拓扑,其中,Router A、B、C共同组成一个VRRP组,其VIP为10.0.0.1,配置在路由器A的物理接口上,因此A为master路由器,B和C为backup路由器。VRRP组中,master(路由器A)负责负责转发发往VIP地址的报文,客户端1、2、3都以此VIP作为其默认网关。一旦master故障,backup路由器B和C中具有最高优先级的路由器将成为master并接管VIP地址,而当原来的master路由器A重新上线时,其将重新成为master路由器。
VRRP是一个“选举”协议,它能够动态地将一个虚拟路由器的责任指定至同一个VRRP组中的其它路由器上,从而消除了静态路由配置的单点故障。
VRRP术语:
VRRP虚拟路由(VRRP router):
VRRP的优势:
冗余:可以使用多个路由器设备作为LAN客户端的默认网关,大大降低了默认网关成为单点故障的可能性; 负载共享:允许来自LAN客户端的流量由多个路由器设备所共享; 多VRRP组:在一个路由器物理接口上可配置多达255个VRRP组; 多IP地址:基于接口别名在同一个物理接口上配置多个IP地址,从而支持在同一个物理接口上接入多个子网; 抢占:在master故障时允许优先级更高的backup成为master; 通告协议:使用IANA所指定的组播地址224.0.0.18进行VRRP通告; VRRP追踪:基于接口状态来改变其VRRP优先级来确定最佳的VRRP路由器成为master;
IP地址拥有者(IP Address Owner):如果一个VRRP设备将虚拟路由器IP地址作为真实的接口地址,则该设备被称为IP地址拥有者。如果IP地址拥有者是可用的,通常它将成为Master。
keepalived主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。
keepalived 大致分为两层
1.用户空间 WatchDog:负载监控checkers和VRRP进程的状况 如果服务意外关闭 看门狗会自动重启服务 VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均衡器,则VRRP不是必须的。 Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。 IPVS wrapper:用户发送设定的规则到内核ipvs代码 Netlink Reflector:用来设定vrrp的vip地址等。 2.内核空间 包括ipvs(IP虚拟服务器,用于实现网络服务的负载均衡) 和netlink(提供高级路由及其他相关的网络功能)
Keepalived的所有功能是配置keepalived.conf文件来实现的。
简单来说keepalived提供高可用 在一个服务器挂掉之后可以迅速切换到应外一个服务器进行服务 为了让备用节点在某些情况下切换成主节点
如web服务器 在对外服务时最重要的两个元素 (争用的两个因素)
1.ip 因为web服务 我们主要就是靠ip来访问 所以如果主节点挂了 我们可以将此ip转移到备用的节点上 此时就可以靠备用的节点来作为访问服务的入口 这样就不会影响到对外服务 ip还是这个ip 只是用的设备发生了变化 对于客户来说 这对他们没有 影响
2.存储 (如果是文件系统 没有并发访问控制功能 有可能发生两个服务器同时写的情况 因为文件系统是将文件挂载到服务器上进行操作 通过将数据加载到内存中修改数据 如果有两台服务器 同时对该文贱进行操作 文件系统是不会察觉的 这样就会造成数据不一致 )(解决方法如 分布式文件系统 块级别的存储 的共享存储nfs san(存储局域网络) samba等等 )
但是keepalived 基本上不涉及存储
在做高可用的前提
1.保证主备服务器的时间同步 可以通过定义一个ntp server来做
2.保证iptables和selinux对实验不造成影响
3、(可选)各节点之间可通过主机名互相通信;
节点的名称设定与hosts文件中解析的主机名都要保持一致;
# uname -n 获得的主机,与解析的主机名要相同;
4、(可选)各节点之间基于密钥认证的方式通过ssh互信通信;
复制代码
keepalived的主配置文件 /etc/keepalived/keepalived.conf unit文件 /usr/lib/systemd/system/keepalived.service
keepalived 提供的高可用 例子
1.lvs的负载均衡高可用 在配置文件中直接配置即可 ! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected] smtp_connect_timeout 3
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_script chk_schedown { script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" 文件如果存在 则-2优先级 interval 2 2s检测一次 weight -2 }
vrrp_instance VI_1 {
interface eth0 #指明网卡 centos7中的网卡名有可能不是eth0 state MASTER
priority 101 virtual_router_id 51 garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
172.16.100.1/16 dev eth0 label eth0:0
}
track_script {
chk_schedown
}
复制代码
}
virtual_server 172.16.100.1 80 { 定义v-server delay_loop 6 健康检查间隔,单位为秒 lb_algo rr 负载均衡调度算法,一般用wrr、rr、wlc lb_kind dr 负载均衡转发规则。一般包括DR,NAT,TUN 3种 persistence_timeout 50 会话保持时间,会话保持,就是把用户请求转发给同一个服务器,不然刚在1上提交完帐号密码,就跳转到另一台服务器2上了 protocol TCP 指定协议为tcp
sorry_server 192.168.200.200 1358 添加一个备用服务器。当所有的RS都故障时sorry server生效
real_server 172.16.100.11 80 { 定义r-server
weight 1
HTTP_GET {
url { 根据url确认real-server是否存活
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 172.16.100.12 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
复制代码
}
如果要使用TCP_CHECK检测各realserver的健康状态,那么,上面关于realserver部分的定义也可以替换为如下内容: virtual_server 172.16.100.1 80 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 300 protocol TCP
sorry_server 127.0.0.1 80
real_server 172.16.100.11 80 {
weight 1
TCP_CHECK {
tcp_port 80
connect_timeout 3
}
}
real_server 172.16.100.12 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
}
}
复制代码
}
2.nginx的高可用
注释了lvs的相关配置 使用nginx负载均衡 nginx 爽主模型
1.主一 nginx配置
events { worker_connections 1024; }
http { log_format main 'remote_user [request" ' 'body_bytes_sent "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;
include /etc/nginx/conf.d/*.conf;
upstream webserver{
复制代码
server 192.168.117.129; server 192.168.117.133; }
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://webserver;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
复制代码
}
主1 keeplived配置
[root@node1 ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived
global_defs { notification_email { root@localhost
} notification_email_from ka@root smtp_server 127.0.0.1 smtp_connect_timeout 30 }
vrrp_ script chk_nginx{ script "killall -0 nginx &> /dev/null" interval 1 weight -2 }
vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass e7fa32a1 } virtual_ipaddress { 192.168.117.150/24 dev eno16777736 label eno1677736:0 } track_script{ chk_nginx }
notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
}
vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 151 priority 99 advert_int 1 authentication { auth_type PASS auth_pass e7fa32a2 } virtual_ipaddress { 192.168.117.155/24 dev eno16777736 label eno16777736:1 } track_script{ chk_nginx }
notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
}
2.主2 keepalive配置
[root@yunjisuandaniouck ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived
global_defs { notification_email { root@localhost
} notification_email_from ka@root smtp_server 127.0.0.1 smtp_connect_timeout 30 }
vrrp_ script chk_nginx{ script "killall -0 nginx &> /dev/null" interval 1 weight -2 }
vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 99 advert_int 1 authentication { auth_type PASS auth_pass e7fa32a1 } virtual_ipaddress { 192.168.117.150/24 dev ens33 label ens33:0 } track_script{ chk_nginx }
notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
}
vrrp_instance VI_2 { state MASTER interface ens33 virtual_router_id 151 priority 100 advert_int 1 authentication { auth_type PASS auth_pass e7fa32a2 } virtual_ipaddress { 192.168.117.155/24 dev ens33 label ens33:1 } track_script{ chk_nginx }
notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
}
主2 nginx配置
[root@yunjisuandaniouck ~]# cat /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_user [request" ' 'body_bytes_sent "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 webserver{ server 192.168.117.129; server 192.168.117.133; }
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
复制代码
proxy_pass http://webserver; }
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
复制代码
两个nginx 负载均衡一起工作 nginx1 ip为192.168.117.150 nginx2 的ip为192.168.117.155 不论访问哪一个都会根据定义的算法机制 调到响应的real-server 此时 如果有一台主机挂了 可以将这个提供服务的ip 转移到与之高可用的服务器上 这样使用 挂掉的哪个服务器的ip 同样可以访问到相应的服务 因为他们的nginx配置相同
总结: 1.日志? 自定义 2.每个vrrp_instance需要专用的组播地址 3.使用ip addr list 查看效果
4.7中可以用status查看keepalive状态信息 相当于日志
~]# cat /etc/keepalived/keepalived.conf
keepalived双主模型 在其中一个
! Configuration File for keepalived
global_defs { notification_email { root@localhost #指定邮件收件地址 } notification_email_from ka@root #邮件的发件人时谁? smtp_server 127.0.0.1 #指定邮件服务器 smtp_connect_timeout 30 #连接之后超时时间 }
vrrp_ script chk_nginx{ #定义的脚本文件 script "killall -0 nginx &> /dev/null" #killall -0的作用是看服务是否在线 interval 1 #一秒检查一次 weight -2 #执行失败后权重-2 }
vrrp_instance VI_1 { #vrrp实例一 state MASTER #指明主备 interface eno16777736 # 指明接口 virtual_router_id 51 #此处路由id 在有多换个vrrp实例时名字要不同 priority 100 #优先级 advert_int 1 #检查间隔,默认1秒 VRRP心跳包的发送周期 authentication { #定义认证方式 防止其他arp广播影响心跳认证 只有认证通过的心跳才会被接受 其他的都认为在耍流氓 auth_type PASS #认证方式为简单认证 auth_pass e7fa32a1 #认证密码 可以用openssl生成 防止和其他认证密码向冲突 } virtual_ipaddress { #虚拟地址 192.168.117.150/24 dev eno16777736 label eno1677736:0 } track_script{ #定义执行的脚本文件 chk_nginx }
notify_master "/etc/keepalived/notify.sh master" | notify_backup "/etc/keepalived/notify.sh backup" | 此三处指定的是配置脚本的所在地 和对应情况 执行的参数 在为主后传master给脚本文件 notify_fault "/etc/keepalived/notify.sh fault" |
}
vrrp_instance VI_2 { #实例2 state BACKUP interface eno16777736 virtual_router_id 151 priority 99 advert_int 1 authentication { auth_type PASS auth_pass e7fa32a2 } virtual_ipaddress { 192.168.117.155/24 dev eno16777736 label eno16777736:1 } track_script{ chk_nginx }
notify_master "/etc/keepalived/notify.sh master" 作用:当成为MASTER时,以指定的用户和组执行脚本。 notify_backup "/etc/keepalived/notify.sh backup" 作用:当成为BACKUP时,以指定的用户和组执行脚本。 notify_fault "/etc/keepalived/notify.sh fault" 作用:当该同步组Fault时,以指定的用户和组执行脚本。
}
下面主要用于定义lvs的负载均衡 virtual_server 192.168.200.100 443 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
real_server 192.168.201.100 443 {
weight 1
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc #基于特征码 认证 这样虽让很不错 但是如果改变了网站的一下code 那就要重新修改digest
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3 #连接超时时间为3s
nb_get_retry 3 尝试次数
delay_before_retry 3 在尝试前的延迟时间
}
}
复制代码
}
virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
sorry_server 192.168.200.200 1358
real_server 192.168.200.2 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.200.3 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
复制代码
}
virtual_server 10.10.10.3 1358 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
real_server 192.168.200.4 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.200.5 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
复制代码
}