首页 » keepalived » 正文

CentOS下安装keepalived

软件名版本号
CentOS7.8.2003
keepalived2.1.5
nginx1.16.1
节点名IP地址
node110.0.190.110
node210.0.190.111
VIP10.0.190.250

1、yum方式安装

yum方式安装的版本比较老,直接执行yum install keepalived安装即可。

2、源码方式安装

###下载源码,当前时间最新版是2.1.5
cd /tmp
[ -x /usr/bin/wget ]||yum install wget -y
wget https://www.keepalived.org/software/keepalived-2.1.5.tar.gz
###编译安装
yum install gcc gcc-c++ make libnl3-devel pcre-devel openssl openssl-devel -y
tar -xf keepalived-2.1.5.tar.gz
cd keepalived-2.1.5
./configure --prefix=/usr/local/keepalived
make -j $(grep 'processor' /proc/cpuinfo | wc -l)
make install
###复制默认配置文件到/etc目录
cp -fr /usr/local/keepalived/etc/keepalived/ /etc/
cd /etc/keepalived
mv keepalived.conf keepalived.conf.bak
touch keepalived.conf

3、安装nginx

##在节点1和节点二下分别执行以下命令安装nginx
rpm -ql epel-release >> /dev/null||yum install epel-release
yum install nginx -y

##配置防火墙
firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --reload

##修改nginx默认页面
echo "This is a defalut web page from `hostname -I`" > /usr/share/nginx/html/index.html

##启动nginx服务
systemctl enable --now nginx

4、配置keepalived

节点1

cd /etc/keepalived

local_ip=10.0.190.110
backup_ip=10.0.190.111
VIP=10.0.190.250
service_name=nginx
process_name=nginx
weight=110
virtual_router_id=`echo ${VIP}|awk -F "." '{print $NF}'`
network_card_name=`cat $(ls /etc/sysconfig/network-scripts/ifcfg-*|grep -v ifcfg-lo)|grep NAME|awk -F '=' '{print $2}'|head -n 1`

###keepalived基本配置
cat >> keepalived.conf << EOF
global_defs {
   router_id LVS_SERVER
}

vrrp_script check_${service_name} {
    script "/etc/keepalived/check_${service_name}.sh"
    interval 3
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP
    #非抢占模式
    nopreempt
    interface ${network_card_name}
    virtual_router_id ${virtual_router_id}
    priority ${weight}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    unicast_src_ip ${local_ip}
    unicast_peer {
        ${backup_ip}
    }
    virtual_ipaddress {
        ${VIP}/24 dev ${network_card_name} label ${network_card_name}:0
    }

    track_script {
        check_${service_name}
    }
}
EOF

#配置服务检测脚本,注意脚本中的#!/bin/bash一行不可丢失不可错误,不然keepalived会报错
#错误内容为command '/etc/keepalived/check_nginx.sh', error 8: Exec format error
touch check_${service_name}.sh
cat >> check_${service_name}.sh << EOF
#!/bin/bash
if [ \$(ps -C ${process_name} --no-header | wc -l) -eq 0 ]; then
    systemctl stop keepalived
fi
EOF
chmod +x check_${service_name}.sh

###配置防火墙
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ${network_card_name} --destination ${backup_ip} --protocol vrrp -j ACCEPT
firewall-cmd --reload

节点2

cd /etc/keepalived

local_ip=10.0.190.111
backup_ip=10.0.190.110
VIP=10.0.190.250
service_name=nginx
process_name=nginx
weight=100
virtual_router_id=`echo ${VIP}|awk -F "." '{print $NF}'`
network_card_name=`cat $(ls /etc/sysconfig/network-scripts/ifcfg-*|grep -v ifcfg-lo)|grep NAME|awk -F '=' '{print $2}'|head -n 1`

cat >> keepalived.conf << EOF
global_defs {
   router_id LVS_SERVER
}

vrrp_script check_${service_name} {
    script "/etc/keepalived/check_${service_name}.sh"
    interval 3
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP
    nopreempt
    interface ${network_card_name}
    virtual_router_id ${virtual_router_id}
    priority ${weight}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    unicast_src_ip ${local_ip}
    unicast_peer {
        ${backup_ip}
    }
    virtual_ipaddress {
        ${VIP}/24 dev ${network_card_name} label ${network_card_name}:0
    }

    track_script {
        check_${service_name}
    }
}
EOF

#service check script
touch check_${service_name}.sh
cat >> check_${service_name}.sh << EOF
#!/bin/bash
if [ \$(ps -C ${process_name} --no-header | wc -l) -eq 0 ]; then
    systemctl stop keepalived
fi
EOF
chmod +x check_${service_name}.sh

###配置防火墙
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ${network_card_name} --destination ${backup_ip} --protocol vrrp -j ACCEPT
firewall-cmd --reload

分别在节点1和节点2上启动keepalived服务

