REK2 搭建6节点K8S教程(二):HAProxy + Keepalived 高可用

上一章我们介绍可机器的基础设置,本章我们来介绍配置K8S的高可用特性,在本章你将了解到 RKE2 的“自动故障转移”机制是什么?HAProxy + Keepalived 的作用是什么?以及如何配置HAProxy + Keepalived。


在 RKE2 高可用集群 中,虽然 RKE2 本身带有“自动故障转移”机制(例如 Kubernetes 的 kubectl 客户端会按顺序尝试访问多个 API Server 地址),但这与 HAProxy + Keepalived 的作用 是不同维度的功能补充。

1. RKE2 的“自动故障转移”机制是什么?

RKE2 的自动故障转移(failover)是客户端层面的冗余

  • Kubernetes 客户端(如 kubectlkubelet)会读取 kubeconfig 文件中的多个 API Server 地址,并按顺序尝试连接。
  • 如果某个 API Server 不可用(例如节点宕机),客户端会自动切换到下一个地址
  • RKE2 会将所有 Control Plane 节点的 API Server 地址写入 kubeconfig 文件(例如 /etc/rancher/rke2/rke2.yaml)。
clusters:
  - name: default
    cluster:
      server: https://10.88.88.71:6443
      server: https://10.88.88.72:6443
      server: https://10.88.88.73:6443
      insecure-skip-tls-verify: true

优点

  • 简单:无需额外部署负载均衡器或虚拟 IP 。
  • 客户端自动尝试多个 API Server 地址,保证连通性。
  • 适用于 小规模集群或测试环境

缺点

  • 客户端需要维护多个 API Server 地址(通常位于 kubeconfig 文件中)。
  • 故障转移延迟较高(客户端会按顺序逐个尝试地址)。
  • 无法提供负载均衡(如轮询、权重分配、健康检查等)。
  • 客户端配置复杂性:每次新增或删除 Control Plane 节点时,需要更新 kubeconfig 文件。

2. HAProxy + Keepalived 的作用

HAProxy 和 Keepalived 提供的是网络层和服务发现层面的高可用性,与 RKE2 内置的“客户端自动故障转移”是互补的。

(1)HAProxy 的作用

  • 负载均衡
    • 支持 TCP/HTTP 层的负载均衡(RKE2 的 API Server 是基于 TCP 的)。
    • 支持轮询(round-robin)、加权轮询、最小连接数等策略。
  • 健康检查
    • 自动检测后端 API Server 的状态(如端口 6443 是否可用)。
    • 如果某个 API Server 节点宕机,HAProxy 会自动将其从负载池中移除,避免流量打到故障节点。
  • 集中管理入口
    • 客户端只需配置一个 VIP(虚拟 IP)作为 API Server 入口,无需手动维护多个地址。

(2)Keepalived 的作用

  • 虚拟 IP(VIP)管理
    • 提供一个统一的 API Server 入口(例如 192.168.1.200)。
    • 当主节点故障时,VIP 自动漂移到健康的备用节点,实现无缝故障切换。
  • 主备容灾
    • 通过 VRRP 协议实现主备切换,确保负载均衡本身的高可用。
  • 简化客户端配置
    • 所有客户端(如 kubectlkubelet、外部用户)只需访问 VIP,无需关心后端节点。

3. HAProxy + Keepalived部署

节点IP/hostname系统
VIP(虚拟IP)10.88.88.70虚拟IP
Master110.88.88.71/k8sm1Ubuntu Server 22.04 LTS
Master210.88.88.72/k8sm2Ubuntu Server 22.04 LTS
Master310.88.88.73/k8sm3Ubuntu Server 22.04 LTS
Worker110.88.88.74/k8sn1Ubuntu Server 22.04 LTS
Worker210.88.88.75/k8sn2Ubuntu Server 22.04 LTS
ManageNode110.88.88.76/k8smgtUbuntu Server 22.04 LTS

3.1 安装HAProxy + Keepalived

在三台master上执行安装命令。

apt install  haproxy keepalived -y

编辑配置文件

