keepalived实现双vip部署

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: keepalived实现双vip部署


Keepalived 是一个基于 VRRP 协议来实现的服务高可用方案,可以利用其来避免 IP 单点故障,一般与其它负载均衡技术(如 LVS 、HAProxy 、Nginx)一起工作来达到集群的高可用。Keepalived 是 LVS 的扩展项目, 因此它们之间具备良好的兼容性,可直接通过 Keepalived 的配置文件来配置 LVS。

相关术语

  • LB (Load Balancer 负载均衡)
  • HA (High Available 高可用)
  • Failover (失败切换)
  • Cluster (集群)
  • LVS (Linux Virtual Server Linux 虚拟服务器)
  • DS (Director Server),指的是前端负载均衡器节点
  • RS (Real Server),后端真实的工作服务器
  • VIP (Virtual IP),虚拟的 IP 地址,向外部直接面向用户请求,作为用户请求的目标的 IP 地址
  • DIP (Director IP),主要用于和内部主机通讯的 IP 地址
  • RIP (Real Server IP),后端服务器的 IP 地址
  • CIP (Client IP),访问客户端的 IP 地址
  1. 准备两台主机,四个IP:
192.168.100.226
192.168.100.224
192.168.100.201(VIP)
192.168.100.202(VIP)

2.安装keepalived

  • 通过 yum源进行安装
yum -y install keepalived
  • 通过源码安装

官方下载keepalived源码包

# 安装依赖
yum install -y libnfnetlink-devel zlib zlib-devel gcc gcc-c++ openssl openssl-devel openssh
tar -xf keepalived-2.1.0          # 解压安装包
cd keepalived-2.1.0               # 进入安装包
./config --prefix=/usr/local/keepalived      # 编译指定安装路径
make && make install   # 编译完成后进行安装
ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/      # 创建软连接
ls /usr/sbin/ | grep keepalived       
> keepalived
cd /usr/local/keepalived/etc/
cp -r keepalived /etc/keepalived
cp sysconfig/keepalived /etc/sysconfig/keepalived
  1. 修改配置

配置文件在/usr/local/keepalived目录下

vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   script_user root
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script chk_http_port {
        script "/data/shell/check.sh httpd"
        interval 0
        weight -2
vrrp_instance VI_1 {
    state BACKUP        # BACKUP为备
    interface eth0
    virtual_router_id 101
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.100.201 dev eth0 label eth0:1
    }
vrrp_instance VI_2 {      # 当有两个VIP时vrrp_instance应当区分开
    state MASTER        # MASTER为主
    interface eth0        # 工作接口
    virtual_router_id 102   # 虚拟路由ID,如果是一组虚拟路由就定义一个ID,如果是多组就要定义多个;
                  # 而且这个虚拟ID还是虚拟MAC最后一段地址的信息,取值范围0-255
    priority 100        # 定义优先级,数值越高,优先级越高
    advert_int 1        # 通告频率,秒
    track_interface {           # 监听的网卡,网卡故障马上切换vip
        eth0
        ens33
    }
    authentication {      # 通信机制,这里是明文,还有加密
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {       # 配置虚拟VIP,这里配置在网卡eth0,别名是eth0:2
        192.168.100.202 dev eth0 label eth0:2
    }
}

主机2的配置文件,只需修改参数

state BACKUP      # 主机1为MASTER时,主机2为BACKUP
priority 80       #  这里配置坚持master的优先级大于backup即可,根据state属性定义
  1. 启动keepalived
systemctl restart keepalived

  1. 另一台是没有vip

    停掉主机

    查看备机

配置监控脚本

vim check.sh
#!/bin/bash
Date=$(date "+%Y-%m-%d %H:%M:%S")
log_file="/var/log/keepalived.log"
check_process() {
if [ -z "$1" ]; then
    echo "进程名为空........"
    echo "[$Date] 执行脚本无参数......" >> $log_file
    exit
fi
process_status=`pidof $1`
if [ "$process_status" != "" ]; then
   return 10
   else:
   return 11
fi
}
check_process $1
if [ $? -eq 10 ]; then
    echo 0
    exit 0
    else
    echo "[$Date] 进程[$1]异常,正在准备重启....." >> $log_file
    count=0
    while (($count < 3))
    do
            ((count++))
        echo "[$Date] 尝试第$count次拉起进程$1......" >> $log_file
        systemctl restart $1  2&> /dev/null
        check_process $1
        if [ $? -eq 10 ]; then
            echo "[$Date] 进程$1已拉起......."  >> $log_file
            echo 0
            exit 0
        fi
    done
    echo 1
    echo "[$Date] 尝试拉起进程$1三次均失败......" >> $log_file
    systemctl stop keepalived
    exit 1
fi

调试脚本,脚本需要传参,传参为进程名

/bin/bash check_process.sh nginx
  • 创建用户keepalived_script
useradd keepalived_script

启动失败可查看keepalived日志

tail -f /var/log/messages

python的一键部署keepalived脚本

从下载源码包到修改配置启动服务

# encoding: utf-8
import sys
import os
version = '2.2.2'   # keepalived版本号
tar_name = "keepalived-{}.tar.gz".format(version) # 源码包名
download_file = "https://www.keepalived.org/software/{}".format(tar_name)   # keepalived的官网下载地址
instanll_path = "/usr/local/keepalived" # 安装路径
file_path = '/tmp/keepalived' # 源码包存储位置
MASTER = 0          # 0表示为主,非0表示为从
network = 'ens33'     # 监听的网卡名
network_bn = "ens33:02"   # 网卡别名
virtual_router_id = 52  # 路由id,两个keepalived的需要一致
priority = 99     # 权重,master的要大于从的
advert_int = 1
Vip = "192.168.43.111"    # 虚拟ip
chk_http_port = 'chk_http_port'
httpd = "httpd"   # 监控的进程名(需要依赖上面的监控脚本,将上面的监控脚本复制一份保存为/data/shell/check.sh)
def mkdir_path(files_path):
    if not os.path.exists(files_path):
        os.makedirs(files_path)
def wget_tar():
    s = os.system("which wget")
    if s != 0:
        print("主机无wget命令,正在尝试安装.....")
        install_wget = "yum -y install wget"
        w = os.system("install_wget")
        if w == 0:
            print("安装wget成功!!")
            return "ok"
        else:
            print("wget命令安装失败,请检查网络或yum源!!!")
            exit(0)
    else:
        return "ok"
def sed_file(file):
    s = '\   script_user root'
    s1 = '\    vrrp_script chk_http_port {'
    s2 = '\        script "/data/shell/check.sh {} "'.format(httpd)
    s3 = '\        interval 0'
    s4 = '\        weight -2'
    s5 = '}'
    s6 = '\    vrrp_instance VI_2 {'
    if MASTER == 0:
        s7 = '\    state MASTER'
    else:
        s7 = '\    state BACKUP'
    s8 = '\    interface {}'.format(network)
    s9 = '\    virtual_router_id {}'.format(virtual_router_id)
    s10 = '\    priority {}'.format(priority)
    s11 = '\    advert_int {}'.format(advert_int)
    s12 = '\    track_interface {'
    s13 = '\        {}'.format(network)
    s14 = '\    }'
    s15 = '\    authentication {'
    s16 = '\        auth_type PASS'
    s17 = '\        auth_pass 1111'
    s18 = '\    }'
    s19 = '\    virtual_ipaddress {'
    s20 = '\        {} dev {} label {}'.format(Vip, network, network_bn)
    s21 = '\    }'
    s22 = '\    track_script {'
    s23 = '\        chk_http_port'
    s24 = '\   }'
    s25 = '}'
    cmd_list = [s, s1, s2, s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25]
    os.system("sed -i '18,$d'  {}".format(file))
    for cmd in cmd_list:
       os.system("echo {} >> {}".format(cmd, file))
def download_tar():
    install_yl = os.system('yum install -y libnfnetlink-devel zlib zlib-devel gcc gcc-c++ openssl openssl-devel openssh')
    if install_yl == 0:
        print("依赖安装完成!!!")
    else:
        print("依赖安装失败!!!")
        exit(0)
    d_status = os.system('cd {} && wget {}'.format(file_path, download_file))
    #d_status = 0
    if d_status ==0:
        if os.path.exists(file_path + '/' + tar_name):
            mkdir_path(instanll_path)
            tar_cmd = 'cd {} &&tar -xf {}  && cd {}/keepalived-{} && ./configure --prefix={} && make && make install'.format(file_path, tar_name,file_path, version,  instanll_path)
            tar_s = os.system(tar_cmd)
            if tar_s ==0:
                print("安装编译成功!!!")
                ln_cmd = "ln -s {}/sbin/keepalived /usr/sbin/"
                ln_s = os.system(ln_cmd)
                if ln_s == 0:
                    print("软连接创建成功!!")
                    cp_cmd = "cp -r {}/etc/keepalived /etc/ && cp -r {}/etc/sysconfig/keepalived /etc/sysconfig/".format(instanll_path, instanll_path)
                    cp_s = os.system(cp_cmd)
                    if cp_s == 0:
                        add_cmd = "useradd keepalived_script"
                        os.system(add_cmd)
                        print("配置文件copy完毕!!")
                        sed_file('/etc/keepalived/keepalived.conf')
                        # os.system("sed -i '/PIDFile/d' /lib/systemd/system/keepalived.service")
                        # os.system("sed -i '7iPIDFile=run/keepalived.pid' /lib/systemd/system/keepalived.service")
                        os.system("systemctl daemon-reload")
                        start_cmd = "systemctl restart keepalived"
                        start_s = os.system(start_cmd)
                        if start_s == 0:
                            print("keepalived安装完毕,已启动!!!")
                        else:
                            print("keepalived启动失败!!!")
                    else:
                        print("配置文件copy失败!!")
                else:
                    print("软连接创建失败!!")
            else:
                print("安装编译失败!!!")
                exit(0)
def main():
    mkdir_path(file_path)
    status = wget_tar()
    if status == "ok":
        download_tar()
    else:
        print("退出安装!!")
if __name__ == '__main__':
    main()

使用注意:

  1. 需要将上面的检查脚本保存为/data/shell/check.sh
    监控的进程需要为system管理的进程,否则在检测到进程故障时无法重新拉起,将会直接ip漂移
  2. 使用时可以将一下代码保存为install_keepalived.py
  3. 配置文件中的基本参数可在脚本开头配置,如(安装路径、源码包存储路径、安装的软件包版本、VIP、是否为主等)
  4. 使用 python install_keepalived.py 命令执行
    模块在centos系统自带python中有无需安装模块


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
应用服务中间件 nginx 数据安全/隐私保护
HAProxy的高级配置选项-配置haproxy的状态页
这篇文章详细介绍了如何配置HAProxy的状态页,包括隐藏版本信息、设置自动刷新时间、自定义访问URI、配置认证信息以及启用管理功能等,并通过实战案例展示了配置过程和效果。
450 4
HAProxy的高级配置选项-配置haproxy的状态页
|
运维 Linux
keepalived详解(二)——keepalived安装与配置文件
keepalived详解(二)——keepalived安装与配置文件
792 1
|
负载均衡 应用服务中间件 Linux
Nginx系列教程(14) - LVS+KeepAlived+Nginx实现高性能负载均衡集群
Nginx系列教程(14) - LVS+KeepAlived+Nginx实现高性能负载均衡集群
2924 0
|
Kubernetes 安全 网络协议
【K8S系列】深入解析k8s网络插件—Calico
【K8S系列】深入解析k8s网络插件—Calico
4552 0
|
开发工具 Linux
Keepalived 日志配置与启动配置
在Redhat系统下,可以使用下面的方法将keepalived的日志输出到/var/log/下的某个文件里:  1.将keepalived日志输出到local0:  vim /etc/sysconfig/keepalived  KEEPALIVED_OPTIONS="-D -d -S 0"  2.
3522 0
|
负载均衡 安全 Ubuntu
docker部署keepalived(搭建keepalived)
将HTML或其他格式的内容转化为图片是Web开发中的一个较为常见需求。在某些特殊场景下,比如生成用户看不到的信息图片或进行内容的快速截图,该功能变得尤为重要。部署Keepalived至Docker容器提供了一种便捷方式来保证服务的高可用性。通过上述步骤,你可以轻松地在自己的项目中实现这一点,从而确保业务的连续性和稳定性。
635 4
|
网络安全
出现“Host key verification failed”错误--解决
遇到“Host key verification failed”错误,通常是因为远程主机密钥发生变化,与本地保存的信息不符。这种情况可能是远程主机系统更改或重装等原因导致的。解决方法是根据提示使用`ssh-keygen -f "/root/.ssh/known_hosts" -R "[10.61.0.152]:29022"`命令移除旧的密钥信息,然后重新尝试连接。
2101 5
|
存储 JSON Kubernetes
基于 cri-dockerd 二进制部署 kubernetest-v1.26.3 2
基于 cri-dockerd 二进制部署 kubernetest-v1.26.3
184 0
|
负载均衡 安全 网络安全
什么是 Traceroute?为什么要使用它?
【8月更文挑战第31天】
1098 0
|
关系型数据库 MySQL 网络安全
MHA 高可用配置 及故障切换
MHA 高可用配置 及故障切换

热门文章

最新文章