跳转到内容
123xiao | 无名键客

《Kubernetes 集群高可用架构实战:从控制平面冗余到故障切换设计》

字数: 0 阅读时长: 1 分钟

背景与问题

很多团队第一次做 Kubernetes 高可用,往往把重点放在“多加几台 master”上,结果上线后才发现:控制平面节点变多,不等于集群真的高可用

我见过几类非常典型的事故:

  • 控制平面有 3 台,但前面只放了一个单点负载均衡,LB 一挂整个集群 API 不可用
  • etcd 做了 3 节点,但部署在同一台物理宿主机或同一可用区,宿主机故障直接团灭
  • kubeadm 初始化时 controlPlaneEndpoint 配置不规范,后续证书、加入节点、切换流量都出问题
  • kube-apiserver 虽然有多副本,但控制器和调度器的 Leader Election 配置异常,故障切换慢到业务已经报警
  • 节点健康检查阈值设置不合理,结果不是“高可用”,而是“高抖动”

所以这篇文章不只是讲“标准架构长什么样”,而是从 “为什么看起来冗余了,实际仍然会中断” 这个 troubleshooting 视角出发,带你梳理:

  1. 控制平面高可用真正依赖哪些组件
  2. 故障切换链路是怎么工作的
  3. 如何用一套可运行的配置快速搭建
  4. 出现 API 不通、切换慢、选主异常时怎么排查
  5. 哪些安全和性能优化值得优先做

先看全局:高可用不是“堆机器”,而是“消灭单点”

一个可靠的 Kubernetes 高可用集群,至少要同时覆盖下面几个层次:

  • 访问入口高可用:客户端访问 API Server 不能依赖单点
  • 控制平面高可用:多个 apiserver、controller-manager、scheduler
  • 状态存储高可用:etcd 多副本并保持法定多数
  • 网络与 DNS 可恢复:节点故障后服务发现和网络插件不拖后腿
  • 故障切换可验证:不是“理论上能切”,而是演练过、观测过

下面这张图可以先建立整体认知。

flowchart TD
    A[kubectl / CI / Controller] --> B[VIP 或 LB]
    B --> C1[kube-apiserver-1]
    B --> C2[kube-apiserver-2]
    B --> C3[kube-apiserver-3]

    C1 --> E1[etcd-1]
    C2 --> E2[etcd-2]
    C3 --> E3[etcd-3]

    C1 --> F1[kube-controller-manager]
    C2 --> F2[kube-controller-manager]
    C3 --> F3[kube-controller-manager]

    C1 --> G1[kube-scheduler]
    C2 --> G2[kube-scheduler]
    C3 --> G3[kube-scheduler]

    C1 -. watch/list .-> H[Worker Nodes]
    C2 -. watch/list .-> H
    C3 -. watch/list .-> H

背景与问题

常见故障现象

在排障现场,通常不是“高可用失败”这么抽象,而是以下这些可观测问题:

  • kubectl get nodes 卡住或超时
  • 新 Pod 长时间 Pending
  • Deployment 无法滚动发布
  • Node NotReady 后很久业务流量还没摘除
  • 部分控制平面节点恢复后,集群出现频繁 leader 切换
  • etcd 告警:failed to reach the peerURLleader changed

为什么控制平面最容易被低估

因为业务 Pod 运行在 worker 上,很多人天然认为“只要 worker 多,业务就稳”。但实际上:

  • 调度 需要 scheduler
  • 副本自愈 需要 controller-manager
  • Service/Ingress/Operator 大量依赖 apiserver
  • 集群状态一致性 靠 etcd

换句话说,控制平面不是“管理面可有可无”,它一旦不可用,集群很快从“还能跑”进入“不能变更、不能恢复、故障扩散”的状态。


核心原理

这一部分重点回答两个问题:

  1. 为什么 3 控制平面是常见选择?
  2. 故障切换到底是怎么发生的?

