### 安装Keepalived
```bash
yum install keepalived -y
```
 
### 使用简单的failover
参考:https://docs.oracle.com/cd/E37670_01/E41138/html/section_uxg_lzh_nr.html
典型的Keepalived高可用性配置包括一个主服务器和一个或多个备份服务器。一个或多个虚拟IP地址(定义为VRRP实例)被分配给主服务器的网络接口,以便它可以为网络客户端提供服务。备份服务器侦听主服务器定期发送的组播VRRP通告报文。默认广告时间间隔为一秒。如果备份节点无法接收三个连续的VRRP通告,则具有最高分配优先级的备份服务器将接管主服务器,并将虚拟IP地址分配给其自己的网络接口。如果多个备份服务器具有相同的优先级,则具有最高IP地址值的备份服务器将成为主服务器
以下示例使用Keepalived在两台服务器上实现简单的故障转移配置。一台服务器充当主服务器,另一台服务器充当备份服务器,主服务器的优先级高于备份服务器。
显示虚拟IP地址10.0.0.100最初如何分配给主服务器(10.0.0.71)。当主服务器发生故障时,备份服务器(10.0.0.72)将成为新的主服务器,并被分配虚拟IP地址10.0.0.100。
 

 
#### master配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr1@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_instance VRRP1 {
state MASTER
# Specify the network interface to which the virtual address is assigned
interface eth0
# The virtual router ID must be unique to each VRRP instance that you define
virtual_router_id 41
# Set the value of priority higher on the master server than on a backup server
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1066
}
virtual_ipaddress {
10.0.0.100/24
}
}
```
 
#### backup配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr2@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_instance VRRP1 {
state BACKUP
# Specify the network interface to which the virtual address is assigned
interface eth0
virtual_router_id 41
# Set the value of priority lower on the backup server than on the master server
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1066
}
virtual_ipaddress {
10.0.0.100/24
}
}
```
如果主服务器(svr1)发生故障,keepalived会将虚拟IP地址10.0.0.100/24分配给备份服务器(svr2)上的eth0接口,该服务器将成为主服务器。
#### 查看master网卡分配的VIP
```bash
ip addr list eth0
```
```
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:cb:a6:8d brd ff:ff:ff:ff:ff:ff
inet 10.0.0.72/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.100/24 scope global eth0
inet6 fe80::a00:27ff:fecb:a68d/64 scope link
valid_lft forever preferred_lft forever
```
#### 查看backup日志
```bash
tail -f /var/log/messages
```
```
...51:55 ... VRRP_Instance(VRRP1) Entering BACKUP STATE
...
...53:08 ... VRRP_Instance(VRRP1) Transition to MASTER STATE
...53:09 ... VRRP_Instance(VRRP1) Entering MASTER STATE
...53:09 ... VRRP_Instance(VRRP1) setting protocol VIPs.
...53:09 ... VRRP_Instance(VRRP1) Sending gratuitous ARPs on eth0 for 10.0.0.100
```
 
### Keepalived负载均衡之NAT模式(双网卡场景)
以下示例在NAT模式下使用Keepalived在两台服务器上实现简单的故障转移和负载平衡配置。一台服务器充当主服务器,另一台服务器充当备份服务器,主服务器的优先级高于备份服务器。每个服务器都有两个网络接口,其中一个接口连接到面向外部网络(192.168.1.0/24)的一侧,另一个接口连接到内部网络(10.0.0.0/24),其中两个Web服务器可以访问。
 

 
#### master配置
此配置类似“使用简单的failover”,增加了vrrp_sync_group部分,以便在故障转移时将网络接口一起分配,并使用virtual_server部分定义真实的后备Keepalived用于负载平衡的终端服务器。 lb_kind的值设置为NAT(网络地址转换),这意味着Keepalived服务器代表后端服务器处理来自客户端的入站和出站网络流量。
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr1@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_sync_group VRRP1 {
# Group the external and internal VRRP instances so they fail over together
group {
external
internal
}
}
vrrp_instance external {
state MASTER
interface eth0
virtual_router_id 91
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
# Define the virtual IP address for the external network interface
virtual_ipaddress {
192.168.1.1/24
}
}
vrrp_instance internal {
state MASTER
interface eth1
virtual_router_id 92
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
# Define the virtual IP address for the internal network interface
virtual_ipaddress {
10.0.0.100/24
}
}
# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
delay_loop 10
protocol TCP
# Use round-robin scheduling in this example
lb_algo rr
# Use NAT to hide the back-end servers
lb_kind NAT
# Persistence of client sessions times out after 2 hours
persistence_timeout 7200
real_server 10.0.0.71 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
real_server 10.0.0.72 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
}
```
 
#### backup配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr2@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_sync_group VRRP1 {
# Group the external and internal VRRP instances so they fail over together
group {
external
internal
}
}
vrrp_instance external {
state BACKUP
interface eth0
virtual_router_id 91
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
# Define the virtual IP address for the external network interface
virtual_ipaddress {
192.168.1.1/24
}
}
vrrp_instance internal {
state BACKUP
interface eth1
virtual_router_id 92
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
# Define the virtual IP address for the internal network interface
virtual_ipaddress {
10.0.0.100/24
}
}
# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
delay_loop 10
protocol TCP
# Use round-robin scheduling in this example
lb_algo rr
# Use NAT to hide the back-end servers
lb_kind NAT
# Persistence of client sessions times out after 2 hours
persistence_timeout 7200
real_server 10.0.0.71 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
real_server 10.0.0.72 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
}
```
 
