优化Kubernetes集群性能的最佳实践

通过合理资源分配、自动扩缩容、高效网络、存储选择和持续可观测性来优化Kubernetes性能。

优化Kubernetes集群性能的最佳实践

Kubernetes集群性能问题通常表现为滚动更新缓慢、Pod挂起、资源争抢或意外的云账单。修复方案很少是单一的魔法设置;你需要准确的资源规格、匹配需求的扩缩容规则,以及足够的可观测性来发现压力源头。

使用这份清单来调整集群,无需猜测。

从请求和限制开始

调度器使用CPU和内存的requests来决定Pod的放置位置。如果请求值过低,节点看起来比实际更空闲,工作负载会争夺资源。如果请求值过高,调度器会浪费容量,Pod可能保持挂起状态。

根据实际使用数据设置请求值。例如,如果一个API容器在正常流量下使用约300毫核,在部署预热期间峰值接近700毫核,你可以从以下配置开始:

resources:
  requests:
    cpu: "300m"
    memory: "512Mi"
  limits:
    memory: "1Gi"

注意CPU限制。严格的CPU限制可能会限制延迟敏感的服务,即使节点有空闲CPU。内存限制仍然有用,因为超过内存限制的容器可能会被杀死,避免整个节点进入内存压力状态。

使用清晰的信号进行自动扩缩容

当你的指标跟踪用户需求时,水平Pod自动扩缩容效果良好。对于简单的无状态服务,CPU可能足够,但队列深度、请求速率或自定义应用指标通常是更好的扩缩容信号。

kubectl autoscale deployment api \
  --cpu-percent=70 \
  --min=3 \
  --max=20

集群自动扩缩容、Karpenter或云提供商的节点自动扩缩容层应有足够的空间在Pod长时间挂起前添加节点。检查节点组是否覆盖了工作负载所需的实例大小、区域、GPU要求或污点。

保持调度可预测

当关键Pod落在过载或不合适的节点上时,性能会下降。对高流量服务使用拓扑分布约束,对硬件特定工作负载使用节点亲和性,对只应运行特定类型Pod的节点使用污点。

topologySpreadConstraints:
- maxSkew: 1
  topologyKey: kubernetes.io/hostname
  whenUnsatisfiable: ScheduleAnyway
  labelSelector:
    matchLabels:
      app: api

这可以防止副本在集群有更好放置选项时堆积到一个节点上。

在真正有问题的环节调整网络

大多数集群不需要奇特的网络调整。从找到慢路径开始:DNS查找时间、服务网格开销、跨区域流量、过载的入口或Pod到数据库的延迟。

有用的检查包括:

kubectl top pods -A
kubectl get endpointslices -A
kubectl describe ingress <name>
kubectl logs -n kube-system -l k8s-app=kube-dns

对于通信频繁的服务,将Pod及其主要依赖项保持在同一个区域,如果可能的话,同一个可用区。如果你使用服务网格,在广泛部署网格更改之前,先测量一个工作负载在有无sidecar注入时的p95和p99延迟。

根据工作负载匹配存储

存储选择可能对数据库、队列和CI工作负载的性能起主导作用。根据延迟、IOPS、吞吐量和故障行为选择卷,而不仅仅是容量。

例如,PostgreSQL Pod需要具有可预测延迟和清晰备份行为的持久卷类。构建缓存可能更关心吞吐量,并且可以容忍重建。无状态Web服务应完全避免持久卷,除非有真正的原因。

注意这些症状:

  • Pod因卷挂载缓慢而卡在ContainerCreating状态。
  • 应用延迟上升而CPU保持正常。
  • 节点磁盘压力导致Pod被驱逐。
  • StatefulSet因卷绑定到单个区域而阻塞。

在更改前观察集群

没有基线指标的优化只是无意义的变动。至少跟踪CPU、内存、重启次数、挂起Pod、节点压力条件、API服务器延迟和工作负载p95延迟。

kubectl get nodes
kubectl describe node <node-name>
kubectl get pods -A --field-selector=status.phase=Pending
kubectl top nodes

如果你运行Prometheus,添加对持续节点压力、高重启率、HPA达到最大副本数以及关键Deployment上不可用副本的警报。

要点

从工作负载出发优化Kubernetes。合理设置请求值,避免不必要的CPU限制,根据需求信号进行扩缩容,保持副本分散,选择适合工作负载的存储。然后在每次更改后进行测量,以便知道集群是变得更快、更便宜,还是仅仅不同。