使用 Keepalived 和 HAProxy 的 HA K8s 集群

发布: (2026年1月9日 GMT+8 22:59)
7 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将按照要求将其翻译为简体中文并保留原有的格式和技术术语。

Source:

概览

堆叠 HA 集群是一种拓扑结构,其中由 etcd 提供的分布式数据存储集群叠加在由 kubeadm 管理的节点组成的集群之上,这些节点运行控制平面组件。

每个控制平面节点运行 kube‑apiserverkube‑schedulerkube‑controller‑manager 实例。kube‑apiserver 通过负载均衡器向工作节点暴露。

每个控制平面节点会创建一个本地 etcd 成员,该 etcd 成员仅与同一节点的 kube‑apiserver 通信。本地的 kube‑controller‑manager 和 kube‑scheduler 实例也是如此。

Diagram

该拓扑将控制平面和 etcd 成员放在同一节点上。与使用外部 etcd 节点的集群相比,它更容易搭建,也更易于管理复制。

3 节点堆叠集群的工作原理

每个控制平面节点运行:

  • 一个 etcd 成员
  • kube‑apiserver、scheduler、controller‑manager

因此你会得到:

  • 3 个 etcd 成员 → 法定人数 = 2
  • 3 个 API 服务器 → 负载均衡(可容忍 1 台宕机)

如果有一台节点故障,你仍然拥有:

  • 2 个 etcd 成员 → 法定人数仍然满足
  • 2 个控制平面实例 → 仍可用

这是 kubeadm 部署的默认拓扑。使用 kubeadm initkubeadm join --control-plane 时,会在控制平面节点上自动创建本地 etcd 成员。

前提假设:你已经使用 kubeadm 完成了集群的引导,因为本文档不详细介绍这些步骤。

Source:

设置机器

要为 Kubernetes 高可用(HA)使用 HAProxy + Keepalived 并配置 3 台 master 节点和一个虚拟 IP(VIP),请按照以下结构化步骤操作。

Master 节点

  • 10.238.40.162
  • 10.238.40.163
  • 10.238.40.164

VIP:10.238.40.166

在所有 master 上安装 HAProxy 和 Keepalived

sudo apt update
sudo apt install -y haproxy keepalived

HAProxy 配置

所有三台 master 节点上编辑 /etc/haproxy/haproxy.cfg

global
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option httplog
    option dontlognull

frontend kubernetes-apiserver
    bind *:8443
    mode tcp
    option tcplog
    default_backend kubernetes-apiserver

backend kubernetes-apiserver
    mode tcp
    balance roundrobin
    option tcp-check
    server master1 10.238.40.162:6443 check fall 3 rise 2
    server master2 10.238.40.163:6443 check fall 3 rise 2
    server master3 10.238.40.164:6443 check fall 3 rise 2

Keepalived 配置

一次只能有一个节点“拥有”VIP(由 Keepalived 管理),但配置文件需要放在 所有 节点上。

在每个 master 节点上编辑 /etc/keepalived/keepalived.conf
注意:为每个节点调整 priority 值:

节点优先级角色
Master1110MASTER
Master2100BACKUP
Master390BACKUP
global_defs {
    router_id LVS_DEVEL
    script_user root
    enable_script_security
}

vrrp_script chk_haproxy {
    script "/bin/curl -f http://localhost:6443/healthz || exit 1"
    interval 2
    weight -2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface enp19s0
    virtual_router_id 51
    priority 110          # 根据上表在各节点上修改
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k8s-ha-cluster
    }
    virtual_ipaddress {
        10.238.40.166/24
    }
    track_script {
        chk_haproxy
    }
}

重启服务

sudo systemctl restart haproxy keepalived
sudo systemctl enable haproxy keepalived

验证 VIP

ip addr show | grep 10.238.40.166

VIP verification screenshot

检查服务状态

sudo systemctl status haproxy
sudo systemctl status keepalived

Source:

引导集群

第一台 主节点上创建 kubeadm-config.yaml 文件。
使用 VIP 作为控制平面端点,并将其加入 apiServer.certSANs

重要:将 InitConfiguration 中的 advertiseAddress 字段更改为对应每台主节点的 IP 地址。

apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.32.6
apiServer:
  certSANs:
    - "10.238.40.166"      # VIP
    - "127.0.0.1"          # localhost
    - "0.0.0.0"            # wildcard
    - "10.96.0.1"          # Kubernetes service IP
    - "10.238.40.162"
    - "10.238.40.163"
    - "10.238.40.164"
  extraArgs:
    # (add any extra arguments you need here)

继续执行常规的 kubeadm init / kubeadm join 步骤,使用 VIP(10.238.40.166)作为控制平面端点。

kubeadm 配置

horization-mode: Node,RBAC
certificatesDir: /etc/kubernetes/pki
clusterName: pcai
controlPlaneEndpoint: "10.238.40.166:8443"
controllerManager:
  extraArgs:
    bind-address: 0.0.0.0
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
networking:
  dnsDomain: cluster.local
  podSubnet: "172.20.0.0/16"
  serviceSubnet: "172.30.0.0/16"
scheduler:
  extraArgs:
    bind-address: 0.0.0.0
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: "10.238.40.162"
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

初始化集群

kubeadm init --upload-certs --config kubeadm-config.yaml -v=5

注意: 保存输出!其中包含控制平面和工作节点的加入命令。

配置 kubectl 访问

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

安装网络方案(Calico)

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml

等待网络 Pod 准备就绪

kubectl wait --for=condition=ready pod -l k8s-app=calico-node -n kube-system --timeout=300s

加入额外的控制平面节点

在其他主节点上运行控制平面加入命令(kubeadm init 的输出):

kubeadm join 10.238.40.166:8443 --token  \
  --discovery-token-ca-cert-hash sha256: \
  --control-plane --certificate-key 

注意: 证书密钥仅在 2 小时内有效。如果过期,请生成新的密钥:

kubeadm init phase upload-certs --upload-certs

验证与健康检查

检查所有节点是否就绪

kubectl get nodes -o wide

验证控制平面组件

kubectl get pods -n kube-system

检查 etcd 集群健康状态

kubectl exec -n kube-system etcd- -- etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

测试 VIP 故障转移

# Stop keepalived on the master node that owns the VIP
sudo systemctl stop keepalived

# Verify VIP moves to another node
ip addr show | grep 10.238.40.166

# Test API access via VIP
curl -k https://10.238.40.166:8443/healthz

# Restart keepalived
sudo systemctl start keepalived

结论

恭喜!您已成功部署了一个使用堆叠 etcd 拓扑、HAProxy 和 Keepalived 的高可用 Kubernetes 集群。该部署提供了:

关键优势

  • 高可用性: 自动故障转移,无单点故障
  • 负载分配: 通过 HAProxy 将流量分配到所有 API Server
  • 自动恢复: Keepalived 在几秒内完成 VIP 故障转移
  • 简化架构: 与外部 etcd 相比,堆叠拓扑降低了复杂性

集群能力

在此 3‑master 节点配置下:

  • 能容忍 1 台节点故障,仍保持完整的集群功能
  • 通过 3 个成员中的 2 个维持 etcd 仲裁
  • 通过剩余的健康主节点继续提供 API 请求服务
  • 自动将 VIP 故障转移到可用节点
Back to Blog

相关文章

阅读更多 »

你好,我是新人。

嗨!我又回到 STEM 的领域了。我也喜欢学习能源系统、科学、技术、工程和数学。其中一个项目是…