生产级集群搭建:kubeadm vs 二进制 vs 托管集群的选型与落地

一句话定位:三种搭建方式的成本、自由度、运维边界全对比,给团队一份能落地的选型表。

写在前面

"我们公司要上 K8s,用哪种方式搭?"这是我被问过最多的问题之一。问的人期待一个标准答案,但现实是:不同规模、不同团队、不同业务,答案完全不同。我见过 5 个人的创业团队硬上二进制部署,3 个运维天天救火;也见过金融客户因为合规要求,只能用自建 kubeadm,把托管集群直接否掉;还见过某互联网公司为了"省事"用托管集群,结果被厂商绑定,改云成本翻倍。

搭建方式的选择,本质是"运维成本、自由度、合规约束"三者的权衡。这三种方式没有绝对优劣,只有"是否匹配你的场景"。

这篇我会把 kubeadm、二进制、托管集群三种方式掰开:各自适合什么场景、生产实践的关键点(尤其是 kubeadm 的 HA 控制面和证书管理,这是新手最容易踩雷的地方)、托管集群的成本陷阱。最后给一份选型决策矩阵,你能直接拿去给团队做评估。

版本基线:K8s 1.30.4,kubeadm 1.30.4,Helm 3.14,操作系统 Ubuntu 22.04 LTS。

核心问题

  • kubeadm、二进制、托管集群,本质区别是什么?
  • kubeadm 搭生产集群,证书、etcd、HA 控制面怎么搞才稳?
  • 二进制部署在 2024 年还有意义吗?什么场景才值得?
  • 托管集群(ACK/EKS/TKE)省了什么、限制了什么?隐性成本在哪?
  • 怎么根据团队规模和业务诉求,做出可复用的选型决策?

一、原理剖析

1.1 三种方式的本质差异

先把三种方式的"本质"讲清楚,不然选型就是拍脑袋。

  • kubeadm:官方提供的集群引导工具。它把"初始化控制面、签发证书、配置 kubelet、加入节点"这套流程标准化,但不负责基础设施(机器、网络、LB)。本质是"半自动引导工具 + 一份配置"。
  • 二进制部署:手工下载 apiserver/scheduler/controller-manager/kubelet/kube-proxy 二进制,用 systemd 跑起来,自己配证书、自己写 etcd 集群。本质是"手工搭一个 K8s",你能看到每个螺丝。
  • 托管集群:云厂商(阿里云 ACK、AWS EKS、腾讯云 TKE)提供控制面,你只管工作节点。控制面的可用性、升级、监控由厂商负责。本质是"控制面 as a Service"。
┌──────────────┬──────────────────┬──────────────────┬──────────────────┐
│              │     kubeadm      │      二进制      │     托管集群     │
├──────────────┼──────────────────┼──────────────────┼──────────────────┤
│ 控制面部署   │ 工具自动引导     │ 手工 systemd     │ 厂商托管         │
│ etcd         │ 可内置/外置      │ 手工搭           │ 厂商托管(隐藏) │
│ 证书管理     │ kubeadm 自动签发 │ 全手工           │ 厂商托管         │
│ 升级         │ kubeadm upgrade  │ 手工替换二进制   │ 厂商一键(有限) │
│ 自由度       │ 中(标准路径)   │ 极高             │ 低(厂商限制)   │
│ 运维成本     │ 中               │ 极高             │ 低               │
│ 故障排查     │ 可查所有组件     │ 可查所有组件     │ 控制面黑盒       │
│ 离线/私有云  │ 支持             │ 支持             │ 不支持(多数)   │
│ 起步门槛     │ 中               │ 极高             │ 低               │
└──────────────┴──────────────────┴──────────────────┴──────────────────┘

1.2 控制面高可用:为什么是核心难点

三种方式都要解决一个问题:控制面高可用。这是生产集群和测试集群最大的分水岭。

控制面高可用的核心是 apiserver 的多实例 + 前置 LB。etcd 也要多实例(推荐 3 或 5 节点,奇数防脑裂)。看下图:

端到端 Raft

端到端 Raft

端到端 Raft

外部 LB
VIP: 10.0.0.100
keepalived/Haproxy