#### 防火墙配置
如果将Keepalived配置为使用NAT模式与内部网络上的服务器进行负载平衡,则Keepalived服务器将处理所有入站和出站网络流量,并通过重写真实服务器的源IP地址来隐藏后端服务器,使用外部网络接口的虚拟IP地址在传出数据包。
开启IP伪装(master/backup)
```bash
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
service iptables save
```
允许网卡之间的转发(master/backup)
```bash
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited
service iptables save
```
开放端口(以HTTP为例)
```bash
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
service iptables save
```
 
#### 创建VIP的路由(后端服务器)
```bash
ip route add default via 10.0.0.100 dev eth0
ip route show
```
```
default via 10.0.0.100 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.71
```
永久生效
```bash
echo "default via 10.0.0.100 dev eth0" > /etc/sysconfig/network-scripts/route-eth0
```
 
### Keepalived负载均衡之NAT模式(单网卡场景)
`注意:不能在同一网段直接访问虚拟IP,因为真实服务针对客户端发来的数据包,应答的时候不会经过keepalived(数据包不需要路由),改不了数据包,所以访问不了。如果keepalived和真实主机处于同一内网推荐使用DR模式,代理性能更高,此处仅为实验,为了更深入理解。`
此配置类似“Keepalived负载均衡之NAT模式(双网卡场景)”

 
#### master配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
! Configuration File for keepalived
global_defs {
notification_email {
test01@ynotes.cn
}
notification_email_from haproxy1@ynotes.cn
smtp_server localhost
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict #严格执行VRRP协议规范,此模式不支持节点单播,注销该参数
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface enp0s3
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.50.240
}
}
virtual_server 192.168.50.240 5555 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.50.251 5555 {
weight 1
TCP_CHECK {
connect_port 5555
connect_timeout 3
}
}
real_server 192.168.50.252 5555 {
weight 1
TCP_CHECK {
connect_port 5555
connect_timeout 3
}
}
}
```
 
#### backup配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
! Configuration File for keepalived
global_defs {
notification_email {
test01@ynotes.cn
}
notification_email_from haproxy2@ynotes.cn
smtp_server localhost
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict #严格执行VRRP协议规范,此模式不支持节点单播,注销该参数
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface enp0s3
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.50.240
}
}
virtual_server 192.168.50.240 5555 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.50.251 5555 {
weight 1
TCP_CHECK {
connect_port 5555
connect_timeout 3
}
}
real_server 192.168.50.252 5555 {
weight 1
TCP_CHECK {
connect_port 5555
connect_timeout 3
}
}
}
```
 
#### 开启端口转发(master/backup)
```bash
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
```
```
net.ipv4.ip_forward = 1
```
 
#### 防火墙配置
对后端服务器的流量进行转发
开启SNAT(master/backup)
```bash
iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.50.251/32 -j SNAT --to-source 192.168.50.240 #对源地址为192.168.50.251的数据包替换源地址为192.168.50.240
iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.50.252/32 -j SNAT --to-source 192.168.50.240
service iptables save #永久保存配置
```
 
