haproxy案例项目(haproxy+dns+nginx+nfs+keepalived)

作者:爱莉希雅&&&日期:2026/3/15

HAProxy+Nginx+NFS+DNS 部署笔记

一、环境规划

主机名IP 地址安装软件角色说明
haproxy192.168.72.100/24haproxy负载均衡器
nginx1192.168.72.10/24nginx、nfs-utilsWeb 节点 1(挂载 NFS 共享)
nginx2192.168.72.20/24nginx、nfs-utilsWeb 节点 2(挂载 NFS 共享)
nfs192.168.72.30/24nfs-utilsNFS 文件共享服务器
dns192.168.72.40/24bindDNS 域名解析服务器

二、部署步骤(按服务器角色拆分)

2.1 NFS 服务器部署(192.168.72.30)

2.1.1 环境准备
1# 1. 设置主机名(永久生效并立即生效)
2hostnamectl set-hostname nfs && bash
3# hostnamectl set-hostname nfs:修改系统主机名为nfs
4# && bash:重新加载shell,使主机名修改立即生效
5
6# 2. 关闭防火墙(禁用并立即停止)
7systemctl disable --now firewalld.service 
8# disable:设置防火墙开机不自启
9# --now:立即停止防火墙服务
10
11# 3. 关闭SELinux(临时+永久)
12setenforce 0
13# setenforce 0:临时将SELinux切换为宽容模式(不拦截仅记录)
14sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
15# sed:文本替换工具
16# -i:直接修改文件内容
17# "s/旧内容/新内容/":替换规则,将强制模式改为宽容模式
18
19# 4. 配置静态IP
20nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.72.30/24 ipv4.gateway 192.168.72.2 ipv4.dns 223.5.5.5 connection.autoconnect yes
21# nmcli c m:修改网络连接配置
22# ens160:网卡名称(根据实际环境调整)
23# ipv4.method manual:手动配置IP(非DHCP)
24# ipv4.addresses:设置IP地址和子网掩码
25# ipv4.gateway:网关地址
26# ipv4.dns:DNS服务器地址(临时,后续可修改)
27# connection.autoconnect yes:开机自动连接该网络
28
29nmcli c up ens160
30# 重启网络连接,使IP配置生效
31

以上操作都可以用脚本来完成快速部署