systemctl enable --now keepalived

5、验证

###安装抓包工具
yum install tcpdump -y

tcpdump:
-a:尝试将网络和广播地址转换成名称;
-c<数据包数目>:收到指定的数据包数目后,就停止进行倾倒操作;
-d:把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出;
-dd:把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出;
-ddd:把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出;
-e:在每列倾倒资料上显示连接层级的文件头;
-f:用数字显示网际网络地址;
-F<表达文件>:指定内含表达方式的文件;
-i<网络界面>:使用指定的网络截面送出数据包;
-l:使用标准输出列的缓冲区;
-n:不把主机的网络地址转换成名字;
-N:不列出域名;
-O:不将数据包编码最佳化;
-p:不让网络界面进入混杂模式;
-q :快速输出,仅列出少数的传输协议信息;
-r<数据包文件>:从指定的文件读取数据包数据;
-s<数据包大小>:设置每个数据包的大小;
-S:用绝对而非相对数值列出TCP关联数;
-t:在每列倾倒资料上不显示时间戳记;
-tt: 在每列倾倒资料上显示未经格式化的时间戳记;
-T<数据包类型>:强制将表达方式所指定的数据包转译成设置的数据包类型;
-v:详细显示指令执行过程;
-vv:更详细显示指令执行过程;
-x:用十六进制字码列出数据包资料;
-w<数据包文件>:把数据包数据写入指定的文件。