#### 修改默认网关(后端服务器)
```bash
vim /etc/sysconfig/network-scripts/ifcfg-enp0s3 #修改默认网关
```
```bash
GATEWAY0=192.168.50.240 #这里配置成VIP地址
```
```bash
systemctl restart network #重启网卡
ip route #查看路由信息
```
```
default via 192.168.50.240 dev enp0s3 proto static metric 100
172.10.0.0/24 dev br-975d989973b4 proto kernel scope link src 172.10.0.1
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev br-b64efd3fb71e proto kernel scope link src 172.18.0.1
172.20.0.0/16 dev docker_gwbridge proto kernel scope link src 172.20.0.1
192.168.50.0/24 dev enp0s3 proto kernel scope link src 192.168.50.252 metric 100
192.168.100.0/24 dev br-ea58d9f6ef1f proto kernel scope link src 192.168.100.1
```
 
### Keepalived负载均衡之DR模式
以下示例在直接路由(DR)模式下使用Keepalived在两台服务器上实现简单的故障转移和负载平衡配置。一台服务器充当主服务器,另一台服务器充当备份服务器,主服务器的优先级高于备份服务器。每个Keepalived服务器都有一个网络接口,服务器连接到同一网段(10.0.0.0/24),可以访问两个Web服务器。
下图显示Keepalived主服务器具有网络地址10.0.0.11和10.0.0.1(虚拟)。 Keepalived备份服务器的网络地址为10.0.0.12。 Web服务器websvr1和websvr2分别具有网络地址10.0.0.71和10.0.0.72。此外,两个Web服务器都配置了虚拟IP地址10.0.0.1,以使它们接受具有该目标地址的数据包。主服务器接收传入请求并重定向到Web服务器,Web服务器直接响应。
 

#### master配置
类似“Keepalived负载均衡之NAT模式”的配置,但lb_kind的值设置为DR(直接路由),这意味着Keepalived服务器处理来自的所有入站网络包,出站网络包由后端服务器直接回复客户端,绕过Keepalived服务器。此配置减少了Keepalived服务器上的负载,但安全性较低,因为每个后端服务器都需要外部访问。某些实现使用额外的网络接口,每个Web服务器都有一个专用网关来处理响应网络包。
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr1@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_instance external {
state MASTER
interface eth0
virtual_router_id 91
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
virtual_ipaddress {
10.0.0.1/24
}
}
virtual_server 10.0.0.1 80 {
delay_loop 10
protocol TCP
lb_algo rr
# Use direct routing
lb_kind DR
persistence_timeout 7200
real_server 10.0.0.71 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
real_server 10.0.0.72 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
}
```
 
#### backup配置
```bash
vim /etc/keepalived/keepalived.conf
```
```ini
global_defs {
notification_email {
root@mydomain.com
}
notification_email_from svr2@mydomain.com
smtp_server localhost
smtp_connect_timeout 30
}
vrrp_instance external {
state BACKUP
interface eth0
virtual_router_id 91
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1215
}
virtual_ipaddress {
10.0.0.1/24
}
}
virtual_server 10.0.0.1 80 {
delay_loop 10
protocol TCP
lb_algo rr
# Use direct routing
lb_kind DR
persistence_timeout 7200
real_server 10.0.0.71 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
real_server 10.0.0.72 80 {
weight 1
TCP_CHECK {
connect_timeout 5
connect_port 80
}
}
}
```
 
#### 防火墙配置
开启服务端口,以http服务为例(master/backup)
```bash
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
service iptables save
```
 
#### 后端服务器(RS)配置
```bash
echo "net.ipv4.conf.lo.arp_ignore = 1" >> /etc/sysctl.conf #只响应目的IP地址为接收网卡上的本地地址的arp请求
echo "net.ipv4.conf.lo.arp_announce = 2" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.arp_ignore = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.arp_announce = 2" >> /etc/sysctl.conf
sysctl -p
```
```
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
```
```bash
echo "ifconfig lo:0 10.0.0.1 broadcast 10.0.0.255 netmask 255.255.255.255 up" >> /etc/rc.local
ifconfig lo:0 10.0.0.1 broadcast 10.0.0.255 netmask 255.255.255.255 up
ip addr show lo
```
```
2: lo: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:cb:a6:8d brd ff:ff:ff:ff:ff:ff
inet 10.0.0.72/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.1/24 brd 10.0.0.255 scope global secondary eth0
inet6 fe80::a00:27ff:fecb:a68d/64 scope link
valid_lft forever preferred_lft forever
```