1. 控制平面冗余的最小合理形态

对于生产环境,最常见的是:

  • 3 台控制平面节点
  • 1 个虚拟入口(VIP 或外部 LB)
  • 3 节点 etcd 集群(可堆叠在控制平面,也可独立)

原因很简单:
etcd 基于 Raft,需要多数派(quorum)才能写入。

  • 1 节点:无高可用
  • 2 节点:任意一台故障后失去多数,设计上不划算
  • 3 节点:允许 1 台故障,成本与可靠性最平衡
  • 5 节点:可容忍 2 台故障,但写入延迟、运维复杂度更高

2. 控制器和调度器并不是“同时工作”,而是“抢主工作”

kube-controller-managerkube-scheduler 通常都会开多个实例,但真正对外生效的通常只有一个 Leader,其余是热备。

stateDiagram-v2
    [*] --> Standby1
    [*] --> Leader
    [*] --> Standby2

    Leader --> Failed: 节点宕机/进程退出
    Failed --> ReElection: 租约失效
    ReElection --> NewLeader: 其他实例抢占成功
    NewLeader --> Leader

这里的关键依赖是 Leader Election 租约机制
如果租约参数过大,切换会慢;如果太小,又容易抖动。

常见参数包括:

  • --leader-elect=true
  • --leader-elect-lease-duration
  • --leader-elect-renew-deadline
  • --leader-elect-retry-period

3. API Server 高可用依赖入口层

kube-apiserver 可以多实例,但客户端是否能自动切换,取决于前面的入口。

常见做法:

  • 云上:使用云厂商 SLB/NLB
  • 自建机房:HAProxy + Keepalived
  • 裸金属:LVS / F5 / 硬件 LB

这里有个容易忽略的点:
API Server 的高可用不只是“流量分发”,还涉及健康检查是否准确。

如果 LB 只检查 TCP 6443 端口连通,而不检查更深层的健康状态,就可能把流量仍然导向“端口活着但内部卡死”的 apiserver。

4. etcd 是高可用链路里最脆弱、也最关键的点

etcd 存的是集群事实状态,所有控制器基本都围着它转。

etcd 故障的典型后果:

  • apiserver 读写失败
  • 资源创建/更新失败
  • 调度停滞
  • 控制器无法推进状态

因此高可用设计里最重要的一条经验就是:

控制平面节点挂一台还能顶住,etcd 多数派一丢,整个集群就进入危险区。

下面这张时序图展示一个控制平面节点故障后的切换过程。

sequenceDiagram
    participant Client as kubectl/业务控制器
    participant LB as LB/VIP
    participant API1 as apiserver-1
    participant API2 as apiserver-2
    participant CM as controller-manager
    participant ETCD as etcd集群

    Client->>LB: 请求 /api
    LB->>API1: 转发请求
    API1->>ETCD: 读写资源
    API1--xLB: 节点故障/无响应

    Client->>LB: 重试请求
    LB->>API2: 健康检查后切换转发
    API2->>ETCD: 继续处理请求

    CM--xCM: 原 Leader 故障
    CM->>ETCD: 其他实例基于租约重新选主
    ETCD-->>CM: 新 Leader 生效

架构选型与取舍

方案一:堆叠式控制平面(Stacked etcd)

即 etcd 与控制平面组件部署在同一批 master 节点上。

优点

  • 部署简单,适合中小规模集群
  • kubeadm 支持成熟
  • 节点数量少,运维成本相对低

缺点

  • 控制平面与存储状态机耦合
  • 节点资源争抢时,etcd 更容易受影响
  • 故障域重叠,需要更严格的资源隔离

方案二:外部 etcd

控制平面节点和 etcd 节点分开部署。

优点

  • etcd 独立,资源更可控
  • 故障域更清晰
  • 大规模集群更稳

缺点

  • 组件更多,证书和网络配置更复杂
  • 维护门槛更高

我给中级团队的建议