1#!/bin/bash
2 
3# useage: sudo ./init_sys.sh <hostname> <ip_address> [gateway] [dns]
4 
5RED='\033[0;31m'
6GREEN='\033[0;32m'
7YELLOW='\033[1;33m'
8NC='\033[0m'
9 
10log_info() {
11    echo -e "${GREEN}[INFO]${NC} $1"
12}
13log_warn() {
14    echo -e "${YELLOW}[WARN]${NC} $1"
15}
16log_error() {
17    echo -e "${RED}[ERROR]${NC} $1"
18}
19 
20check_root() {
21    if [[ $EUID -ne 0 ]]; then
22        log_error "此脚本必须以root权限运行"
23        exit 1
24    fi
25}
26 
27usage() {
28    echo "用法: $0 <hostname> <ip_address> [gateway] [dns_servers]"
29    echo ""
30    echo "参数说明:"
31    echo "  hostname    要设置的主机名"
32    echo "  ip_address  要设置的静态IP地址 (如: 192.168.72.100)"
33    echo "  gateway     网关地址 (如: 192.168.72.2)"
34    echo "  dns_servers DNS服务器,逗号分隔 (可选,默认: 8.8.8.8,223.5.5.5)"
35    echo ""
36    echo "示例:"
37    echo "  $0 myserver 192.168.72.100 192.168.72.2 8.8.8.8,223.5.5.5"
38    echo "  $0 webserver 10.0.0.50"
39    exit 1
40}
41 
42get_interface() {
43    # 尝试获取第一个活动的非环回接口
44    local interface=$(ip route | grep default | head -1 | awk '{print $5}' 2>/dev/null)
45 
46    if [[ -z "$interface" ]]; then
47        # 如果没有默认路由,获取第一个非环回接口
48        interface=$(ip link show | grep -v lo | grep 'state UP' | head -1 | awk -F': ' '{print $2}')
49    fi
50 
51    if [[ -z "$interface" ]]; then
52        log_error "无法自动检测网络接口"
53        read -p "请输入网络接口名称 (如: eth0, ens160): " interface
54    fi
55 
56    echo "$interface"
57}
58 
59set_hostname() {
60    local hostname=$1
61 
62    log_info "正在设置主机名为: $hostname"
63 
64    /usr/bin/hostnamectl set-hostname $hostname
65 
66    log_info "主机名设置完成"
67}
68 
69close_selinux_firewalld() {
70    log_info "关闭selinux"
71    setenforce 0
72    sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
73    
74    log_info "关闭防火墙"
75    /usr/bin/systemctl disable --now firewalld
76}
77 
78set_static_ip() {
79    local interface=$(get_interface)
80    local ip=$1
81    local gateway=${2:-"192.168.72.2"}
82    local dns=${3:-"223.5.5.5,8.8.8.8"}
83 
84    log_info "正在为接口 $interface 配置静态IP: $ip"
85 
86    nmcli c modify $interface ipv4.method manual ipv4.addresses $ip/24 ipv4.gateway $gateway ipv4.dns $dns connection.autoconnect yes
87    nmcli c up $interface
88}
89 
90main() {
91    if [[ $# -lt 2 ]]; then
92        usage
93    fi
94 
95    check_root
96 
97    set_hostname "$1"
98    
99    close_selinux_firewalld
100 
101    set_static_ip "$2" "$3" "$4"
102}
103 
104main "$@"
2.1.2 安装并配置 NFS
1# 1. 创建NFS共享目录
2mkdir /share
3# 创建用于共享的目录
4
5# 2. 创建测试页面(共享给Nginx节点)
6vim /share/index.html
7# 编辑index.html文件,写入内容:nfs 192.168.72.30
8# 作用:Nginx节点挂载后,访问Web时展示该内容
9
10# 3. 设置共享目录权限(NFS默认使用nobody用户)
11chown -R nobody: /share
12# chown:修改文件所属用户和组
13# -R:递归修改目录下所有文件
14# nobody::设置所属用户为nobody,组为空(继承父级)
15
16# 4. 安装NFS服务端工具
17dnf install nfs-utils -y
18# dnf:RHEL/CentOS 8+包管理器
19# install nfs-utils:安装NFS核心工具
20# -y:自动确认安装
21
22# 5. 配置NFS共享规则
23vim /etc/exports
24# 编辑NFS主配置文件,添加以下内容:
25/share  192.168.72.0/24(rw,sync,no_subtree_check)
26# /share:要共享的目录
27# 192.168.72.0/24:允许访问的客户端网段
28# rw:读写权限
29# sync:同步写入(数据先写入磁盘再返回成功)
30# no_subtree_check:关闭子树检查(提升性能)
31
32# 6. 加载NFS配置并验证
33exportfs -rv
34# exportfs:管理NFS共享
35# -r:重新加载配置
36# -v:详细输出(显示共享的目录和网段)
37# 输出:exporting 192.168.72.0/24:/share 表示配置生效
38
39# 7. 启动NFS服务
40systemctl start nfs-server.service
41# 启动NFS服务端
42
43# 8. 验证NFS共享
44showmount -e 192.168.72.30
45# showmount:查看NFS共享信息
46# -e:显示导出的共享目录
47# 输出:/share 192.168.72.0/24 表示共享成功
48

2.2 Nginx1 部署(192.168.72.10)

2.2.1 环境准备(同 NFS,仅 IP 和主机名不同)
1# 1. 设置主机名
2hostnamectl set-hostname nginx1 && bash
3
4# 2. 关闭防火墙
5systemctl disable --now firewalld.service 
6
7# 3. 关闭SELinux
8setenforce 0
9sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
10
11# 4. 配置静态IP
12nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.72.10/24 ipv4.gateway 192.168.72.2 ipv4.dns 223.5.5.5 connection.autoconnect yes
13nmcli c up ens160
14
2.2.2 安装 Nginx 并挂载 NFS
1# 1. 安装Nginx
2dnf install nginx -y
3# 安装Nginx Web服务
4
5# 2. 安装NFS客户端工具(用于挂载共享目录)
6dnf install nfs-utils -y
7
8# 3. 挂载NFS共享目录到Nginx根目录
9mount -t nfs 192.168.72.30:/share /usr/share/nginx/html/
10# mount:挂载命令
11# -t nfs:指定文件系统类型为NFS
12# 192.168.72.30:/share:NFS服务器的共享目录
13# /usr/share/nginx/html/:Nginx默认网页根目录(挂载后,访问Nginx即访问NFS共享文件)
14
15# 4. 验证挂载结果
16ls /usr/share/nginx/html/
17# 输出index.html,表示挂载成功
18
19cat /usr/share/nginx/html/index.html 
20# 输出nfs 192.168.72.30,验证文件内容正确
21
22# 5. 启动Nginx服务
23systemctl start nginx
24
25# 6. 本地访问测试
26curl 192.168.72.10
27# 输出nfs 192.168.72.30,表示Nginx+NFS挂载成功
28

2.3 Nginx2 部署(192.168.72.20)

步骤与 Nginx1 完全一致,仅修改以下内容:
1# 1. 设置主机名
2hostnamectl set-hostname nginx2 && bash
3
4# 2. 配置IP
5nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.72.20/24 ipv4.gateway 192.168.72.2 ipv4.dns 223.5.5.5 connection.autoconnect yes
6
7# 3. 访问测试
8curl 192.168.72.20
9# 输出nfs 192.168.72.30 即成功
10

2.4 HAProxy 部署(192.168.72.100)

2.4.1 环境准备
1# 1. 设置主机名
2hostnamectl set-hostname haproxy && bash
3
4# 2. 关闭防火墙
5systemctl disable --now firewalld.service 
6
7# 3. 关闭SELinux
8setenforce 0
9sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
10
11# 4. 配置静态IP
12nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.72.100/24 ipv4.gateway 192.168.72.2 ipv4.dns 223.5.5.5 connection.autoconnect yes
13nmcli c up ens160
14
2.4.2 安装并配置 HAProxy
1# 1. 安装HAProxy
2dnf install haproxy -y
3
4# 2. 备份原配置文件(防止配置错误无法回滚)
5cp -p /etc/haproxy/haproxy.cfg{,.bak}
6# cp -p:保留文件属性(权限、时间戳)
7# {,.bak}:快捷写法,等价于 cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
8
9# 3. 编辑HAProxy配置文件
10vim /etc/haproxy/haproxy.cfg
11# 配置内容及每行解释:
12global  # 全局配置段(进程级配置)
13    log         127.0.0.1 local2  # 日志输出到本地syslog的local2设备
14    chroot      /var/lib/haproxy  # 切换根目录(安全隔离)
15    pidfile     /var/run/haproxy.pid  # 进程PID文件路径
16    maxconn     4000  # 最大并发连接数
17    user        haproxy  # 运行HAProxy的用户
18    group       haproxy  # 运行HAProxy的组
19    daemon      # 以守护进程方式运行
20    stats socket /var/lib/haproxy/stats mode 600 level admin  # 统计信息套接字(权限600,管理员级别)
21    ssl-default-bind-ciphers PROFILE=SYSTEM  # 绑定SSL时使用系统默认加密套件
22    ssl-default-server-ciphers PROFILE=SYSTEM  # 后端服务器SSL加密套件
23
24defaults  # 默认配置段(继承到frontend/backend)
25    mode                    http  # 工作模式:HTTP(七层代理)
26    log                     global  # 继承global的日志配置
27    option                  httplog  # 记录HTTP详细日志
28    option                  dontlognull  # 不记录空请求日志
29    option http-server-close  # 关闭客户端与服务器的连接(复用连接)
30    option forwardfor       except 127.0.0.0/8  # 传递客户端真实IP(排除本地地址)
31    option                  redispatch  # 后端服务器不可用时,重新分发请求
32    retries                 3  # 后端连接失败重试次数
33    timeout http-request    10s  # HTTP请求超时时间
34    timeout queue           1m  # 请求排队超时时间
35    timeout connect         10s  # 与后端服务器连接超时时间
36    timeout client          1m  # 客户端连接超时时间
37    timeout server          1m  # 后端服务器响应超时时间
38    timeout http-keep-alive 10s  # 长连接超时时间
39    timeout check           10s  # 健康检查超时时间
40    maxconn                 3000  # 每个进程最大并发连接数
41
42frontend webserver  # 前端配置段(接收客户端请求)
43    bind *:80  # 监听所有网卡的80端口
44    default_backend             webcluster  # 默认转发到webcluster后端集群
45
46backend webcluster  # 后端配置段(负载均衡规则)
47    balance     roundrobin  # 负载均衡算法:轮询(依次分发请求)
48    server web1 192.168.72.10:80 check inter 2000 rise 2 fall 3 weight 1
49    # server 节点名 IP:端口 配置项
50    # check:启用健康检查
51    # inter 2000:健康检查间隔2秒
52    # rise 2:连续2次检查成功则标记为可用
53    # fall 3:连续3次检查失败则标记为不可用
54    # weight 1:权重(值越大,分配到的请求越多)
55    server web2 192.168.72.20:80 check inter 2000 rise 2 fall 3 weight 1  # 同web1
56
57# 4. 验证配置文件语法
58haproxy -c -f /etc/haproxy/haproxy.cfg
59# -c:检查配置语法
60# -f:指定配置文件
61# 输出Configuration file is valid 表示语法正确
62
63# 5. 启动HAProxy
64systemctl start haproxy
65
66# 6. 访问测试(轮询访问nginx1/nginx2)
67curl 192.168.72.100
68# 输出nfs 192.168.72.30 表示负载均衡生效
69

2.5 DNS 服务器部署(192.168.72.40)

2.5.1 环境准备
1# 1. 设置主机名
2hostnamectl set-hostname dns && bash
3
4# 2. 关闭防火墙
5systemctl disable --now firewalld.service 
6
7# 3. 关闭SELinux
8setenforce 0
9sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
10
11# 4. 配置静态IP
12nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.72.40/24 ipv4.gateway 192.168.72.2 ipv4.dns 223.5.5.5 connection.autoconnect yes
13nmcli c up ens160
14
2.5.2 安装并配置 BIND(DNS 服务)
1# 1. 安装BIND
2dnf install bind -y
3# bind:DNS服务核心包
4
5# 2. 编辑BIND主配置文件
6vim /etc/named.conf
7# 配置内容及解释:
8options {
9        listen-on port 53 { 127.0.0.1; 192.168.72.40; };  # 监听53端口(DNS默认端口),仅允许本地和自身IP
10        directory       "/var/named";  # 区域文件存储目录
11        dump-file       "/var/named/data/cache_dump.db";  # 缓存转储文件
12        statistics-file "/var/named/data/named_stats.txt";  # 统计信息文件
13        memstatistics-file "/var/named/data/named_mem_stats.txt";  # 内存统计文件
14        secroots-file   "/var/named/data/named.secroots";  # 安全根文件
15        recursing-file  "/var/named/data/named.recursing";  # 递归查询文件
16        allow-query     { localhost; 192.168.72.0/24; };  # 允许查询的客户端网段
17        recursion yes;  # 启用递归查询(DNS服务器主动向其他服务器查询)
18        dnssec-validation no;  # 关闭DNSSEC验证(简化配置)
19        managed-keys-directory "/var/named/dynamic";  # 托管密钥目录
20        geoip-directory "/usr/share/GeoIP";  # GeoIP数据库目录
21        pid-file "/run/named/named.pid";  # PID文件路径
22        session-keyfile "/run/named/session.key";  # 会话密钥文件
23        include "/etc/crypto-policies/back-ends/bind.config";  # 加密策略配置
24};
25
26logging {  # 日志配置
27        channel default_debug {
28                file "data/named.run";  # 日志文件路径
29                severity dynamic;  # 日志级别(动态调整)
30        };
31};
32
33zone "." IN {  # 根区域(指向根DNS服务器)
34        type hint;  # 提示类型(使用根区域文件)
35        file "named.ca";  # 根区域文件路径
36};
37
38include "/etc/named.rfc1912.zones";  # 包含自定义区域配置
39include "/etc/named.root.key";  # 根密钥文件
40
41# 3. 配置自定义区域(chengke.com)
42vim /etc/named.rfc1912.zones
43# 添加以下内容:
44zone "chengke.com" IN {  # 定义chengke.com区域
45        type master;  # 主DNS服务器
46        file "chengke.com.zone";  # 区域数据文件路径
47};
48
49# 4. 创建区域数据解析文件
50cp -p /var/named/named.localhost /var/named/chengke.com.zone
51# 复制模板文件(保留属性)
52
53vim /var/named/chengke.com.zone
54# 编辑解析文件,内容及解释:
55$TTL 1D  # 缓存时间(1天)
56@       IN SOA  ns1 root.chengk.com. (  # SOA记录(起始授权机构)
57                                        0       ; serial(序列号,修改配置需递增)
58                                        1D      ; refresh(刷新时间,1天)
59                                        1H      ; retry(重试时间,1小时)
60                                        1W      ; expire(过期时间,1周)
61                                        3H )    ; minimum(最小缓存时间,3小时)
62        IN      NS      ns1  # NS记录(域名服务器):chengke.com的DNS服务器是ns1.chengke.com
63ns1     IN      A       192.168.72.40  # A记录:ns1.chengke.com对应IP
64www     IN      A       192.168.72.100  # A记录:www.chengke.com对应HAProxy的IP
65
66# 5. 语法校验
67named-checkconf -i /etc/named.conf
68# 检查主配置文件语法(无输出即正确)
69
70named-checkzone chengke.com /var/named/chengke.com.zone 
71# 检查区域文件语法
72# 输出zone chengke.com/IN: loaded serial 0 OK 表示正确
73
74# 6. 启动BIND服务
75systemctl start named
76
77# 7. 验证DNS解析
78dig -t A www.chengke.com @192.168.72.40
79# dig:DNS查询工具
80# -t A:查询A记录
81# www.chengke.com:要查询的域名
82# @192.168.72.40:指定DNS服务器
83# 输出中ANSWER SECTION显示www.chengke.com IN A 192.168.72.100 表示解析成功
84

2.6 配置 HAProxy 使用自定义 DNS

1# 1. 查看当前DNS配置
2nmcli d show ens160 | grep DNS
3# 输出当前DNS服务器(默认223.5.5.5)
4
5# 2. 修改HAProxy的DNS为自定义DNS服务器
6nmcli c m ens160 ipv4.dns 192.168.72.40
7# 修改网络连接的DNS地址为192.168.72.40
8
9nmcli c up ens160 
10# 重启网络连接使DNS生效
11
12# 3. 验证DNS修改
13nmcli d show ens160 | grep DNS
14# 输出IP4.DNS[1]: 192.168.72.40 表示修改成功
15
16# 4. 域名访问测试
17curl www.chengke.com
18# 输出nfs 192.168.72.30 表示DNS解析+HAProxy负载均衡+Nginx+NFS全流程生效
19

可以去测试,只开一台web服务器,和两台web服务器都关闭来验证负载均衡

3. keepalived+haproxy+nginx+nfs+dns

在此基础上我们来添加haproxy集群高可用

3.1 主机规划

主机名IP 地址安装软件角色说明
VIP192.168.72.200虚拟 IP(HAProxy 高可用入口)
haproxy01192.168.72.100haproxy,keepalived负载均衡器(主)
haproxy02192.168.72.101haproxy,keepalived负载均衡器(备)
nginx1192.168.72.10nginx,nfs-utilsWeb 节点 1(挂载 NFS 共享)
nginx2192.168.72.20nginx,nfs-utilsWeb 节点 2(挂载 NFS 共享)
nfs192.168.72.30nfs-utilsNFS 文件共享服务器
dns192.168.72.40bindDNS 域名解析服务器

3.2 前期准备

在原有 HAProxy+Nginx+NFS+DNS 基础上,增加 HAProxy 高可用能力:

  1. 克隆 haproxy01 得到 haproxy02,实现 HAProxy 双节点;
  2. 通过 keepalived 实现双节点故障自动切换,并提供 VIP(192.168.72.200)作为统一访问入口;
  3. 编写高可用检测脚本,确保 HAProxy 故障时自动切换 VIP。

3.3 原有基础环境部署(补充 HAProxy 双节点)

3.3.1 搭建 haproxy01(原 HAProxy 节点改造)
1# 1. 修改主机名
2[root@haproxy ~]# hostnamectl set-hostname haproxy01 && bash
3
4# 2. 环境准备(复用原有配置:关闭防火墙、SELinux、静态IP 192.168.72.100)
5# 3. 原有HAProxy配置保持不变(负载均衡指向nginx1/nginx2)
6# 4. 验证HAProxy正常运行
7[root@haproxy01 ~]# systemctl restart haproxy
8[root@haproxy01 ~]# curl 192.168.72.100
9nfs 192.168.72.30
10
3.3.2 搭建 haproxy02(HAProxy 备节点)
  1. 克隆 haproxy01 虚拟机,命名为 haproxy02 并启动;
  2. 修改主机名和 IP:
1# 修改主机名
2[root@haproxy01 ~]# hostnamectl set-hostname haproxy02 && bash
3
4# 修改静态IP为192.168.72.101
5[root@haproxy02 ~]# nmcli c m ens160 ipv4.addresses 192.168.72.101/24
6[root@haproxy02 ~]# nmcli c up ens160
7
8# 启动HAProxy并验证
9[root@haproxy02 ~]# systemctl start haproxy
10[root@haproxy02 ~]# curl 192.168.72.101
11nfs 192.168.72.30
12
13当然curl www.chengke.com这个域名更好理解
14

3.4 搭建 keepalived(实现 HAProxy 高可用)

3.4.1 在 haproxy01(主节点)安装配置 keepalived
1# 1. 安装keepalived
2[root@haproxy01 ~]# dnf install keepalived -y
3
4# 2. 备份默认配置
5[root@haproxy01 ~]# cp -p /etc/keepalived/keepalived.conf{,.bak}
6
7# 3. 编辑keepalived主配置(MASTER节点)
8[root@haproxy01 ~]# vim /etc/keepalived/keepalived.conf
9

配置内容:

global_defs原配置中有一个vrrp_strict,这是开启严格模式

  1. 禁止无 VIP 配置:必须配置虚拟 IP,否则服务无法启动。
  2. 禁止单播邻居:只能用组播(224.0.0.18),不能配置 unicast_peer
  3. VRRPv2 禁止 IPv6:v2 仅支持 IPv4,v3 才可混用 IPv4/IPv6。
  4. 禁用 VRRP 认证:配置 authentication 会被忽略。
  5. VIP 默认不响应流量:仅当优先级 = 255 或 VRRPv3+accept 时才响应 ICMP/TCP。

生产环境常单播,这时候需要注释掉。

1global_defs {
2   router_id LVS_master  # 节点标识(唯一)
3}
4
5# HAProxy健康检查脚本配置
6vrrp_script chk_haproxy {
7    script "/etc/keepalived/check_haproxy.sh"  # 检测脚本路径
8    interval 2  # 检测间隔(秒)
9    rise 2      # 连续2次检测成功标记为可用
10    fall 3      # 连续3次检测失败标记为不可用
11    weight -20  # 检测失败后优先级降低20
12}
13
14vrrp_instance VI_1 {
15    state MASTER          # 节点角色(主)
16    interface ens160      # 绑定网卡(与IP配置一致)
17    virtual_router_id 51  # 虚拟路由ID(主备节点需一致,范围0-255)
18    priority 100          # 优先级(主节点高于备节点)
19    advert_int 1          # 心跳检测间隔(秒)
20    # 认证配置(主备节点需一致)
21    authentication {
22        auth_type PASS
23        auth_pass 1111
24    }
25    virtual_ipaddress {
26        192.168.72.200/24  # 虚拟VIP(统一访问入口)
27    }
28    # 关联健康检查脚本
29    track_script {
30        chk_haproxy
31    }
32}
33
3.4.2 编写 HAProxy 健康检查脚本(haproxy01)
1# 1. 创建脚本文件
2[root@haproxy01 ~]# vim /etc/keepalived/check_haproxy.sh
3

脚本内容:

1#!/bin/bash
2# 检测HAProxy进程是否运行
3count=[`ps -C haproxy --no-header|wc -l`](https://xplanc.org/primers/document/zh/10.Bash/90.%E5%B8%AE%E5%8A%A9%E6%89%8B%E5%86%8C/EX.wc.md)
4if [ $count -eq 0 ]; then
5        # 尝试重启HAProxy
6        /usr/bin/systemctl start haproxy
7        sleep 1
8        # 重启失败则停止keepalived,释放VIP
9        if [ [`ps -C haproxy --no-header | wc -l`](https://xplanc.org/primers/document/zh/10.Bash/90.%E5%B8%AE%E5%8A%A9%E6%89%8B%E5%86%8C/EX.wc.md) -eq 0 ]; then
10                /usr/bin/systemctl stop keepalived
11        fi      
12fi
13
14
15上面有缺陷是可能有存在僵尸进程
16优化为以下,还可以添加反馈,还可以添加log日志搜集报错,运行结果
17脚本不够完善:
18[root@haproxy01 keepalived]# ./check_haproxy.sh 
19[WARN]the haproxy verification failed,and the service is being restart 2026-03-15 16:16:07
20[info]the haproxy service restarted successfully 2026-03-15 16:16:08
21
22需要手动执行脚本才能看见提示语句,建议添加一个日志文件,将提示语句输入到文件中,这样方便查看,实时了解服务的变化
23
24
25#!/bin/bash
26RED='\033[0;31m'
27GREEN='\033[0;32m'
28YELLOW='\033[1;33m'
29NC='\033[0m'
30log_info(){
31        echo -e "${GREEN}[info]$1${NC} $(date +'%F %T')"
32}
33log_warn(){
34        echo -e "${YELLOW}[WARN]$1${NC} $(date +'%F %T')"
35}
36log_error(){
37        echo -e "${RED}[ERROR]$1${NC} $(date +'%F %T')"
38}
39answer=`systemctl is-active haproxy`
40if [ $answer != "active" ]; then
41        log_warn "the haproxy verification failed,and the service is being restart"
42        /usr/bin/systemctl start haproxy
43        sleep 1
44        answer_after=$(systemctl is-active haproxy)
45        if [ $answer_after != "active" ]; then
46                /usr/bin/systemctl stop keepalived
47        else
48                log_info "the haproxy service restarted successfully"
49        fi
50else
51        log_info "haproxy is up and running"
52fi
53
1# 2. 赋予脚本执行权限
2[root@haproxy01 ~]# chmod +x /etc/keepalived/check_haproxy.sh
3
4# 3. 启动keepalived并设置开机自启
5[root@haproxy01 ~]# systemctl enable --now keepalived
6
7# 4. 验证VIP已绑定
8[root@haproxy01 ~]# ip a show ens160 
9# 输出中包含 192.168.72.200/32 表示VIP绑定成功
10
3.4.3 在 haproxy02(备节点)安装配置 keepalived
1# 1. 安装keepalived
2[root@haproxy02 ~]# dnf install keepalived -y
3
4# 2. 复制haproxy01的配置和脚本(简化配置)
5[root@haproxy02 ~]# scp -p 192.168.72.100:/etc/keepalived/* /etc/keepalived/
6# 输入haproxy01的root密码完成复制
7
8# 3. 修改keepalived配置(BACKUP节点)
9[root@haproxy02 ~]# vim /etc/keepalived/keepalived.conf
10

修改后的配置:

1global_defs {
2   router_id LVS_backup  # 备节点标识
3}
4
5vrrp_script chk_haproxy {
6    script "/etc/keepalived/check_haproxy.sh"
7    interval 2
8    rise 2
9    fall 3
10    weight -20
11}
12
13vrrp_instance VI_1 {
14    state BACKUP           # 节点角色(备)
15    interface ens160
16    virtual_router_id 51   # 与主节点一致
17    priority 90            # 优先级低于主节点(100)
18    advert_int 1
19    authentication {
20        auth_type PASS
21        auth_pass 1111     # 与主节点一致
22    }
23    virtual_ipaddress {
24        192.168.72.200/24  # 与主节点共享VIP
25    }
26    track_script {
27        chk_haproxy
28    }
29}
30
1# 4. 赋予脚本执行权限   这一步上面scp -p 将权限也原封不动的复制过来,也可以不用这一步
2[root@haproxy02 ~]# chmod +x /etc/keepalived/check_haproxy.sh
3# 5. 启动keepalived并设置开机自启
4[root@haproxy02 ~]# systemctl enable --now keepalived
5

3.5 高可用验证测试

3.5.1 基础访问测试(VIP 访问)
1# 在任意节点访问VIP,验证负载均衡生效
2[root@localhost ~]# curl 192.168.72.200
3nfs 192.168.72.30
4[root@localhost ~]# curl www.chengke.com  # DNS已解析到VIP/HAProxy IP
5nfs 192.168.72.30
6
3.5.2 故障切换测试(主节点 HAProxy 故障)

因为脚本写了重启该服务,所以不会出现关闭的情况,除非关闭后修改其服务的配置文件使其无法启动

1# 1. 在haproxy01停止HAProxy
2[root@haproxy01 ~]# systemctl stop haproxy
3
4# 2. 验证haproxy01的keepalived是否停止(释放VIP)
5[root@haproxy01 ~]# systemctl status keepalived  # 状态为stopped
6[root@haproxy01 ~]# ip a show ens160  # VIP 192.168.72.200已消失
7
8# 3. 验证haproxy02已绑定VIP
9[root@haproxy02 ~]# ip a show ens160  # 输出包含192.168.72.200/32
10
11# 4. 访问VIP验证服务不中断
12[root@localhost ~]# curl 192.168.72.200
13nfs 192.168.72.30
14
15# 5. 恢复haproxy01的HAProxy和keepalived
16[root@haproxy01 ~]# systemctl start haproxy
17[root@haproxy01 ~]# systemctl start keepalived
18# 验证VIP切回haproxy01(主节点优先级更高)
19[root@haproxy01 ~]# ip a show ens160  # VIP重新绑定
20
3.5.3 节点宕机测试(主节点关机)
1# 1. 关闭haproxy01虚拟机
2[root@haproxy01 ~]# poweroff
3
4# 2. 验证haproxy02自动接管VIP
5[root@haproxy02 ~]# ip a show ens160  # 包含VIP 192.168.72.200
6
7# 3. 访问VIP验证服务正常
8[root@localhost ~]# curl 192.168.72.200
9nfs 192.168.72.30
10
11# 4. 重启haproxy01,验证VIP切回主节点
12[root@haproxy01 ~]# systemctl start keepalived
13[root@haproxy01 ~]# ip a show ens160  # VIP重新绑定
14
1以上测试可直接进行,但是如果要测试www.chengke.com,需要将dns服务器上的区域文件做相对应的修改,并且重启named服务
2
3[root named]# cat chengke.com.zone 
4$TTL 1D
5@       IN SOA  ns1.chengke.com. root.chengke.com. (
6                                        2026012202       ; serial(必须递增,10位)
7                                        86400   ; refresh (1D,用秒更规范)
8                                        3600    ; retry (1H)
9                                        604800  ; expire (1W)
10                                        10800 ) ; minimum (3H)
11        IN      NS      ns1.chengke.com.  
12ns1.chengke.com.     IN      A       192.168.72.40  
13www.chengke.com.     IN      A       192.168.72.200  
14[root named]# systemctl restart named
15
16
17[root keepalived]# curl www.chengke.com
18nfs 192.168.72.30
19

3.6 核心流程升级总结

  1. NFS 提供统一 Web 文件共享,所有 Nginx 节点挂载后内容一致;
  2. Nginx 作为 Web 服务,接收 HAProxy 分发的请求;
  3. 双 HAProxy 节点通过 keepalived 实现高可用:
    • 主节点(haproxy01)绑定 VIP,承担负载均衡;
    • 备节点(haproxy02)实时监控主节点状态,故障时自动接管 VIP;
    • 健康检查脚本确保 HAProxy 进程异常时自动重启或切换 VIP;
  4. DNS 将域名(www.chengke.com)解析到 VIP(192.168.72.200),实现域名访问的高可用。

3.7 注意事项

  1. keepalived 主备节点的 virtual_router_idauth_pass 必须一致;
  2. 优先级(priority)主节点需高于备节点,确保主节点恢复后重新接管 VIP;
  3. 健康检查脚本需在主备节点都配置,避免单节点脚本缺失导致切换异常;
  4. 所有节点的防火墙需放行 VRRP 协议(默认已关闭防火墙,若开启需配置:firewall-cmd --permanent --add-protocol=vrrp && firewall-cmd --reload)。

三、核心流程总结

  1. NFS 提供统一的 Web 文件共享,所有 Nginx 节点挂载后内容一致;
  2. Nginx 作为 Web 服务,接收 HAProxy 分发的请求;
  3. HAProxy 通过轮询算法将请求分发到 nginx1/nginx2,实现负载均衡;
  4. DNS 将域名(www.chengke.com)解析到 HAProxy 的 IP,实现域名访问。

haproxy案例项目(haproxy+dns+nginx+nfs+keepalived)》 是转载文章,点击查看原文


相关推荐


Spring Cloud+AI :实现分布式智能推荐系统
我不是呆头2026/3/7

欢迎文末添加好友交流,共同进步! “ 俺はモンキー・D・ルフィ。海贼王になる男だ!” 引言 在当今数字化时代,推荐系统已成为电商平台、内容分发平台、社交网络等互联网产品的核心竞争力之一。从淘宝的"猜你喜欢"、抖音的精准内容推送,到 Netflix 的影视推荐,优秀的推荐系统不仅能显著提升用户留存率和转化率,更能为企业带来可观的商业价值。据统计,亚马逊约 35% 的销售额来自推荐系统,Netflix 则通过推荐算法为用户节省了每年约 10 亿美元的搜索成本。 然而,随着业


一文搞懂激活函数!
aicoting2026/2/27

推荐直接网站在线阅读:aicoting.cn 在深度学习中,激活函数(Activation Function)是神经网络的灵魂。它不仅赋予网络非线性能力,还决定了训练的稳定性和模型性能。那么,激活函数到底是什么?为什么我们非用不可?有哪些经典函数?又该如何选择? 所有相关源码示例、流程图、模型配置与知识库构建技巧,我也将持续更新在Github:AIHub,欢迎关注收藏! 1. 什么是激活函数,为什么需要激活函数 激活函数的核心作用就是为神经网络引入非线性。 为什么需要非线性? 想象一下,如果


【Python练习五】Python 正则与网络爬虫实战:专项练习(2道经典练习带你巩固基础——看完包会)
纯.Pure_Jin(g)2026/2/18

第一题 题目: 使用正则完成下列内容的匹配 匹配陕西省区号 029-12345匹配邮政编码 745100匹配邮箱 lijian@xianoupeng.com匹配身份证号 62282519960504337X 代码: import re # 1. 匹配陕西省区号 029-12345 pattern_area = r'^029-\d{5}$' # 精确匹配 029- 开头,后接5位数字 test_area = '029-12345' print("区号匹配:", re.match(pattern_


Claude Code Agent Teams:3个AI同时写代码,底层原理和主流框架对比
易安说AI2026/2/10

大家好,我是易安,AI超级个体,大厂程序员二孩奶爸。 Claude Opus 4.6 带来了 Agent Teams 功能,可以让多个 Claude Code 实例并行工作。我用它做了个小项目,踩了一些坑,也顺便把底层原理和市面上几个主流多 Agent 框架做了个对比。这篇文章干货比较多,建议收藏。 Agent Teams 到底是什么 简单说就是一个 Lead Agent 可以 spawn 出多个 Teammate Agent,每个 Teammate 是一个完全独立的 Claude Code 会


abigen使用教程 - go版本
Warson_L2026/2/1

在 Web3 后端开发中,abigen 是一个至关重要的工具。它能根据 Solidity 合约生成的 ABI(应用二进制接口)自动生成 Go 语言代码,让你像调用普通 Go 函数一样调用智能合约。 以下是详细的 abigen 使用教程。 第一步:安装 abigen 工具 abigen 是 go-ethereum 项目的一部分。你可以通过以下命令安装: # 安装最新版 abigen go install github.com/ethereum/go-ethereum/cmd/abigen@lat


Verifier-state pruning in BPF
mounter6252026/1/22

The BPF verifier works, on a theoretical level, by considering every possible path that a BPF program could take. As a practical matter, however, it needs to do that in a reasonable amount of time. At the 2025 Linux Plumbers Conference, Mahé Tardy an


Spring设计模式与依赖注入详解
callNull2026/1/14

📚 前言 这是我之前写 项目时的一些理解和感悟, 我喊了AI帮我润色了一下语言文字,发出来了,希望对大家有用 在学习Spring框架时,经常会遇到@Configuration、@Bean、@Service、@Resource等注解,以及各种设计模式的应用。本文通过具体的代码示例(MailConfig和MailService),深入浅出地解释这些概念,帮助理解Spring的核心机制。 🎯 核心问题 问题1:为什么需要@Configuration和@Bean? 问题2:为什么没有注解的类也能被@


多模态大模型有哪些模态?
智泊AI2026/1/6

“多模态”中的“模态”(modality),即指各类数据形式或信息来源。在多模态大模型中,典型模态涵盖以下类别: 更多AI大模型学习视频及资源,都在智泊AI。 文本模态‌: 涵盖自然语言文本、经语音识别转换的文本内容等。 图像模态‌: 指视觉图像数据,例如照片、插画、艺术作品等。 视频模态‌: 包含动态影像序列,如短视频、影视片段、监控录像等。 音频模态‌: 指声学信号数据,如人声、音乐、环境音效等。 其他模态‌: 还包括如环境传感器读数、生理信号、指纹、虹膜等非传统信息形式。 多模态模型的


旮旯c语言三个任务
宇宙超级无敌暴龙战士2025/12/29

#include <stdio.h> // 任务1:计算数组元素和 int getArrSum(int arr[], int len) { int sum = 0; for (int i = 0; i < len; i++) { sum += arr[i]; } return sum; } // 任务2:获取数组最大值 int getArrMax(int arr[], int len) { int max = arr[0]; f


python+django/flask+vue基于spark的西南天气数据的分析与应用系统
Q_Q5110082852025/12/19

目录 项目介绍本项目具体实现截图开发技术大数据类设计开发的基本流程是:论文大纲结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 项目介绍 系统功能 数据采集与清洗:系统通过爬虫技术从多个天气预报网站抓取西南地区的实时天气数据,并通过Spark SQL对数据进行并行计算,提取关键气象指标,并进行多维度分析,如空气质量、降水量、风速等。 数据处理与分析:系统利用Spark对天气数据进行分布式存储与处理,通过数据分析,实时展示西南地区的空气质量、温度变化、降水量、风

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客