性能问题分析

性能问题分析

本节介绍 Kubernetes 中常见的性能问题及排查方法。

CPU 使用率过高

症状

# Pod CPU 使用率持续超过限制
kubectl top pods
NAME                CPU(cores)   MEMORY(bytes)
myapp-abc123        950m         256Mi

排查步骤

# 1. 查看 Pod 资源使用
kubectl top pod <pod-name>

# 2. 查看容器资源限制
kubectl get pod <pod-name> -o yaml | grep -A 10 resources

# 3. 查看节点 CPU 使用
kubectl top nodes

# 4. 进入容器查看进程
kubectl exec -it <pod-name> -- top

# 5. 查看 CPU throttling
kubectl describe pod <pod-name> | grep -A 5 "CPU"

性能分析工具

使用 perf 分析

# 在宿主机上分析容器进程
# 1. 找到容器进程 PID
docker inspect --format '{{.State.Pid}}' <container-id>

# 2. 使用 perf 分析
sudo perf top -p <pid>

# 3. 生成火焰图
sudo perf record -F 99 -p <pid> -g -- sleep 60
sudo perf script | ./flamegraph.pl > cpu-flamegraph.svg

应用内部分析

// Node.js - 使用 clinic.js
npm install -g clinic
clinic doctor -- node app.js

// 或使用 --prof 参数
node --prof app.js
node --prof-process isolate-*.log > processed.txt

常见原因及解决方案

原因 1:资源限制过低

# 检查资源配置
resources:
  requests:
    cpu: 100m      # 太低
    memory: 128Mi
  limits:
    cpu: 200m      # 太低
    memory: 256Mi

# 解决方案:调整资源限制
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1000m
    memory: 1Gi

原因 2:无效的死循环或阻塞

# 查看应用日志
kubectl logs <pod-name> --tail=100

# 使用 pprof 分析 Go 应用
kubectl port-forward <pod-name> 6060:6060
go tool pprof http://localhost:6060/debug/pprof/profile

# 使用 async-profiler 分析 Java 应用
kubectl exec -it <pod-name> -- jstack <pid>

原因 3:HPA 配置不当

# 检查 HPA
kubectl get hpa

# 调整 HPA 阈值
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70  # 从 50 调整到 70

内存问题

内存使用率过高

# 查看内存使用
kubectl top pod <pod-name>

# 查看内存限制
kubectl get pod <pod-name> -o yaml | grep -A 3 "memory"

内存泄漏检测

Node.js 应用

# 生成堆快照
kubectl exec -it <pod-name> -- node --inspect app.js

# 使用 Chrome DevTools 连接
chrome://inspect

# 或使用 heapdump
npm install heapdump
// 在代码中触发堆快照
const heapdump = require('heapdump');
heapdump.writeSnapshot('./heap-' + Date.now() + '.heapsnapshot');

Java 应用

# 生成堆转储
kubectl exec -it <pod-name> -- jmap -dump:format=b,file=/tmp/heap.hprof <pid>

# 复制出来分析
kubectl cp <pod-name>:/tmp/heap.hprof ./heap.hprof

# 使用 MAT 或 VisualVM 分析

Go 应用

# 使用 pprof
kubectl port-forward <pod-name> 6060:6060
go tool pprof http://localhost:6060/debug/pprof/heap

# 生成内存火焰图
curl http://localhost:6060/debug/pprof/heap > heap.out
go tool pprof -http=:8080 heap.out

OOMKilled 问题

# 查看 Pod 状态
kubectl get pods
NAME           READY   STATUS      RESTARTS
myapp-abc123   0/1     OOMKilled   3

# 查看详细信息
kubectl describe pod <pod-name>
# Last State: Terminated
#   Reason: OOMKilled
#   Exit Code: 137

# 查看容器日志(可能为空)
kubectl logs <pod-name> --previous

解决方案

# 1. 增加内存限制
resources:
  limits:
    memory: 2Gi  # 从 512Mi 增加

# 2. 优化应用内存使用
# - 减少缓存大小
# - 优化数据结构
# - 使用流式处理

# 3. 使用内存优化的容器镜像
# 使用 alpine 而不是 ubuntu
FROM node:18-alpine

磁盘问题

磁盘空间不足

# 查看节点磁盘使用
kubectl get nodes
kubectl describe node <node-name>