如果你们当前:

  • 集群规模中等
  • 运维团队人数有限
  • 主要目标是“先把高可用做扎实”

那么优先选:

3 控制平面 + stacked etcd + HAProxy/Keepalived 或云 LB

如果你们已经有:

  • 多可用区部署
  • 大量 CRD/Operator
  • 高并发 API 请求
  • 独立平台团队

再考虑外部 etcd。


实战代码(可运行)

下面给出一个比较实用的落地示例:
使用 HAProxy + Keepalived + kubeadm 搭建 3 控制平面高可用入口。

说明:示例基于 Linux 环境,适合自建机房或虚拟机环境。
假设:

  • VIP: 10.10.0.100
  • HAProxy/Keepalived 节点:
    • 10.10.0.10
    • 10.10.0.11
  • 控制平面节点:
    • 10.10.0.21
    • 10.10.0.22
    • 10.10.0.23

1. HAProxy 配置

在两台 LB 节点上安装 HAProxy:

sudo apt-get update
sudo apt-get install -y haproxy

配置 /etc/haproxy/haproxy.cfg

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

defaults
    log global
    mode tcp
    option tcplog
    timeout connect 10s
    timeout client  1m
    timeout server  1m

frontend kubernetes-apiserver
    bind 0.0.0.0:6443
    default_backend kubernetes-control-plane

backend kubernetes-control-plane
    mode tcp
    balance roundrobin
    option tcp-check
    default-server inter 3s fall 3 rise 2
    server cp1 10.10.0.21:6443 check
    server cp2 10.10.0.22:6443 check
    server cp3 10.10.0.23:6443 check

检查配置并启动:

sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl enable haproxy
sudo systemctl restart haproxy

2. Keepalived 配置 VIP

安装:

sudo apt-get install -y keepalived

主节点 /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_K8S_01
}

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
    weight 20
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 120
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass K8SHA2023
    }
    virtual_ipaddress {
        10.10.0.100/24
    }
    track_script {
        chk_haproxy
    }
}

备节点 /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_K8S_02
}

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
    weight 20
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass K8SHA2023
    }
    virtual_ipaddress {
        10.10.0.100/24
    }
    track_script {
        chk_haproxy
    }
}

启动服务:

sudo systemctl enable keepalived
sudo systemctl restart keepalived
ip addr show

验证 VIP 是否漂移成功:

ping 10.10.0.100
nc -zv 10.10.0.100 6443

3. kubeadm 初始化第一个控制平面

10.10.0.21 上创建配置文件 kubeadm-ha.yaml

apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.27.3
controlPlaneEndpoint: "10.10.0.100:6443"
networking:
  podSubnet: "10.244.0.0/16"
apiServer:
  certSANs:
    - "10.10.0.100"
    - "10.10.0.21"
    - "10.10.0.22"
    - "10.10.0.23"
controllerManager: {}
scheduler: {}
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: "10.10.0.21"
  bindPort: 6443
nodeRegistration:
  criSocket: "unix:///var/run/containerd/containerd.sock"

初始化:

sudo kubeadm init --config kubeadm-ha.yaml --upload-certs

初始化完成后按提示配置 kubectl

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

安装网络插件,这里以 Flannel 为例:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

4. 加入其余控制平面节点

在第二、第三台控制平面节点上执行 kubeadm init 输出中的 join 命令,类似:

sudo kubeadm join 10.10.0.100:6443 \
  --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  --control-plane \
  --certificate-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

5. 验证高可用状态

kubectl get nodes -o wide
kubectl get pod -n kube-system -o wide
kubectl get endpoints kubernetes -o yaml

查看 etcd 成员状态:

export ETCDCTL_API=3
sudo etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out=table

现象复现:故障切换是否真的生效

很多高可用方案“搭好了”,但没有演练过。建议至少做下面三种验证。

场景一:杀掉一个 apiserver

在某个控制平面节点上:

sudo crictl ps | grep kube-apiserver
sudo crictl stop <apiserver-container-id>

观察:

kubectl get --raw='/readyz?verbose'
kubectl get nodes

预期结果:

  • LB 在数秒内摘除该节点
  • kubectl 请求有短暂抖动,但整体可恢复
  • 其他 apiserver 可继续服务

场景二:停掉 leader scheduler 或 controller-manager

sudo crictl ps | egrep 'kube-scheduler|kube-controller-manager'
sudo crictl stop <container-id>

查看 leader 切换:

kubectl -n kube-system get lease
kubectl -n kube-system describe lease kube-scheduler
kubectl -n kube-system describe lease kube-controller-manager

预期结果:

  • 新 leader 在租约过期后接管
  • 调度与控制回路恢复

场景三:模拟单个 etcd 节点故障

如果是 stacked etcd,可以在一台控制平面节点停掉 etcd:

sudo crictl ps | grep etcd
sudo crictl stop <etcd-container-id>

检查:

export ETCDCTL_API=3
sudo etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key \
  --endpoints=https://127.0.0.1:2379 \
  member list

预期结果:

  • 3 节点 etcd 故障 1 个仍能保持多数
  • apiserver 仍可读写
  • 若再掉 1 个,写入会明显异常

常见坑与排查

这一节我尽量按“先止血,再定位”的思路来写。

坑一:有 3 台 master,但 kubectl 仍频繁超时

常见原因

  • VIP 漂移正常,但 HAProxy 后端健康检查太宽松
  • LB 仅做 TCP 检查,未及时摘除半死不活的 apiserver
  • controlPlaneEndpoint 用了某一台真实 IP,而不是 VIP/LB 地址
  • 客户端 kubeconfig 指向旧地址

排查路径

先看 kubeconfig:

kubectl config view --minify | grep server:

确认是否指向:

https://10.10.0.100:6443

再从 LB 节点检查后端:

echo "show stat" | sudo socat stdio /run/haproxy/admin.sock

如果没有 admin socket,也可以先直接验证端口:

for ip in 10.10.0.21 10.10.0.22 10.10.0.23; do
  echo "== $ip =="
  nc -zv $ip 6443
done

再看 apiserver 本身日志:

sudo crictl ps | grep kube-apiserver
sudo crictl logs <apiserver-container-id> | tail -n 100

止血方案

  • 先把异常控制平面节点从 LB 后端摘除
  • 确认 kubeconfig 指向统一入口
  • 将不稳定节点 cordon,避免进一步影响

坑二:Leader Election 反复抖动,调度时好时坏

常见原因

  • 控制平面节点时间不同步
  • etcd 延迟高,租约续约失败
  • 控制器资源不足,被频繁 OOM 或 CPU throttle
  • 网络抖动导致租约更新延迟

排查路径

先看 lease:

kubectl -n kube-system get lease
kubectl -n kube-system describe lease kube-scheduler
kubectl -n kube-system describe lease kube-controller-manager

看事件和切换频率是否异常。

检查时间同步:

timedatectl status
chronyc tracking

检查控制平面负载:

top
vmstat 1 5
iostat -xz 1 3

查看组件日志:

sudo crictl logs <scheduler-container-id> | tail -n 100
sudo crictl logs <controller-manager-container-id> | tail -n 100

止血方案

  • 先确保 NTP/Chrony 正常
  • 控制平面节点预留足够 CPU、内存、IOPS
  • 不要和高负载业务进程混部

坑三:etcd 明明是 3 节点,还是容易雪崩

常见原因

  • 3 个 etcd 实际在同一宿主机或同一机架
  • 磁盘延迟高,fsync 慢
  • 快照和压缩策略缺失,数据库膨胀
  • 网络 MTU 或防火墙规则导致 peer 通信异常

排查命令

健康检查:

export ETCDCTL_API=3
sudo etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key \
  --endpoints=https://127.0.0.1:2379 \
  endpoint health --write-out=table

