高可用集群说明
高可用集群架构图
Keepalived原理
专为LVS和HA设计的一款健康检查工具
支持故障自动切换
支持节点监控状态检查
Keepalived相关文件
keepalived # 软件包名
/usr/sbin/keepalived # 主程序文件
/etc/keepalived/keepalived.conf # 主配置文件
/usr/share/doc/keepalived # 配置文件示例
/lib/systemd/system/keepalived.service # Unit File
/etc/sysconfig/keepalived # Unit File的环境配置文件
功能
(1)基于VRRP协议完成地址流动
(2)为VIP地址所在的节点生成ipvs规则(在配置文件中预先定义)
(3)为ipvs集群的各RS做健康状态检测
(4)基于脚本调用接口完成脚本中定义的功能,从而影响集群事务,以此支持nginx、haproxy等服务
组件
1.用户空间核心组件
vrrp stack # VIP消息通告
checkers # 检测real server
system call # 标记real server权重
smtp # 邮件组件
ipvs wrapper # 生成ipvs规则
netlink reflector # 网络接口
watchdog # 监控进程
2.控制组件: 配置文件解析器
3.IO复用器
4.内存管理组件
Keepalived 的热备方案
VRRP虚拟路由冗余协议
一主 + 多备,共用同一个IP地址,但优先级不同
LVS-DR + Keepalived
构建过程
LVS - DR 搭建
#R-M:
eth0:0 10.0.0.100 ; eth0 10.0.0.11
#R-S:
eth0:0 10.0.0.100 ; eth0 10.0.0.12
#RS1:
lo:0 10.0.0.100 ; eth0 10.0.0.13
#RS2:
lo:0 10.0.0.100 ; eth0 10.0.0.14
#R-M 负载调度器搭建:
#关闭网卡守护进程
service NetworkManager stop
chkconfig NetworkManager off
#拷贝eth0网卡子接口充当集群入口接口
cd /etc/sysconfig/network-scripts/
cp -a ifcfg-eth0 ifcfg-eth0:0
vim !$
#删除mac/uuid和网卡类型
DEVICE=eth0:0
IPADDR=10.10.10.100
NETMASK=255.255.255.0
ifup eth0:0 #开启子接口
#关闭网卡重定向功能(优化)
vim /etc/sysctl.conf
#添加:
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
sysctl -p #刷新
#重载ipvs模式
modprobe ip_vs
#安装ipvsadm命令行工具
yum -y install ipvsadm
ipvsadm -v #查看当前ipvs集群内容
ipvsadm -A -t 虚拟IP:80 -s rr 添加ipvs TCP集群
ipvsadm -a -t 虚拟IP:80 -r 网站:80 -g #添加ipvsadm集群子节点
# -a 添加节点
# -r 指定真实服务器
# -g 代表的是DR模式
#执行命令:
ipvsadm -A -t 10.10.10.100:80 -s rr #rr轮询算法,
ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.13:80 -g
ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.14:80 -g
#保存ipvs集群内容至文件,进行持久化存储
service ipvsadm save
#设置为开机自启
chkconfig ipvsadm on
#apache服务器 RS1 RS2 搭建
#关闭网卡守护进程
service NetworkManager stop && chkconfig NetworkManager off
#拷贝环回接口的子接口
cd /etc/sysconfig/network-scripts
cp -a ifcfg-lo ifcfg-lo:0
vim !$
DEVICE=lo:0
IPADDR=10.10.10.100
NETMASK=255.255.255.255
#关闭对应ARP响应及公告功能
vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
sysctl -p #刷新
#开启环回网卡子接口
ipup lo:0
#添加路由记录,当访问虚拟iP(vip)时交给lo:0网卡
route add -host 10.10.10.100 dev lo:0
#添加到开机自启
echo "route add -host 10.10.10.100 dev lo:0" >> /etc/rc.local
#新建html测试页面,实验中使用不同的页面,生产环境应是相同网页
echo "this is server 1" >> /var/www/html/index.html
echo "this is server 2" >> /var/www/html/index.html
#开启httpd服务
service httpd start
#访问测试
[root@011 ~]# curl 10.10.10.100
this is server 2
[root@011 ~]# curl 10.10.10.100
this is server 1
Keepalived 搭建
负载调度器1 (D-M)搭建
#安装Keepalived 的依赖
yum -y install kernel-devel openssl-devel popt-devel gcc*
#将软件包上传到D-M负载调度器
#链接:https://pan.baidu.com/s/154EgDqAoN4lt32raGhZXGA 提取码:5vdh
#挂载iso文件
mkdir /mnt/iso1
mount -o loop Keepalived.iso /mnt/iso1/
cp -a /mnt/iso1/* ./ #拷贝软件包到当前目录
#解压软件包编译安装
tar -zxvf keepalived-1.2.2.tar.gz && cd keepalived-1.2.2
./configure --prefix=/ --with-kernel-dir=/usr/src/kernels/2.6.32...../
make && make install
#设置keepalived开机自启
chkconfig --add keepalived
chkconfig keepalived on
#修改keepalived的配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id R1
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.100
}
}
virtual_server 10.10.10.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 10.10.10.13 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 4
}
}
real_server 10.10.10.14 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 4
}
}
}
负载调度器2 (D-S)搭建
#安装Keepalived 的依赖
yum -y install kernel-devel openssl-devel popt-devel gcc*
#将软件包上传到D-M负载调度器
#链接:https://pan.baidu.com/s/154EgDqAoN4lt32raGhZXGA 提取码:5vdh
#挂载iso文件
mkdir /mnt/iso1
mount -o loop Keepalived.iso /mnt/iso1/
cp -a /mnt/iso1/* ./ #拷贝软件包到当前目录
#解压软件包编译安装
tar -zxvf keepalived-1.2.2.tar.gz && cd keepalived-1.2.2
./configure --prefix=/ --with-kernel-dir=/usr/src/kernels/2.6.32...../
make && make install
#设置keepalived开机自启
chkconfig --add keepalived
chkconfig keepalived on
#将负载调度器1的keepalived配置文件复制到当前服务器
scp /etc/keepalived/keepalived.conf root@10.10.10.12:/etc/keepalived/keepalived.conf
#编辑配置文件
state SLAVE
priority 30
#关闭网卡守护进程
service NetworkManager stop && chkconfig NetworkManager off
#拷贝网卡文件
cd /etc/sysconfig/network-scripts/
cp ifcfg-eth0 ifcfg-eth0:0
#vim ifcfg-eth0:0
DEVICE=eth0:0
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=10.10.10.100
NETMASK=255.255.255.0
#启动网卡
ifup eth0:0
#如果报错`Determining if ip address 10.10.10.100 is already in use for device eth0...
Error, some other host (00:0C:29:8F:96:CE) already uses address 10.10.10.100.`
#修改配置文件
vi /etc/sysconfig/network-script/ifup-eth
#注释掉255-259:
#if ! ARPING=$(/sbin/arping -c 2 -w ${ARPING_WAIT:-3} -D -I ${REALDEVICE} ${ipaddr[$idx]}) ; then ARPINGMAC=$(echo $ARPING | sed -ne 's/.*\[\(.*\)\].*/\1/p')
#net_log $"Error, some other host ($ARPINGMAC) already uses address ${ipaddr[$idx]}."
#exit 1
#fi
#编辑内核文件,防止相同网络地址广播冲突
#vim /etc/sysctl.conf
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
sysctl -p #刷新内核参数
modprobe ip_vs #加载内核
#安装ipvsadm管理工具
yum -y install ipvsadm
#开启keepalived
service keepalived start
#查看ipvsadm的集群内容
[root@011 network-scripts]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.10.10.100:80 rr persistent 50
-> 10.10.10.13:80 Route 1 0 0
-> 10.10.10.14:80 Route 1 0 0
#验证
#此时假设负载调度器1,也就是D-M节点宕机,访问网站10.10.10.100;在负载调度器2上查看ipvsadm的状态
HeartBeat + Nginx
说明
软件包:软件包版本为CentOS6系列,如果使用其他版本可以配置eperl源下载安装
环境准备
配置时间同步服务
配置主机名解析
安装nginx服务,编写nginx测试页面(实验中为了验证效果可用不同的页面)
#配置时间同步
#服务端 10.10.10.15
yum install -y ntp
# vim /etc/ntp.conf
restrict 10.10.10.0 mask 255.255.255.0 nomodify notrap
#注释掉原有的server 服务器地址,添加:
server 127.127.1.0
fudge 127.127.1.0 stratum 10
#开启ntpd服务,并设为开机自启
service ntpd start
chkconfig ntpd on
#客户端 10.10.10.16
yum -y install ntpdate
ntpdate -u 10.10.10.15
# 配置主机名解析 heartbeat 配置中需要用到主机名,主机名需要能使用 `uname -n` 获取到的
# 10.10.10.15
hostname nginx1
# vim /etc/sysconfig/network
HOSTNAME=nginx1
# vim /etc/hosts,添加:
10.10.10.15 nginx1
10.10.10.16 nginx2
# 10.10.10.16
hostname nginx2
# vim /etc/sysconfig/network
HOSTNAME=nginx2
# 安装nginx
# 将软件包上传到两个节点上
tar -zxvf nginx-1.17.10.tar.gz #解压缩
cd nginx-1.17.10
# 安装依赖
yum -y install pcre pcre-devel zlib zlib-devel gcc*
# 添加用户
useradd -r -s /sbin/nologin -M nginx
# 安装
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
make && make install
# 编写测试页面
rm -rf /usr/local/nginx/html/*
vim /usr/local/nginx/html/index.html
this is nginx 1 #nginx1
this is nginx 2 #nginx2
# 启动nginx
/usr/local/nginx/sbin/nginx
实验步骤
1.基础准备,两个节点执行
# 将hearbeat上传到服务器
# 解压缩,安装软件,拷贝配置文件
tar -zxvf heartbeat.tar.gz
cd heartbeat
yum -y install *
cd /usr/share/doc/heartbeat-3.0.4/
cp ha.cf authkeys haresources /etc/ha.d/
2.认证服务,节点之间的认证配置
# 主节点:
# 生成密钥随机数
dd if=/dev/random bs=512 count=1 |openssl md5
# 拷贝md5密钥到authkeys文件中
vim authkeys
auth 3
1 crc
2 sha1 HI!
3 md5 cfca93ad58c6f9cae732b40ef8b07310
# 修改权限
chmod 600 authkeys
# 修改主配置文件ha.cf
vim ha.cf
bcast eth0 #取消注释
# 添加一主一备节点,需要能被两台主机解析
node nginx1
node nginx2
# 配置haresources文件
vim haresourecs
nginx1 IPaddr::10.10.10.100/24/eth0:0
# 将主节点上的三个配置文件拷贝到从节点上
scp ha.cf authkeys haresources root@nginx2:/etc/ha.d/
chmod 600 /etc/ha.d/authkeys #从节点修改权限
# 启动服务并进行验证
# 主节点:
service heartbeat start
# 从节点
service heartbeat start
验证:
使用浏览器访问10.10.10.100,查看网页内容
此时,模拟主节点宕机(断开主节点的网络),等待一会,访问网页
但是这种模式的高可用有一问题,我们先将主节点进行恢复并重新启动HeartBeat
此时,我们只将主节点的nginx服务关闭pkill nginx
,验证heartbeat是否能完成切换
由此可见,nginx服务宕机heartbeat并不能自动的切换为从节点。
我们可以结合脚本应用和定时任务来监控nginx服务,nginx服务宕机后自动停止heartbeat服务完成主从切换
#!/bin/env bash
#name:nginx.sh
#date:2020-09-06
PWD=/server/scripts
URL="http://10.10.10.15/index.html"
HTTP_CODE=`curl -o /dev/null -s -w "%{http_code}" "${URL}"`
if [ $HTTP_CODE != 200 ];then service heartbeat stop;fi