apiserver-1
10.0.0.10:6443

apiserver-2
10.0.0.11:6443

apiserver-3
10.0.0.12:6443

etcd-1
10.0.0.10:2379

etcd-2
10.0.0.11:2379

etcd-3
10.0.0.12:2379

scheduler-1
leader election

scheduler-2
standby

controller-mgr-1
leader election

controller-mgr-2
standby

关键认知:

  • apiserver 无状态,可直接水平扩展,前面挂 LB。
  • etcd 是 Raft 一致性协议,多节点之间需要端到端通信,不能简单 LB。每个 apiserver 连自己的本地 etcd 性能最好。
  • scheduler 和 controller-manager 通过 leader election 选主,多副本只有一个干活,其他 standby。这就是为什么 kubeadm 默认参数带 --leader-elect=true

kubelet 和 kube-proxy 连 apiserver 用的是 kubeconfig 里的 server 地址。生产环境这个地址必须是 LB 的 VIP,否则 apiserver 故障切换就没意义。这是 kubeadm HA 部署的核心:--control-plane-endpoint 指向 LB。

1.3 证书体系:K8s 的信任链

证书管理是生产集群的另一大坑。K8s 控制面有一堆证书,搞不清楚就升级就出事。

CA(pki/ca.crt / ca.key)──┬─ apiserver serving cert
                         ├─ apiserver-kubelet-client cert
                         ├─ front-proxy-ca ─── front-proxy-client
                         ├─ etcd CA(pki/etcd/ca.crt)
                         │   ├─ etcd server cert
                         │   ├─ etcd peer cert
                         │   └─ etcd healthcheck-client
                         ├─ apiserver-etcd-client cert
                         └─ sa.key / sa.pub(签名 ServiceAccount Token)

记住几点:

  • CA 有效期 10 年,但签发的组件证书默认只有 1 年。1 年到期不续,集群就挂。kubeadm 1.20+ 支持自动续期(kubelet 触发),但控制面静态 Pod 的证书需要 kubeadm 主动续。
  • 升级前必查证书有效期:kubeadm certs check-expiration
  • 续期命令:kubeadm certs renew all。续完必须重启控制面静态 Pod(apiserver/scheduler/controller-manager),否则用的还是老证书。
  • 生产环境强烈建议把根 CA 离线备份,CA 丢了整个集群的信任链就断了。

二、实战操作

2.1 环境准备(3 控制面 + 3 工作节点)

这次我们搭一个真正的 HA 集群:3 台 master + 3 台 worker + 外部 LB。

角色主机名IP配置
LBlb-0110.0.0.1002C4G
masterk8s-master-110.0.0.114C8G + 100G SSD(etcd)
masterk8s-master-210.0.0.124C8G + 100G SSD
masterk8s-master-310.0.0.134C8G + 100G SSD
workerk8s-worker-110.0.0.218C16G
workerk8s-worker-210.0.0.228C16G
workerk8s-worker-310.0.0.238C16G

VIP 用 keepalived 漂在 LB 上:10.0.0.100:6443

2.2 搭建 HA 负载均衡(keepalived + haproxy)

apiserver 前置 LB,生产推荐 keepalived + haproxy(也可以用云厂商 SLB,更省心)。在两台 LB 机器上:

# 两台 LB 都执行
sudo apt-get install -y keepalived haproxy

# 配置 haproxy(两台配置一样)
sudo cat > /etc/haproxy/haproxy.cfg <<'EOF'
global
    log /dev/log local0
    maxconn 4096

defaults
    log global
    mode tcp
    option tcplog
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend k8s-api
    bind *:6443
    mode tcp
    default_backend k8s-api

backend k8s-api
    mode tcp
    option tcp-check
    balance roundrobin
    server k8s-master-1 10.0.0.11:6443 check inter 5s fall 3 rise 2
    server k8s-master-2 10.0.0.12:6443 check inter 5s fall 3 rise 2
    server k8s-master-3 10.0.0.13:6443 check inter 5s fall 3 rise 2
EOF

