16.1.7 高可用架构与故障域设计
高可用架构的目标是消除控制平面与关键数据通道的单点故障,确保集群在组件故障、节点宕机或网络分区时仍能维持核心功能。Kubernetes 的高可用需要从控制平面、数据存储、网络与依赖组件四个层面协同设计,并与故障域(可用区/机架/机房)隔离策略结合。
控制平面高可用设计要点
- 多主节点部署:至少 3 个控制平面节点,满足 etcd 法定人数。
- API Server 多副本:前置 L4/L7 负载均衡或 VIP 入口。
- Controller Manager 与 Scheduler 选主:leader election 保证同一时刻仅一个主控实例。
- etcd 集群化:3/5/7 节点奇数部署,跨故障域分布。
安装与配置示例(高可用 API 入口 + 控制平面)
1)部署 HAProxy + Keepalived(API 入口)
文件路径:/etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 2000
defaults
mode tcp
timeout connect 5s
timeout client 50s
timeout server 50s
frontend k8s-api
bind *:6443
default_backend k8s-masters
backend k8s-masters
balance roundrobin
option tcp-check
server cp1 10.0.1.11:6443 check
server cp2 10.0.1.12:6443 check
server cp3 10.0.1.13:6443 check
文件路径:/etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.1.100/24
}
}
启动服务并验证:
systemctl enable --now haproxy
systemctl enable --now keepalived
# 预期:VIP 10.0.1.100 绑定在主节点网卡
ip a | grep 10.0.1.100
2)Kubeadm 初始化第一个控制平面
kubeadm init \
--control-plane-endpoint "10.0.1.100:6443" \
--upload-certs \
--pod-network-cidr 10.244.0.0/16
# 预期输出:join 命令,包含 --control-plane 和 --certificate-key
3)加入其余控制平面节点
kubeadm join 10.0.1.100:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
故障域设计与拓扑感知(示例)
- 节点打标签:故障域/可用区标识
kubectl label node w1 topology.kubernetes.io/zone=zone-a
kubectl label node w2 topology.kubernetes.io/zone=zone-b
kubectl label node w3 topology.kubernetes.io/zone=zone-c
- 副本分布策略:TopologySpreadConstraints
文件路径:deploy-ha.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-ha
spec:
replicas: 3
selector:
matchLabels:
app: web-ha
template:
metadata:
labels:
app: web-ha
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web-ha
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
应用并验证分布:
kubectl apply -f deploy-ha.yaml
kubectl get pod -o wide -l app=web-ha
# 预期:Pod 分散在不同 zone 的节点
etcd 高可用与一致性(示例与验证)
- 查看 etcd 健康
# 在任一控制平面节点执行
ETCDCTL_API=3 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 \
endpoint health
# 预期:each endpoint is healthy
- 快照备份与恢复演练
# 备份
ETCDCTL_API=3 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 \
snapshot save /var/backups/etcd-$(date +%F).db
# 校验
ETCDCTL_API=3 etcdctl snapshot status /var/backups/etcd-$(date +%F).db
网络与入口高可用(示例)
- Ingress Controller 多副本
kubectl -n ingress-nginx scale deploy ingress-nginx-controller --replicas=3
kubectl -n ingress-nginx get pod -o wide
- CoreDNS 高可用
kubectl -n kube-system scale deploy coredns --replicas=3
kubectl -n kube-system get pod -l k8s-app=kube-dns -o wide
故障排查(典型问题与命令)
- API 入口不可达
# 检查 LB/VIP 状态
ip a | grep 10.0.1.100
systemctl status haproxy keepalived
# 检查 apiserver 端口
nc -vz 10.0.1.11 6443
nc -vz 10.0.1.12 6443
nc -vz 10.0.1.13 6443
- etcd quorum 丢失
# 查看成员与健康
ETCDCTL_API=3 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
# 现象:member 状态为 unhealthy 或连接超时
- 副本未跨域分布
kubectl get node -L topology.kubernetes.io/zone
kubectl describe pod -l app=web-ha | grep -i topology
命令解释速查
- kubeadm init --control-plane-endpoint:指定 API 统一入口(VIP/LB)。
- --upload-certs:分发控制平面证书,便于多主加入。
- etcdctl endpoint health:检查 etcd 成员健康状态。
- topologySpreadConstraints:强制副本跨故障域分布。
练习
1. 设计 3 个可用区的控制平面与 etcd 布局,画出拓扑并说明数据一致性策略。
2. 使用 TopologySpreadConstraints 与 podAntiAffinity 对比测试副本分布结果。
3. 模拟一个控制平面宕机:停止 kube-apiserver 容器,验证 API 入口可用性。
4. 对 etcd 进行快照备份与恢复演练,记录 RTO/RPO 指标。