# SSH 到节点检查
df -h
du -sh /var/lib/docker/*
du -sh /var/lib/containerd/*

# 查看 Pod 磁盘使用
kubectl exec -it <pod-name> -- df -h

常见原因

  1. 容器日志过多
# 检查日志大小
sudo du -sh /var/log/containers/*
sudo du -sh /var/log/pods/*

# 清理日志
sudo truncate -s 0 /var/log/containers/*.log

# 配置日志轮转
# /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
  1. 未使用的镜像和容器
# 清理未使用的镜像
docker system prune -a

# 清理未使用的容器
docker container prune

# 清理未使用的卷
docker volume prune

# 在 Kubernetes 中配置垃圾回收
# kubelet 参数
--image-gc-high-threshold=85
--image-gc-low-threshold=80
  1. PV 空间不足
# 检查 PVC 使用情况
kubectl get pvc

# 扩容 PVC(如果 StorageClass 支持)
kubectl edit pvc <pvc-name>
# 修改 spec.resources.requests.storage

# 或创建新的更大的 PVC 并迁移数据

磁盘 I/O 性能问题

# 使用 iostat 查看 I/O
iostat -x 1

# 使用 iotop 查看进程 I/O
sudo iotop

# 测试磁盘性能
# 写入测试
dd if=/dev/zero of=/tmp/test bs=1M count=1024 conv=fdatasync

# 读取测试
dd if=/tmp/test of=/dev/null bs=1M

# 使用 fio 进行更详细的测试
fio --name=random-write --ioengine=libaio --rw=randwrite --bs=4k --size=1G --numjobs=1 --runtime=60 --time_based

网络性能问题

延迟过高

# 测试延迟
kubectl run test --rm -it --image=busybox -- sh
ping <service-ip>

# 使用 mtr 查看路径
mtr <service-ip>

# 检查 DNS 延迟
time nslookup kubernetes.default

带宽瓶颈

# 使用 iperf3 测试带宽
# 服务端
kubectl run iperf3-server --image=networkstatic/iperf3 -- -s

# 客户端
POD_IP=$(kubectl get pod iperf3-server -o jsonpath='{.status.podIP}')
kubectl run iperf3-client --rm -it --image=networkstatic/iperf3 -- -c $POD_IP

# 结果分析
# Transfer: 实际传输的数据量
# Bandwidth: 带宽(Mbits/sec 或 Gbits/sec)

Service 性能优化

# 使用 IPVS 而不是 iptables
# kube-proxy ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-proxy
  namespace: kube-system
data:
  config.conf: |
    mode: "ipvs"
    ipvs:
      scheduler: "rr"  # 轮询

节点性能问题

节点 NotReady

# 查看节点状态
kubectl get nodes

# 查看节点详情
kubectl describe node <node-name>

# 常见原因:
# 1. kubelet 未运行
sudo systemctl status kubelet
sudo journalctl -u kubelet -f

# 2. 网络插件问题
kubectl get pods -n kube-system

# 3. 资源耗尽
free -h
df -h

节点高负载

# 查看负载
uptime
# load average: 15.2, 12.3, 10.1

# 查看进程
top
htop

# 查看 I/O 等待
iostat -x 1

# 分析进程
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10

API Server 性能

API Server 响应慢

# 查看 API Server 指标
kubectl get --raw /metrics | grep apiserver_request_duration

# 查看 API Server 日志
kubectl logs -n kube-system kube-apiserver-<node>

# 常见原因:
# 1. etcd 性能问题
# 2. 请求量过大
# 3. 认证/授权延迟

etcd 性能优化

# 检查 etcd 性能
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 \
  check perf

# 查看 etcd 慢日志
journalctl -u etcd | grep "slow"

# 压缩历史版本
etcdctl compact <revision>

# 碎片整理
etcdctl defrag

性能监控最佳实践

关键指标

# Pod 级别
- CPU 使用率
- 内存使用率
- 网络 I/O
- 磁盘 I/O

# 节点级别
- CPU 负载
- 内存使用
- 磁盘使用
- 网络带宽

# 集群级别
- API Server 延迟
- etcd 延迟
- Scheduler 延迟

Prometheus 告警规则

groups:
- name: performance
  rules:
  - alert: HighCPUUsage
    expr: rate(container_cpu_usage_seconds_total[5m]) > 0.9
    for: 10m
    annotations:
      summary: "CPU 使用率持续过高"
  
  - alert: HighMemoryUsage
    expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.9
    for: 5m
    annotations:
      summary: "内存使用率过高"
  
  - alert: DiskSpaceLow
    expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
    for: 5m
    annotations:
      summary: "磁盘空间不足"

小结

本节介绍了性能问题分析:

CPU 问题:使用率过高、throttling、分析工具
内存问题:内存泄漏检测、OOMKilled
磁盘问题:空间不足、I/O 性能
网络性能:延迟、带宽、IPVS 优化
节点问题:NotReady、高负载
性能监控:关键指标、告警规则

下一节:实战案例和工具。