cd /etc/haproxy/
mv haproxy.cfg haproxy.cfg.bak #备份文件,默认的没用了
vim haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    # log         127.0.0.1 local2
    log         /var/log/haproxy.log local2  # 日志写入到 /var/log/haproxy.log,使用 local2 设施
    chroot      /var/lib/haproxy             # 将 HAProxy 绑定到 chroot 目录
    pidfile     /var/run/haproxy.pid         # 指定进程 ID 文件路径
    maxconn     4000                          # 最大连接数限制
    user        haproxy                       # 使用 haproxy 用户运行
    group       haproxy                       # 使用 haproxy 组运行
    daemon                                   # 以后台模式运行

    # 启用统计信息的 Unix socket
    stats socket /var/lib/haproxy/stats      # 用于管理命令和监控的 socket 路径
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http      # 默认使用 HTTP 模式
    log                     global    # 使用全局日志配置
    option                  httplog   # 记录 HTTP 请求日志
    option                  dontlognull  # 忽略空请求日志
    option http-server-close # 关闭服务器端的连接保持(避免资源浪费)
    option forwardfor       except 127.0.0.0/8  # 设置 X-Forwarded-For 头(排除回环地址)
    option                  redispatch # 当服务器不可用时,重新分配请求到其他服务器
    retries                 3         # 最大重试连接后端服务器的次数
    timeout http-request    10s       # HTTP 请求超时时间
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000      # 每个进程最大连接数
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#---------------------------------------------------------------------
frontend rke2-apiserver
    mode                 tcp        # 使用 TCP 模式(适合代理 Kubernetes API Server)
    bind                 *:19345    # 监听所有接口的 19345 端口
    option               tcplog    # 记录 TCP 级别的日志
    default_backend      rke2-apiserver  # 指定默认后端为 rke2-apiserver
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend rke2-apiserver
    mode        tcp        # 使用 TCP 模式
    option      tcplog    # 记录 TCP 日志
    option      tcp-check # 启用 TCP 健康检查
    balance     roundrobin # 使用轮询负载均衡算法
    default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
    server      k8sm1   10.88.88.71:9345 check 
    server      k8sm2   10.88.88.72:9345 check
    server      k8sm3   10.88.88.73:9345 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080          # 监听所有接口的 1080 端口
    stats auth           admin:QingHaoPassword  # 访问统计页面的用户名和密码
    stats refresh        5s            # 页面自动刷新间隔
    stats realm          HAProxy\ Statistics  # 访问认证的 Realm 名
    stats uri            /admin?stats  # 统计页面的访问路径

#19345 是 HAProxy 的前端端口,客户端通过此端口访问 HAProxy 。
#9345 是 HAProxy 后端后端服务器的端口,即 HAProxy 会将流量转发到后端服务器的 9345 端口。
cd /etc/keepalived
mv keepalived.conf keepalived.conf.bak
vim /etc/keepalived/keepalived.conf
global_defs {
    script_user root
    enable_script_security
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh" # 定义脚本路径和名称
    interval 5 # 每 5 秒执行一次检测,注意设置间隔太小会有问题
    weight -15 # 权重变化
    fall 2     # 检测连续2次失败才算失败
    rise 1     # 检测1次成功就算成功
}
vrrp_instance VI_1 {
    state MASTER # backup节点设为BACKUP, <看情况调整>
    interface ens160 # 服务器网卡接口
    virtual_router_id 51  # 这个值只要在 keepalived 集群中保持一致即可,默认值是 51
    priority 100 #如:master设为 100,备份服务 50,比备份服务器上高就行了,如:master设为 100,备份服务 50
    advert_int 1     
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH  #这个值只要在keepalived集群中保持一致即可
    }
    virtual_ipaddress {
        10.88.88.70   # VIP 地址,<看情况调整>
    }
    track_script {
       chk_apiserver
    }
}

脚本:check_apiserver.sh

该脚本通过检查 HAProxy 进程是否存在来判断 HAProxy 服务是否正常。如果 HAProxy 进程异常(连续多次检测失败),脚本会主动停止 Keepalived 服务,促使虚拟 IP(VIP)漂移到健康的节点。

为什么需要这个脚本?

VRRP 的局限性:VRRP 本身只能管理 VIP 的分配,无法直接感知 HAProxy 或 API Server 的状态。此脚本通过主动检查 HAProxy 的运行状态,为 VRRP 提供额外的健康检查信息。

直接控制 Keepalived:当 HAProxy 故障时,主动停止 Keepalived 服务,确保 VIP 能够快速漂移到其他节点。

避免“脑裂”:如果 HAProxy 故障后 Keepalived 仍然持有 VIP,会导致流量无法正常转发。通过强制停止 Keepalived,可以快速释放 VIP,避免资源浪费。

vim /etc/keepalived/check_apiserver.sh
#!/bin/bash 
err=0
for k in $(seq 1 3)
do
    check_code=$(pgrep haproxy)
    if [[ $check_code == "" ]]; then
        err=$(expr $err + 1)
        sleep 1
        continue
    else
        err=0
        break
    fi
done

if [[ $err != "0" ]]; then
    echo "systemctl stop keepalived"
    /usr/bin/systemctl stop keepalived
    exit 1
else
    exit 0
fi
chmod +x /etc/keepalived/check_apiserver.sh #给与脚本权限

启动服务

systemctl enable haproxy 
systemctl restart haproxy
systemctl enable keepalived 
systemctl restart keepalived

检查IP:

ip addr 
#输出
root@k8sm3:/etc/keepalived# ip addr
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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:63:38:36 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.88.88.73/24 brd 10.88.88.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe63:3836/64 scope link
       valid_lft forever preferred_lft forever

3.2 测试

停止haproxy 服务,然后过10秒再使用ip addr 查看VIP是否还存在,不存在则判定漂移到另外的两个master节点上。

ip addr
#输出
root@k8sm1:~# ip addr
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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:09:aa:17 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.88.88.71/24 brd 10.88.88.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet 10.88.88.70/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe09:aa17/64 scope link
       valid_lft forever preferred_lft forever

service haproxy restart && service keepalived restart #执行后,VIP漂移到其他节点。

ip addr
#输出
root@k8sm1:~# ip addr
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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:09:aa:17 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.88.88.71/24 brd 10.88.88.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe09:aa17/64 scope link
       valid_lft forever preferred_lft forever

REK2 搭建6节点K8S教程(一):系统准备 GitLab CE搭建指南 REK2 搭建6节点K8S教程(三):RKE节点安装
View Comments
There are currently no comments.