###节点1
[root@linux110 ~]# tcpdump -i ens32 -vn host 10.0.190.111
tcpdump: listening on ens32, link-type EN10MB (Ethernet), capture size 262144 bytes
21:15:37.847983 IP (tos 0xc0, ttl 255, id 598, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
21:15:38.932493 IP (tos 0xc0, ttl 255, id 599, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
21:15:40.016913 IP (tos 0xc0, ttl 255, id 600, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel

###节点2
[root@linux111 ~]# tcpdump -i ens32 -vn host 10.0.190.110
tcpdump: listening on ens32, link-type EN10MB (Ethernet), capture size 262144 bytes
21:17:20.227806 IP (tos 0xc0, ttl 255, id 642, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
21:17:21.228918 IP (tos 0xc0, ttl 255, id 643, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
21:17:22.229820 IP (tos 0xc0, ttl 255, id 644, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
21:17:23.230913 IP (tos 0xc0, ttl 255, id 645, offset 0, flags [none], proto VRRP (112), length 40)
    10.0.190.111 > 10.0.190.110: vrrp 10.0.190.111 > 10.0.190.110: VRRPv2, Advertisement, vrid 250, prio 110, authtype simple,intvl 1s, length 20, addrs: 10.0.190.250 auth "123456^@^@"
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel

###查看网卡信息,节点1
[root@linux110 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:ac:3d:2d brd ff:ff:ff:ff:ff:ff
    inet 10.0.190.110/24 brd 10.0.190.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet 10.0.190.250/24 scope global secondary ens32:0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feac:3d2d/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
模拟服务宕机
###访问VIP所在的服务器的nginx页面
root@debian-manager:~# curl 10.0.190.250
This is a defalut web page from 10.0.190.110

###节点1重启keepalived服务测试VIP漂移情况
systemctl restart keepalived

###再次访问VIP所在的服务器的nginx页面
root@debian-manager:~# curl 10.0.190.250
This is a defalut web page from 10.0.190.111

###VIP能正常漂移

###模拟nginx服务挂掉,节点2上操作(现在VIP在节点2上)
systemctl stop nginx

###测试VIP漂移情况
root@debian-manager:~# curl 10.0.190.250
This is a defalut web page from 10.0.190.110

###节点2查看keepalived服务状态
[root@linux111 keepalived]# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since 六 2020-09-12 21:27:15 CST; 3min 54s ago
  Process: 30631 ExecStart=/usr/local/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 30632 (code=exited, status=0/SUCCESS)

###脚本执行正常
非抢占模式下,主备节点的state均为BACKUP,非抢占模式主要是为了避免MASTER宕机恢复后因为权重更高又抢占回VIP导致的业务暂时性中断的时候采用,非抢占模式在主备节点硬件配置一样或者差异不大的时候使用比较合适,如果主备节点硬件配置差异较大,比较建议MASTER节点在配置更高的服务器上。
针对于非抢占模式,检测脚本需要执行停止keepalived服务动作,降低权重并不会生效,待服务器故障恢复之后再手动启动keepalived服务即可。
而如果是抢占模式下,则可以通过降低权重的方式来进行VIP的漂移,此时检测脚本可通过exit 1或者return 1等方式将脚本执行结果变成非0,keepalived检测到脚本执行后返回值非0时将会降低权重然后进行VIP的漂移,待服务恢复后又重新恢复

6、一键安装脚本

#!/bin/bash
#purpose:install the keepalived latest version from source
#support: CentOS 7 or CentOS 8
#url:yisca.cn
#date:2020年9月10日
#by:波仔

function Check_OS (){
if  grep -Eq "CentOS" /etc/*-release; then
    OS=CentOS
  else
    echo "没有找到支持的操作系统,脚本仅支持CentOS"
    exit 1
fi

case ${OS} in
  CentOS)
    if [ -f /etc/centos-release ]; then
      Os_Version=`cat /etc/centos-release|awk '{print $4}'`
    elif [ -f /etc/system-release ]; then
      Os_Version=`cat /etc/system-release|awk '{print $4}'`
    fi
esac

}

Check_OS

Make_Install () {
make -j $(grep 'processor' /proc/cpuinfo | wc -l)
if [ $? -ne 0  ]
  then
   make
fi
make install
}

cd /tmp
curl -O https://www.keepalived.org/download.html
if [ ! $? -eq 0 ]
  then
    echo "访问keepalived官方网站失败,请检查网络"
    sleep 5
    exit 1
fi

rpm -ql epel-release > /dev/null
if [ ! $? -eq 0 ]
  then
  yum install epel-release -y
fi

[ -x /usr/bin/aria2c ] || yum install aria2 -y

latest_version=`cat download.html |grep '<a href="software/'|awk 'NR==1{print}'|awk -F 'keepalived-' '{print $NF}'|awk -F '.tar' '{print $1}'`
download_url="https://www.keepalived.org/software/keepalived-${latest_version}.tar.gz"
aria2c -s16 -x16 -k1M ${download_url}

tar -xf keepalived-${latest_version}.tar.gz
if [ ! $? -eq 0 ]
  then
    echo "下载keepalived源码失败,请检查网络"
    sleep 5
    exit 1
fi
yum install gcc gcc-c++ make libnl3-devel pcre-devel openssl openssl-devel -y
cd keepalived-${latest_version}
./configure --prefix=/usr/local/keepalived
Make_Install
#cp keepalived/keepalived.service /usr/lib/systemd/system

mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
systemctl enable keepalived
cd /tmp
rm -fr keepalived* download.html

###初始化keepalived,默认2台服务器做主备,采用单播模式,非抢占模式

function init_keepalived () {
echo -e "\n"
echo "Keepalived is being initialized. "
echo "By default, 2 servers are active and standby."
echo "using unicast mode and non-preemptive mode"
echo -e "\n"
sleep 5

network_card_name=`cat $(ls /etc/sysconfig/network-scripts/ifcfg-*|grep -v ifcfg-lo)|grep NAME|awk -F '=' '{print $2}'|head -n 1`

read -p "Please input the local ip address: " local_ip
read -p "Please input another server's ip address: " backup_ip
read -p "Please input the virtual ip address: " VIP
read -p "Please input the service name: " service_name
read -p "Please input the service's process name: " process_name
#read -p "Please input the priority: " weight

weight=`echo ${local_ip}|awk -F "." '{print $NF}'`
virtual_router_id=`echo ${VIP}|awk -F "." '{print $NF}'`

cd /etc/keepalived
[ -f keepalived.conf ] && mv keepalived.conf keepalived.conf.bak
touch keepalived.conf

cat >> keepalived.conf << EOF
global_defs {
   router_id LVS_SERVER
}

vrrp_script check_${service_name} {
    script "/etc/keepalived/check_${service_name}.sh"
    interval 3
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP
    nopreempt
    interface ${network_card_name}
    virtual_router_id ${virtual_router_id}
    priority ${weight}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2ed6469783fe
    }
    unicast_src_ip ${local_ip}
    unicast_peer {
        ${backup_ip}
    }
    virtual_ipaddress {
        ${VIP}/24 dev ${network_card_name} label ${network_card_name}:0
    }

    track_script {
        check_${service_name}
    }
}
EOF

#service check script
touch check_${service_name}.sh
cat >> check_${service_name}.sh << EOF
#!/bin/bash
if [ \$(ps -C ${process_name} --no-header | wc -l) -eq 0 ]; then
    systemctl stop keepalived
fi
EOF
chmod +x check_${service_name}.sh

#firewalld
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ${network_card_name} --destination ${backup_ip} --protocol vrrp -j ACCEPT
firewall-cmd --reload

systemctl enable --now keepalived
echo -e "\n"
systemctl status keepalived|grep running >> /dev/null
[ $? -eq 0 ]&&echo "keepalived start successed."||echo "keepalived start failed."
}

echo -e "\n"
echo  "please choose  initialize the keepalived or not.[yes/no]"
echo  "The default is yes"
read -p "Please input your choose: " INIT

case ${INIT} in
  yes)
    init_keepalived
    ;;
  no)
    echo "Exit keepalived initialization,keepalived install complete."
    ;;
  *)
    init_keepalived
esac

发表评论