Kubernetes 官方设置最佳实践:单集群高可用与性能优化指南

在企业级 Kubernetes 集群的建设中,如何保障单集群的稳定性、高可用性以及在规模增长时的性能表现,是运维团队面临的重要课题。

本文基于 Kubernetes 官方文档 - 设置最佳实践(Setup Best Practices),对单集群的架构设计、多区容灾、大规模集群优化及证书管理等核心配置进行系统化总结。


一、 多可用区(Multiple Zones)部署最佳实践

为了防止因单个数据中心或可用区(AZ)故障导致整个集群不可用,官方推荐将单集群的节点跨多个可用区部署

1. 控制平面(Control Plane)的高可用设计

  • 奇数节点分布:控制平面组件(特别是 etcd)采用 Raft 一致性协议,通常推荐部署 3 个或 5 个控制节点,并将其均匀分布在不同的可用区。
  • 独立的故障域:确保 3 个 Master 节点分别位于不同的机架或可用区,避免单点物理故障。

2. 节点与 Pod 的拓扑分布约束

为了让业务 Pod 也能在多区之间均匀分布,从而实现高可用,推荐配置以下策略:

  • 使用 topologySpreadConstraints(拓扑分布约束)
    相比于简单的亲和性(Affinity),官方更推荐使用拓扑分布约束来控制 Pod 在可用区(topology.kubernetes.io/zone)或主机名(kubernetes.io/hostname)维度的均匀度。
    spec:
      topologySpreadConstraints:
        - maxSkew: 1                             # 允许的最大不均匀度
          topologyKey: topology.kubernetes.io/zone # 按可用区分布
          whenUnsatisfiable: DoNotSchedule        # 无法满足时拒绝调度
          labelSelector:
            matchLabels:
              app: my-web-app
    

3. 多区架构下的存储管理

  • 延迟绑定卷(Volume Binding Mode)
    在多区集群中,如果先创建存储卷再调度 Pod,可能会出现“卷在 A 区,而 Pod 被调度到 B 区”的冲突。
    最佳实践:在 StorageClass 中配置 volumeBindingMode: WaitForFirstConsumer。这会促使 K8s 在调度器确定 Pod 所在的可用区后,才在该区创建对应的存储卷。
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local-storage
    provisioner: kubernetes.io/no-provisioner
    volumeBindingMode: WaitForFirstConsumer # 延迟绑定
    

二、 大规模集群(Large Clusters)优化最佳实践

根据官方标准,单个 Kubernetes 集群支持的最大上限为:

  • 节点数:不超过 5000
  • 总 Pod 数:不超过 150,000
  • 每个节点的 Pod 数:不超过 110 个(默认)

当单集群规模扩大(如节点数超过 500 个)时,API Server 和 etcd 的负载会急剧上升。官方提出了以下优化建议:

1. 降低 API Server 的查询负载(使用 Informer)

  • 禁止频繁 Polling 查询:任何外部客户端、微服务或 Operator 都不应该使用频繁轮询(Get/List)的方式获取资源状态。
  • 推荐做法:使用 List-Watch 机制(如客户端 SDK 中的 Informer),在本地维护缓存,仅在资源发生变化时接收通知,从而减轻 API Server 的压力。

2. etcd 存储优化

  • 独立磁盘存储:etcd 对磁盘写入延迟(fsync)极其敏感。在生产环境中,必须将 etcd 的数据目录部署在独立的、高性能的 SSD 磁盘上。
  • 定期进行碎片整理(Compaction):etcd 默认会保留历史版本数据。应配置 --auto-compaction-retention 参数(如 5 分钟或 1 小时),自动清理历史版本,防止存储空间爆满。

3. 利用 NodeLease 减少节点状态更新

  • 在早期版本中,kubelet 会高频向 API Server 更新 Node Status。在大规模集群中这会产生大量的网络流量。
  • 最佳实践:启用并利用 NodeLease(节点租约)功能。kubelet 会转而向 API Server 发送轻量级的 Lease 对象来报告心跳,而仅在节点状态真正发生改变时才更新 Node 资源。

三、 PKI 证书与安全基础设施最佳实践

Kubernetes 的安全运行高度依赖其内部的公钥基础设施(PKI)。官方对证书的设置和管理有严格的推荐。

1. 减少安全边界(使用独立的 CA)

为了防止一个组件被攻破后导致整个集群沦陷,官方建议不要使用单一的 Root CA 签署所有证书,而是至少分离出以下几个独立的 CA:

  • Cluster CA:用于签署 API Server、kubelet、controller-manager 等核心组件的证书。
  • etcd CA:专门用于 etcd 成员之间以及 API Server 与 etcd 通信的证书。
  • Front Proxy CA:用于聚合层(Extension API Server)的客户端认证。

2. 启用 kubelet 证书自动轮转(Certificate Rotation)

  • 手动更新几百个节点的 kubelet 证书是不现实的。
  • 最佳实践:在 kubelet 配置中开启证书自动轮转。kubelet 会在自身证书即将过期时,通过 CSR(证书签名请求)API 自动向控制平面申请新证书。
    # kubelet-config.yaml
    rotateCertificates: true
    
    同时,在 kube-controller-manager 中启用 csrapproving 控制器以自动批准这些证书续签请求。

四、 节点资源保留(Node Resource Reservation)

为了防止节点上的业务 Pod 耗尽系统资源,导致 kubelet 或系统守护进程(如 sshdsystemd)因 OOM 被杀而引发节点失联,官方推荐进行合理的资源预留。

1. 资源分配公式

节点的物理总资源被划分为以下几个部分:
$$\text{Node Capacity} = \text{kube-reserved} + \text{system-reserved} + \text{eviction-threshold} + \text{Allocatable}$$

  • Allocatable(可分配资源):真正能分配给用户 Pod 的资源总量。

2. 最佳实践配置

在各工作节点的 kubelet 配置文件中,建议显式配置资源预留:

# kubelet-config.yaml 示例
kubeReserved:
  cpu: "100m"
  memory: "500Mi"
  ephemeral-storage: "1Gi"
systemReserved:
  cpu: "100m"
  memory: "500Mi"
  ephemeral-storage: "1Gi"
evictionHard:
  memory.available: "100Mi"
  nodefs.available: "10%"
  • kube-reserved:为 Kubernetes 系统组件(kubeletcontainerd)预留的资源。
  • system-reserved:为操作系统守护进程预留的资源。
  • evictionHard:触发主动驱逐 Pod 的硬阈值(例如可用内存低于 100Mi 时),防止系统死机。

五、 总结与最佳实践 CheckList

在落地单集群配置时,建议运维团队对照以下清单进行自检:

posted on 2026-05-30 11:58  LeeHang  阅读(52)  评论(0)    收藏  举报