HA Server :
nginx server
HA Cluster实现方案:
vrrp 协议的实现
keepalived
ais :完整的HA集群
heartbeat
corosync
keepalived:
vrrp 协议 : Virtual Redundant Routing Protocol
vrrp 协议的软件实现,原生设计的目的是为了高可用的ipvs服务
vrrp 协议完成地址流动
为VIP地址所在的节点生成ipvs规则(在配置文件中预先定义)
为ipvs集群的各RS做健康状态监测
基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务
有关keepalived术语:
虚拟路由器: Virtual Router
虚拟路由器标识: VRID(0-255)
物理路由器
master : 主设备
backup : 备用设备
priority : 优先级
VIP : Virtual IP
VMAC : Virtual MAC (23-de-99-01-22-VRID)
通告: 心跳,优先级,周期性
一些有关安全的方式:
认证: 简单的字符认证,MD5
无认证
工作模式:
主/备 : 但虚拟路径器
主/主 : 主/备(虚拟路径器1), 备/主(虚拟路径器2)
组件:
核心组件:
vrrp stack
ipvs wrapper
checkers
控制组件: 配置文件分析器
IO 复用器
内存管理组件
HA Cluster的配置前提
(1) 各节点的时间必须同步 : ntp , chrony
(2) 确保iptables 及 selinux不会成为阻碍
(3) 各节点之间可通过主机名互相通信(对KA 并非必须),建议使用 /etc/hosts文件实现
(4) 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信(非必须)
keepalived 安装配置:
从centos 6.4 以上就开始收录在base源中
程序环境:
配置文件:/etc/keepalived/keepalived.conf
主程序:/usr/sbin/keepalived
Unit File:keepalived.service
单主配置示例:
! Configuration File for keepalived
global_defs {
notification_email { #邮件目的地方
root@localhost
}
notification_email_from keepalived@localhost #邮件发送方
smtp_server 12 7.0.0.1 #邮件服务器,端口25
smtp_connect_timeout 30 #邮件服务器连接超时
router_id node1 #路由器的物理标识符
vrrp_mcast_group4 224.0.41.41 # vrrp 多播地址
}
vrrp_instance VI_1 { #vrrp 实例配置
state BACKUP #bakcup模式,备keepalived服务器
interface eno16777736 #将当前虚拟路由器绑定eno16777736 物理接口
virtual_router_id 14 #虚拟路由器的唯一ID
priority 98 #优先级
advert_int 1 #vrrp 通告时间间隔
authentication { #认证
auth_type PASS
auth_pass 571f97b2 #加密密码 openssl rand -hex 4 认证密钥不能超过8个字符,超过8个只对前8位有效,最好使用随机生成的字符串
}
virtual_ipaddress { #虚拟路由器要转移的ip
10.1.0.91/16 dev eno16777736 # 要转移的ip及绑定的物理接口
}
}
vrrp_mcast_group4 224.0.41.41
keepalived 就是通过多播地址实现的
如果有MULTICAST说明该网卡支持多播,否则需要 ip link set dev eno33554984 multicast on
配置语法:
配置虚拟路由器:
vrrp_instance <STRING>{
...
}
专用参数:
state MASTER|BACKUP : 当前节点再此虚拟路由器上的初始状态,只能有一个是MASTER,余下的都是BACKUP
interface IFACE_NAME : 绑定为当前虚拟路由器使用的物理接口
virtual_route_id VRID : 当前虚拟路由器的唯一标识,范围是0-255
priority 100 : 当前主机在此虚拟路径器中的优先级,范围1-254
advent_int 1 : vrrp 通告的时间间隔
authentication {
auth_type AH|PASS
auth_pass <PASSWORD>
}
virtual_ipaddress{
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18/24 dev eth2 label eth2:1
}
track_interface {
eth0
eth1
...
}
配置要监控的网络接口,一旦接口出现故障,则转为FAULT状态;
nopreempt:定义工作模式为非抢占模式;
preempt_delay 300:抢占式模式下,节点上线后触发新选举操作的延迟时长;
定义通知脚本:
notify_master <STRING>|<QUOTED-STRING>:当前节点成为主节点时触发的脚本;
notify_backup <STRING>|<QUOTED-STRING>:当前节点转为备节点时触发的脚本;
notify_fault <STRING>|<QUOTED-STRING>:当前节点转为“失败”状态时触发的脚本;
notify <STRING>|<QUOTED-STRING>:通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知;
双主模型示例
连个转移ip,同时被一个域名解析,还可以实现负载均衡
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.100.19
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
virtual_router_id 14
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 571f97b2
}
virtual_ipaddress {
10.1.0.91/16 dev eno16777736
}
}
vrrp_instance VI_2 {
state BACKUP
interface eno16777736
virtual_router_id 15
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 578f07b2
}
virtual_ipaddress {
10.1.0.92/16 dev eno16777736
}
}
示例通知脚本:
#!/bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(hostname) to be $1, vip floating"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
脚本的调用方法:
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
虚拟服务器:
配置参数:
virtual_server IP port | virtual_server fwmark int
{
...
real_server {
...
}
...
}
常用参数:
delay_loop <INT> : 服务轮询的时间间隔
lb_algo rr|wrr|wlc|lblc|sh|dh : 定义调度的方法
lb_kind NAT|DR | TUN : 集群的类型
persistence_timeout <INT> : 持久连接时长
protocol TCP : 服务协议,仅支持TCP
sorry_server <IPADDR> <PORT> : 备用服务器地址
real_server <IPADDR> <PORT>
{
weight <INT> : 权重
notify_up <STRING> | <QUOTEN-STRING>
notify_down <STRING> | <QUOTEN-STRING>
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK{...} : 定义当前主机的健康状态检测方法;
}
HTTP_GET | SSL_GET {
url {
path <URL_PATH> : 定义要检测的URL
status_code <INT> : 判断上述检测机制为健康状态的响应码
digest <STRING> : 判断上述检测机制为健康状态的响应的内容的校验码
}
nb_get_retry <INT> : 重试次数
delay_before_retry <INT> : 重试之前的延迟时长
connect_ip <IP ADDRESS> :向当前RS的哪个ip地址发起健康状态检测请求
connect_port <PORT> :向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS> :发出健康状态检测请求时使用的源地址;
bind_port <PORT> :发出健康状态检测请求时使用的源端口;
connect_timeout <INTEGER> :连接请求的超时时长;
}
TCP_CHECK {
connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求
connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址;
bind_port <PORT>:发出健康状态检测请求时使用的源端口;
connect_timeout <INTEGER>:连接请求的超时时长;
}
高可用的ipvs集群示例:
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.100.19
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
virtual_router_id 14
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 571f97b2
}
virtual_ipaddress {
10.1.0.93/16 dev eno16777736
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 10.1.0.93 80 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.1.0.69 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.1.0.71 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
}
keepalived 调用外部的辅助脚本进行资源监控,并根据监控的结果状态实现有限动态调整
分两步
(1)先定义一个脚本
(2)调用此脚本
vrrp_script <SCRIPT_NAME> {
script ""
interval INT
weight -INT
}
track_script {
SCRIPT_NAME_1
SCRIPT_NAME_2
...
}
示例:高可用的nginx服务
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.100.19
}
vrrp_script chk_down {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" #成功返回值为0
interval 1 #每个1秒执行一次
weight -5 #失败权重减去一个数值
}
vrrp_script chk_nginx {
script "killall -0 nginx && exit 0 || exit 1"
interval 1
weight -5
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
virtual_router_id 14
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 571f97b2
}
virtual_ipaddress {
10.1.0.93/16 dev eno16777736
}
track_script { #调用前面定义过的脚本
chk_down
chk_nginx
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}