容器化部署Kubernetes高可用负载均衡:Haproxy与Keepalived的最佳实践

在云原生技术快速发展的今天,Kubernetes已经成为容器编排的事实标准。对于生产环境而言,高可用性是不可妥协的需求。本文将带你探索如何利用Docker容器化部署Haproxy和Keepalived,为Kubernetes集群构建高可用负载均衡层。

1. 为什么选择容器化部署负载均衡?

传统部署方式通常直接在主机上安装Haproxy和Keepalived,这种方式虽然直接,但存在几个明显痛点:

  • 环境依赖复杂:需要手动安装各种依赖库和工具
  • 版本管理困难:升级或回滚需要重新配置整个环境
  • 隔离性差:与主机系统耦合度高,容易产生冲突
  • 可移植性低:难以在不同环境间迁移配置

容器化部署完美解决了这些问题:

# 容器化部署的核心优势
1. **环境隔离**:每个服务运行在独立的容器中
2. **快速部署**:通过镜像一键启动,无需复杂配置
3. **版本控制**:轻松切换不同版本镜像
4. **资源限制**:可精确控制CPU/内存使用
5. **日志集中**:容器日志统一管理

我们选择的方案是:

  • Haproxy:作为负载均衡器,分发流量到多个Kubernetes Master节点
  • Keepalived:提供VIP(虚拟IP)故障转移能力
  • Docker:作为容器运行时,封装和运行这两个服务

2. 环境准备与配置

2.1 系统要求

在开始之前,确保你的主机满足以下要求:

组件要求备注
操作系统CentOS 7.x内核版本3.10+
Docker18.09+需要支持cgroup v1
内存2GB+每个节点最低要求
CPU2核+建议4核
网络稳定局域网节点间延迟<1ms

2.2 基础环境配置

这些配置需要在所有节点上执行:

# 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld

# 禁用SELinux
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

# 关闭swap
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

# 加载内核模块
modprobe br_netfilter
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules

提示:这些配置修改后建议重启系统以确保所有设置生效

3. 容器化部署Haproxy

3.1 Haproxy容器选择

我们推荐使用wise2c/haproxy-k8s镜像,这是一个专为Kubernetes优化的Haproxy镜像:

docker pull wise2c/haproxy-k8s

3.2 配置文件准备

创建Haproxy配置文件/etc/haproxy/haproxy.cfg

global
    log /dev/log local0
    log /dev/log local1 notice
    daemon

defaults
    log global
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend k8s-api
    bind *:6444
    default_backend k8s-api-servers

backend k8s-api-servers
    balance roundrobin
    server master1 192.168.1.161:6443 check
    server master2 192.168.1.162:6443 check
    server master3 192.168.1.163:6443 check

3.3 启动Haproxy容器

使用以下命令启动容器:

docker run -d --name haproxy-k8s \
  -p 6444:6444 \
  -v /etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
  --restart always \
  wise2c/haproxy-k8s

关键参数说明:

  • -p 6444:6444:将容器内的6444端口映射到主机
  • -v:挂载配置文件
  • --restart always:确保容器异常退出后自动重启

4. 容器化部署Keepalived

4.1 Keepalived容器选择

同样使用wise2c/keepalived-k8s镜像:

docker pull wise2c/keepalived-k8s

4.2 Keepalived配置

Keepalived需要特殊权限,因此使用host网络模式运行:

docker run -d --name keepalived-k8s \
  --net=host \
  --cap-add=NET_ADMIN \
  --cap-add=NET_BROADCAST \
  --cap-add=NET_RAW \
  -e VIRTUAL_IP=192.168.1.160 \
  -e INTERFACE=eth0 \
  -e CHECK_PORT=6444 \
  -e RID=10 \
  -e VRID=160 \
  --restart always \
  wise2c/keepalived-k8s

环境变量说明:

  • VIRTUAL_IP:VIP地址
  • INTERFACE:网络接口名称
  • CHECK_PORT:健康检查端口(对应Haproxy端口)
  • RID:路由ID
  • VRID:虚拟路由ID

4.3 验证VIP

部署完成后,检查VIP是否生效:

ip addr show eth0

输出中应该能看到VIP地址:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:01:6e:37 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.161/24 brd 192.168.1.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.1.160/24 scope global secondary eth0
       valid_lft forever preferred_lft forever

5. 与Kubernetes集群集成

5.1 初始化Kubernetes集群

使用kubeadm初始化集群时,指定VIP和Haproxy端口:

kubeadm init --control-plane-endpoint "192.168.1.160:6444" --upload-certs

5.2 加入其他Master节点

在其他Master节点上执行kubeadm join命令:

kubeadm join 192.168.1.160:6444 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --control-plane --certificate-key <key>

5.3 验证集群状态

在所有Master节点上执行:

kubectl get nodes

应该看到所有节点状态为Ready:

NAME      STATUS   ROLES    AGE   VERSION
master1   Ready    master   10m   v1.19.0
master2   Ready    master   8m    v1.19.0
master3   Ready    master   5m    v1.19.0

6. 高级配置与优化

6.1 Haproxy性能调优

修改haproxy.cfg添加性能相关参数:

global
    maxconn 20000
    tune.ssl.default-dh-param 2048

defaults
    maxconn 10000

6.2 Keepalived健康检查优化

可以自定义健康检查脚本,确保只有Haproxy健康时才切换VIP:

# 创建检查脚本
cat > /etc/keepalived/check_haproxy.sh <<'EOF'
#!/bin/bash
if ! killall -0 haproxy; then
  exit 1
fi
exit 0
EOF
chmod +x /etc/keepalived/check_haproxy.sh

6.3 日志收集方案

建议将容器日志统一收集:

# 修改Docker日志驱动为json-file并限制大小
cat > /etc/docker/daemon.json <<EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
EOF
systemctl restart docker

7. 故障排查指南

7.1 VIP无法访问

检查步骤:

  1. 确认Keepalived容器正常运行:docker ps | grep keepalived
  2. 检查VIP是否分配:ip addr show eth0
  3. 验证网络连通性:ping 192.168.1.160

7.2 Haproxy负载不均衡

排查方法:

  1. 检查后端服务器状态:echo "show stat" | socat /var/run/haproxy/admin.sock stdio
  2. 验证端口连通性:telnet 192.168.1.161 6443
  3. 查看Haproxy日志:docker logs haproxy-k8s

7.3 脑裂问题处理

预防措施:

  • 确保所有节点时钟同步
  • 合理设置Keepalived优先级
  • 配置多播检测
# 检查时钟同步
timedatectl status

# 强制同步时间
ntpdate pool.ntp.org

这种容器化部署方案不仅简化了Kubernetes高可用集群的搭建过程,还大大提高了部署的可靠性和可维护性。在实际生产环境中,可以结合CI/CD流水线实现自动化部署和更新,进一步提升运维效率。

更多推荐