查看状态:

export ETCDCTL_API=3
sudo etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out=table

查看日志:

sudo crictl ps | grep etcd
sudo crictl logs <etcd-container-id> | tail -n 200

重点关注:

  • leader 频繁切换
  • apply/commit 延迟高
  • peer 连接失败
  • WAL 或 snapshot 相关报错

止血方案

  • 故障节点先隔离,保证剩余多数派稳定
  • 不要急着重建多个 etcd 成员,避免误操作丢多数
  • 优先确认磁盘和网络,再决定是否 remove/add member

坑四:API Server 活着,但业务还是不恢复

这也是个很真实的坑。
很多人看到 6443 通了,就以为集群恢复了。其实还要看:

  • CoreDNS 是否正常
  • CNI 是否正常
  • kube-proxy / iptables / IPVS 是否正常
  • ingress controller 是否恢复 watch
  • Operator 是否从 apiserver 重新建立连接

排查建议

kubectl get pods -A
kubectl get events -A --sort-by='.lastTimestamp'
kubectl get componentstatuses
kubectl -n kube-system get pods -o wide

注意:componentstatuses 在新版本中不再推荐作为唯一判断依据,只能辅助看。

可以重点查这些组件:

kubectl -n kube-system logs -l k8s-app=kube-dns --tail=100
kubectl -n kube-system logs -l app=flannel --tail=100

定位路径:从“API 不可用”到“根因确认”的实战顺序

如果线上报警说 Kubernetes API 不可用,我通常按这个顺序排查,效率比较高:

flowchart TD
    A[API 不可用/超时] --> B{VIP/LB 是否可达}
    B -- 否 --> C[检查 Keepalived/SLB/NLB/网络]
    B -- 是 --> D{6443 后端是否健康}
    D -- 否 --> E[检查 apiserver 进程/证书/端口]
    D -- 是 --> F{apiserver 是否能访问 etcd}
    F -- 否 --> G[检查 etcd quorum/磁盘/网络]
    F -- 是 --> H{是否为 leader election 或控制器异常}
    H -- 是 --> I[检查 scheduler/controller-manager lease]
    H -- 否 --> J[检查 CNI/CoreDNS/业务控制器]

这个顺序的核心思想是:

  1. 先看入口
  2. 再看服务端
  3. 再看状态存储
  4. 最后看上层控制器和插件

不要一开始就钻进某个 Pod 日志里,那样很容易迷路。


安全/性能最佳实践

高可用做完后,如果不补齐安全与性能细节,后面还是会出事。

安全最佳实践

1. API Server 入口只暴露必要范围

  • 6443 不要对全网开放
  • 使用安全组、ACL、内网白名单限制来源
  • 管理入口与业务入口尽量隔离

2. 证书 SAN 一开始就规划完整

至少包含:

  • VIP/LB 地址
  • 各控制平面节点 IP
  • 必要的 DNS 名称

否则后面补证书会很麻烦,尤其在已有节点加入后更痛苦。

3. etcd 一定启用 TLS

  • client 通信加密
  • peer 通信加密
  • 证书定期轮转
  • 备份文件妥善保管

4. RBAC 最小权限

很多排障脚本喜欢直接给 cluster-admin,我不建议这么做。
运维角色、CI 角色、只读巡检角色应分开。

性能最佳实践

1. etcd 用低延迟磁盘

这是最重要的一条。
如果 etcd 在慢盘上,控制平面再多都救不了。

建议:

  • SSD/NVMe 优先
  • 避免和高 IO 业务混部
  • 监控 fsync 延迟

2. 控制平面节点做资源保留

例如为 kubelet 保留资源,避免系统和控制组件争抢:

kubeReserved:
  cpu: "500m"
  memory: "1Gi"
systemReserved:
  cpu: "500m"
  memory: "1Gi"
evictionHard:
  memory.available: "200Mi"