# 主 LB 配置 keepalived
sudo cat > /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
    router_id K8S_LB
}
vrrp_script check_haproxy {
    script "pidof haproxy"
    interval 2
    weight -20
}
vrrp_instance VI_1 {
    state MASTER              # 备机写 BACKUP
    interface eth0
    virtual_router_id 51
    priority 100              # 备机写 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass K8sHaPwd2024
    }
    virtual_ipaddress {
        10.0.0.100/24
    }
    track_script {
        check_haproxy
    }
}
EOF

sudo systemctl enable --now haproxy keepalived
# 验证 VIP
ip addr show eth0 | grep 10.0.0.100

2.3 kubeadm 初始化第一个控制面

所有节点先做基础准备(参考上一篇的环境准备步骤):关 swap、装 containerd、装 kubeadm/kubelet/kubectl。然后开始初始化。

# 在 k8s-master-1 上执行
# 1. 预下载镜像(避免 init 时拉镜像慢)
sudo kubeadm config images pull \
  --image-repository=registry.k8s.io \
  --kubernetes-version=v1.30.4

# 2. 生成初始化配置
cat > kubeadm-init.yaml <<'EOF'
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: "abcdef.0123456789abcdef"
  ttl: "24h"
  usages:
  - signing
  - authentication
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
  name: k8s-master-1
  taints: []
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.30.4
imageRepository: registry.k8s.io
controlPlaneEndpoint: "10.0.0.100:6443"
apiServer:
  certSANs:
  - "10.0.0.100"
  - "k8s-api.example.com"
  - "127.0.0.1"
  extraArgs:
    audit-log-path: "/var/log/kubernetes/audit/audit.log"
    audit-log-maxage: "30"
    audit-log-maxbackup: "10"
    audit-log-maxsize: "100"
    feature-gates: "DynamicResourceAllocation=true"
  extraVolumes:
  - name: "audit"
    hostPath: "/var/log/kubernetes/audit"
    mountPath: "/var/log/kubernetes/audit"
    readOnly: false
    pathType: DirectoryOrCreate
controllerManager:
  extraArgs:
    "cluster-signing-duration": "87600h"
    "horizontal-pod-autoscaler-sync-period": "15s"
    "node-monitor-grace-period": "40s"
scheduler:
  extraArgs:
    "profile": "kubernetes.io/v1.30"
etcd:
  local:
    dataDir: "/var/lib/etcd"
    extraArgs:
      "auto-compaction-mode": "periodic"
      "auto-compaction-retention": "5h"
      "quota-backend-bytes": "8589934592"
      "heartbeat-interval": "500"
      "election-timeout": "5000"
networking:
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/12"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
maxPods: 110
kubeReserved:
  cpu: "500m"
  memory: "1Gi"
  ephemeral-storage: "1Gi"
systemReserved:
  cpu: "500m"
  memory: "1Gi"
evictionHard:
  memory.available: "500Mi"
  nodefs.available: "10%"
  imagefs.available: "10%"
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
EOF

# 3. 创建审计目录
sudo mkdir -p /var/log/kubernetes/audit

# 4. 初始化(注意 --upload-certs 让其他 master 加入时自动同步证书)
sudo kubeadm init --config=kubeadm-init.yaml --upload-certs | tee kubeadm-init.log

# 输出里会有两条关键命令:
# (a) 加入新控制面节点
# (b) 加入工作节点
# 一定要保存好 kubeadm-init.log

# 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

2.4 加入其余控制面和工作节点

# 在 k8s-master-2 / k8s-master-3 上执行(从 init 日志拿命令,形如:)
sudo kubeadm join 10.0.0.100:6443 \
  --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --control-plane \
  --certificate-key <certificate-key>

# 在 k8s-worker-1/2/3 上执行
sudo kubeadm join 10.0.0.100:6443 \
  --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:<hash>

注意 --control-plane 标志:加 master 用,会拉起控制面静态 Pod;加 worker 不用。--certificate-key 是 init 时 --upload-certs 生成的,有效期 2 小时,过期可以 kubeadm init phase upload-certs --upload-certs 重新生成。

2.5 安装 CNI 和验证

# 装 Calico(下一篇文章会详细讲 CNI 选型)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml

# 验证所有节点 Ready
kubectl get nodes -o wide
# NAME            STATUS   ROLES           AGE   VERSION
# k8s-master-1    Ready    control-plane   10m   v1.30.4
# k8s-master-2    Ready    control-plane   8m    v1.30.4
# k8s-master-3    Ready    control-plane   8m    v1.30.4
# k8s-worker-1    Ready    <none>          6m    v1.30.4
# k8s-worker-2    Ready    <none>          6m    v1.30.4
# k8s-worker-3    Ready    <none>          6m    v1.30.4

# 验证所有 Pod Running
kubectl get pods -A
# 验证 etcd 集群成员
sudo ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
  --key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
  member list -w table

2.6 证书管理与续期

生产必须掌握的运维动作:

# 1. 检查证书有效期(日常巡检必备)
sudo kubeadm certs check-expiration

# 2. 续期所有证书(到期前 30 天做)
sudo kubeadm certs renew all

# 3. 续期后必须重启静态 Pod(否则不生效)
# kubeadm 1.30 可以这样重启:
sudo mkdir -p /etc/kubernetes/manifests-backup
sudo mv /etc/kubernetes/manifests/*.yaml /etc/kubernetes/manifests-backup/
# 等 30 秒让 kubelet 把 Pod 停掉
sleep 30
sudo mv /etc/kubernetes/manifests-backup/*.yaml /etc/kubernetes/manifests/
# 验证
kubectl -n kube-system get pods | grep -E 'apiserver|controller|scheduler'

# 4. 更新 kubelet 用的 admin.conf(本地 kubectl 配置)
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 5. 备份 CA(每季度做一次,放离线介质)
sudo tar -czvf k8s-ca-backup-$(date +%Y%m%d).tar.gz /etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/ca.key /etc/kubernetes/pki/sa.key /etc/kubernetes/pki/sa.pub /etc/kubernetes/pki/etcd/ca.crt /etc/kubernetes/pki/etcd/ca.key
# 把 tar 包存到离线介质,CA 是集群信任链的根,丢了等于集群报废

2.7 集群升级流程(1.30.4 → 1.31.x)

升级是生产最容易出事的操作,流程必须严格:

# 1. 先升级 kubeadm(所有 master)
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.31.x-1.1
sudo apt-mark hold kubeadm

# 2. 验证 kubeadm 版本
kubeadm version

# 3. 升级第一个 master 的控制面
sudo kubeadm upgrade apply v1.31.x

# 4. 升级其他 master(注意是 upgrade node,不是 apply)
sudo kubeadm upgrade node

# 5. 腾空节点(逐个 master 操作)
kubectl cordon k8s-master-1
kubectl drain k8s-master-1 --ignore-daemonsets --delete-emptydir-data

# 6. 升级 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.31.x-1.1 kubectl=1.31.x-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# 7. 恢复调度
kubectl uncordon k8s-master-1

# 8. 同样流程升级 worker 节点(kubeadm upgrade node + 升级 kubelet)
# 9. 升级 CNI(很多事故是升级 K8s 忘了升级 CNI 导致的)
# 10. 验证:kubectl get nodes 看 kubelet 版本

经验:升级务必先在测试集群走一遍完整流程,记录每步耗时和坑。生产升级分批,一个节点升完观察 30 分钟再升下一个。永远不要在生产直接跳两个 minor 版本(虽然官方允许,但 CNI/CSI 兼容性容易翻车)。

三、踩坑与排查

坑 1:kubeadm init 失败,报 [ERROR Swap]: running with swap on is not supported

现象:kubeadm init 直接报错退出。

原因:K8s 1.30 仍然不支持 swap(实验性支持需手动开)。新装的 Ubuntu 默认开了 swap 分区。

解决:

sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
# 重启验证
free -h
# Swap 行必须全是 0

坑 2:join 失败,报 token invaliddiscovery-token-ca-cert-hash 不匹配

现象:worker 节点 join 时报 token 失效或 hash 对不上。

原因:kubeadm init 时生成的 token 默认 24 小时过期;CA cert hash 是基于 CA 证书算的,如果重装过集群 hash 会变。

解决:

# 在 master 上重新生成 token
sudo kubeadm token create --print-join-command
# 这条命令直接打印可用的完整 join 命令

# 如果还想要 control-plane 的 certificate-key
sudo kubeadm init phase upload-certs --upload-certs
# 输出的 key 用在 --certificate-key 参数

坑 3:HA 集群 LB 切换后,kubelet 连不上 apiserver

现象:LB 主备切换后,部分节点 kubelet 报 connection refused,Pod 状态异常。

原因:kubelet 连 apiserver 用的是 kubeconfig 里的 server 地址(VIP)。如果 keepalived 切换 VIP 慢(>10s),kubelet 短期内连不上,影响 Pod 状态上报和心跳。

排查与解决:

# 1. 看 kubelet 日志
sudo journalctl -u kubelet --since "5 min ago" | grep -i "apiserver"

# 2. 测 VIP 连通性
nc -zv 10.0.0.100 6443

# 3. 优化 keepalived 切换速度
# vrrp_script interval 调小到 1s,fallback 检查脚本要快
# 不要用复杂脚本,简单的 pidof/ping 即可

# 4. 给 kubelet 加重试参数(/var/lib/kubelet/kubeadm-flags.env)
KUBELET_KUBEADM_ARGS="--resolv-conf=/run/systemd/resolve/resolv.conf --kubeconfig=/var/lib/kubelet/kubeconfig --config=/var/lib/kubelet/config.yaml --v=2"

根治:云上用云厂商 SLB(自带健康检查 + 私网 VIP),比自建 keepalived 稳得多。

坑 4:etcd 集群磁盘满,整个集群不可写

现象:apiserver 报 etcdserver: mvcc: database space exceeded,所有写操作失败。

原因:etcd 默认配额 2GB(我们的配置里改成 8GB),超过会进入只读模式。常见于大量 watch 事件、CRD 滥用、没有压缩。

解决:

# 1. 紧急压缩(在任一 etcd 节点)
export ETCDCTL_API=3
etcdctl --endpoints=https://10.0.0.11:2379,https://10.0.0.12:2379,https://10.0.0.13:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key \
  compact $(etcdctl ... endpoint status -w json | jq '.[].Status.header.revision')

# 2. 撤销告警
etcdctl ... alarm disarm

# 3. 碎片整理(每个节点单独做,逐个做避免同时不可用)
etcdctl ... --endpoints=https://10.0.0.11:2379 defrag
# 等 30s 再做下一个节点
etcdctl ... --endpoints=https://10.0.0.12:2379 defrag

# 4. 长期:开启 auto-compaction(已在配置里加)
# auto-compaction-mode=periodic, auto-compaction-retention=5h

坑 5:托管集群"看似便宜",账单爆炸

现象:某团队用 ACK Pro 托管集群,起步 3 个 worker,月账单 2000 元。业务起来后扩到 20 个 worker,账单变 1.5 万,其中托管控制面费 + 工作节点 + 流量费 + 监控费,远超预算。

原因:托管集群的隐性成本:

  • 控制面管理费:按集群收(ACK Pro ~240 元/月,EKS $0.10/小时)。
  • 工作节点:云主机费,比自建贵(包了镜像、运行时)。
  • 流量费:跨可用区、公网流量,生产很容易爆。
  • 托管组件费:云监控、日志服务、安全扫描,默认开,按量收费。
  • 快照/备份费:云盘快照按容量收。

解决:选型阶段就把 TCO(总拥有成本)算清楚,不要只看控制面费。具体对比见下一节。

四、最佳实践与选型决策矩阵

4.1 托管集群选型决策表

维度阿里云 ACKAWS EKS腾讯云 TKE自建 kubeadm
控制面费用Pro 0.84 元/时$0.10/时0.64 元/时0(自担机器)
起步门槛极低,5 分钟出集群极低中,需 K8s 经验
私有云/离线标准版可私有部署不支持可私有部署完全支持
控制面可观测有限(Pro 给指标)有限有限完全可观测
升级自由度厂商节奏厂商节奏厂商节奏完全自主
CNI 选择Terway/Flannel/CalicoVPC CNI/Calico/CiliumTKE CNI/Calico任意
厂商绑定中(StorageClass/Ingress)高(VPC CNI)
适合规模中小到大型大型中小到大型任意
合规/金融场景可(专有版)一般

4.2 选型决策矩阵

按这个顺序问自己:

  1. 是否在公有云? 否 → 自建(kubeadm 或二进制)。是 → 看 2。
  2. 是否需要私有云/离线? 是 → 自建。否 → 看 3。
  3. 团队 K8s 运维能力? 弱(无专职 SRE) → 托管。中 → 托管或 kubeadm。强 → 看 4。
  4. 集群规模 > 100 节点? 是 → 托管(控制面免运维)或 kubeadm HA。否 → 看 5。
  5. 特殊定制需求(如自研调度器、特殊网络)? 是 → 二进制或 kubeadm。否 → 托管。

具体场景对照:

  • 创业团队/小公司(<50 节点):公有云托管集群。控制面省心,把人力投到业务。
  • 中型公司(50-500 节点):托管 + 自建混合。核心生产托管,测试/特殊业务自建。
  • 大型公司(>500 节点):多区域 kubeadm HA + 自研运维平台。规模大到托管费不划算。
  • 金融/政企(合规优先):私有云 kubeadm HA,严格控制组件版本和审计。
  • 特殊场景(自研调度器/网络):二进制部署,深度定制。

4.3 二进制部署什么时候还值得

老实说,2024 年 99% 的场景不需要二进制。但有几种情况它仍有价值:

  • 学习/教学:想彻底搞懂每个组件怎么跑,二进制是最佳路径。
  • 深度定制:比如自研 scheduler 插件需要特定编译参数,或要改 kubelet 源码。
  • 极端精简:嵌入式/IoT 场景,只要 kubelet + apiserver,不要 controller-manager。
  • 历史包袱:已有二进制集群,迁移成本高于维护成本。

否则,kubeadm 是更优选择——它本质上也是把二进制部署流程标准化了,该看到的日志、该调的参数都能调,还省了证书管理的心。

4.4 生产集群通用清单

不论用哪种方式,生产集群都要满足:

  • 控制面 ≥ 3 副本,apiserver 前置 LB
  • etcd ≥ 3 节点,独立 SSD,定期 defrag
  • 证书自动续期或监控告警(< 30 天告警)
  • etcd 定期备份(至少每天一次,跨地域存)
  • 控制面组件全部监控,Prometheus + Grafana
  • 升级有完整 SOP,先测试再生产,分批
  • 节点开机自动加入集群(或自动伸缩)
  • 网络插件明确选型,CNI/NetworkPolicy 策略清晰
  • 日志收集(apiserver audit + kubelet + 业务日志)
  • 故障演练:定期 kill apiserver/etcd,验证 HA 有效性

五、小结

三种搭建方式没有银弹:kubeadm 是"标准化半自动",适合大多数自建场景;二进制是"完全手工",只在深度定制或学习场景有价值;托管集群是"控制面 as a Service",适合人力紧张、不想自担控制面风险的团队。

kubeadm HA 的核心是三个东西:控制面 endpoint 指向 LB、etcd 多节点 + 独立 SSD、证书体系持续运维。这三个搞稳了,集群的基础就稳了。

证书管理是新手最容易忽视、生产最容易翻车的点。务必建立巡检机制:kubeadm certs check-expiration 每月跑一次,< 30 天告警,续期后重启静态 Pod。CA 离线备份是最后一道保险。

托管集群的隐性成本必须算清:控制面费只是冰山一角,流量费、监控费、托管组件费才是大头。选型时算 TCO,不要只看单价。被厂商绑定后迁移成本极高,核心业务建议保留自建能力。

思考题

  1. 你的团队当前规模(节点数、SRE 人数、业务合规要求),应该选哪种搭建方式?列出你的决策依据。
  2. 如果今天让你为一家 200 人、50 节点的中型公司设计 K8s 落地方案,你会推荐托管还是自建?多集群策略怎么设计?

延伸阅读

  • kubeadm 官方文档:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/
  • 高可用拓扑选择:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/
  • 证书管理:https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/
  • ACK 产品文档:https://help.aliyun.com/product/85222.html
  • EKS 用户指南:https://docs.aws.amazon.com/eks/

更多推荐