3. 健康检查阈值别“过度灵敏”

太激进会导致抖动式摘除,太宽松又切换太慢。
建议结合实际网络延迟做压测后调整,不要照搬网上参数。

4. 做监控,但更要做演练

至少监控这些指标:

  • apiserver 请求延迟、5xx
  • etcd leader 变更次数
  • etcd fsync/commit 延迟
  • controller-manager 和 scheduler 选主变化
  • Node Ready/NotReady 数量
  • LB 后端健康状态

同时定期演练:

  • 单控制平面节点故障
  • 单 etcd 节点故障
  • LB 主节点故障
  • 网络隔离场景

一份简单的巡检脚本

下面给一个可直接运行的 Bash 脚本,用于快速检查控制平面关键状态。

#!/usr/bin/env bash
set -euo pipefail

VIP="${1:-10.10.0.100}"
PORT="${2:-6443}"

echo "== 1. 检查 VIP/LB 连通性 =="
if nc -z -w 2 "$VIP" "$PORT"; then
  echo "[OK] $VIP:$PORT reachable"
else
  echo "[FAIL] $VIP:$PORT unreachable"
fi

echo
echo "== 2. 检查节点状态 =="
kubectl get nodes -o wide || true

echo
echo "== 3. 检查控制平面 Pod =="
kubectl get pods -n kube-system -o wide | egrep 'etcd|kube-apiserver|kube-controller-manager|kube-scheduler' || true

echo
echo "== 4. 检查 Leader Election =="
kubectl -n kube-system get lease || true

echo
echo "== 5. 检查 apiserver readyz =="
kubectl get --raw='/readyz?verbose' || true

echo
echo "== 6. 检查最近事件 =="
kubectl get events -A --sort-by='.lastTimestamp' | tail -n 20 || true

执行:

chmod +x k8s-ha-check.sh
./k8s-ha-check.sh 10.10.0.100 6443

这个脚本不是万能的,但在“先看大盘有没有明显异常”这件事上很省时间。


边界条件:哪些情况下 3 master 也不够

高可用不是银弹。以下场景中,仅有 3 控制平面并不能真正满足需求:

  • 跨地域容灾:这已经不是单集群高可用,而是多集群灾备问题
  • 强隔离合规要求:需要独立 etcd、独立网络域、严格审计
  • 超大规模集群:控制面与 etcd 资源、API QPS、控制器复杂度都上升
  • 多可用区网络质量差:跨 AZ 延迟过高会影响 etcd 与选主稳定性

这时候要考虑:

  • 多集群架构
  • 联邦或 GitOps 统一管理
  • 外部 etcd
  • 分层入口与多级流量治理

总结

Kubernetes 高可用的关键,不是“把 master 数量从 1 变成 3”,而是把整条链路梳理完整:

  • 入口层:VIP / LB 不能单点
  • 控制平面:apiserver 多副本,controller-manager 与 scheduler 正常选主
  • 状态存储:etcd 保持多数派,磁盘和网络必须稳定
  • 切换机制:健康检查、租约参数、恢复路径要可验证
  • 排障方法:先入口,再 apiserver,再 etcd,再控制器与插件

如果你现在正准备落地,建议按这个顺序推进:

  1. 先搭 3 控制平面 + 统一 controlPlaneEndpoint
  2. 再补上 LB/VIP 高可用
  3. 验证 单节点故障切换
  4. 建立 etcd 与 apiserver 监控
  5. 固化 故障演练与巡检脚本

最后给一句很实在的建议:
没有演练过的高可用,只能叫“看起来像高可用”。
真正上线前,务必亲手断一台、停一个、切一次,你对集群的信心会完全不一样。


分享到:

上一篇
《Java开发踩坑实录:8个高频并发问题的排查思路与修复方案》
下一篇
《前端开发中的模块联邦实战:在中型项目中落地微前端架构的拆分、共享与部署策略》