HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 运维手册

    • Kubernetes 全栈实战与性能原理教程
    • 第一部分:Linux 基础与系统原理
    • 第二部分:Kubernetes 网络深度解析
    • 第三部分:Kubernetes 存储管理实战
    • 第四部分:Kubernetes 调度器深度解析
    • 第五部分:Kubernetes 性能调优实战
    • 第六部分:CNI 与 eBPF 网络深度实践
    • 第七部分:Kubernetes 生产级调优案例
    • 第八部分:命令速查与YAML模板库
    • 第九部分:实验环境快速搭建指南
    • 第十部分:面试题库与进阶路径
    • 第11章:Kubernetes 网络·存储·大文件排查专项手册

第七部分:Kubernetes 生产级调优案例

真实场景下的系统化调优实践

目录

  • 案例1:高并发 API 集群调优
  • 案例2:AI 推理服务优化
  • 案例3:数据库集群高可用
  • 案例4:混合负载调度优化
  • 总结与最佳实践

案例1:高并发 API 集群调优

场景描述

业务背景:

  • 电商平台 API 服务
  • 日常流量:5k QPS
  • 峰值流量:15k QPS(促销活动)
  • 服务:Go 语言编写,响应时间要求 < 100ms

初始问题:

  • 高峰期 P99 延迟达到 500ms
  • CPU 使用率波动大
  • 部分请求超时
  • 内存使用持续增长

调优过程

第1步:性能瓶颈定位

#!/bin/bash
# 性能瓶颈定位脚本

echo "=== 性能瓶颈定位 ==="

# 1. 查看 Pod 资源使用
kubectl top pod -l app=api-service
kubectl describe pod -l app=api-service

# 2. 查看节点资源使用
kubectl top node

# 3. 查看应用日志
kubectl logs -l app=api-service --tail=100

# 4. 查看 Prometheus 指标
kubectl port-forward -n monitoring svc/prometheus 9090:9090 &
echo "查看指标: http://localhost:9090"

发现问题:

  • CPU throttling 严重(throttled_time 占比 40%)
  • 内存缓慢泄漏(每小时增长 100MB)
  • 部分 Pod 负载不均

第2步:CPU 调优

原始配置:

resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1000m
    memory: 1Gi

调优后配置:

resources:
  requests:
    cpu: 1000m
    memory: 512Mi
  # 移除 CPU limits,避免 throttling

测试脚本:

#!/bin/bash
# CPU 调优效果测试

# 部署优化后的配置
kubectl apply -f api-service-optimized.yaml

# 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=api-service --timeout=60s

# 压力测试
wrk -t12 -c400 -d60s --latency http://api-service/api/products

# 监控 CPU 使用
kubectl top pod -l app=api-service

效果:

  • P99 延迟:500ms → 120ms
  • CPU throttling:40% → 0%

第3步:内存泄漏修复

#!/bin/bash
# 内存泄漏分析

# 1. 启用 pprof
kubectl port-forward -n default svc/api-service 6060:6060 &

# 2. 收集内存 profile
curl http://localhost:6060/debug/pprof/heap > heap.prof

# 3. 分析内存使用
go tool pprof -http=:8080 heap.prof

# 4. 生成火焰图
go tool pprof -png heap.prof > memory-flamegraph.png

发现问题:

  • HTTP 连接池未正确关闭
  • 缓存未设置过期时间

修复代码:

// 修复前
client := &http.Client{}

// 修复后
client := &http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 10,
        IdleConnTimeout:     90 * time.Second,
    },
    Timeout: 10 * time.Second,
}

// 缓存添加过期时间
cache := cache.New(5*time.Minute, 10*time.Minute)

效果:

  • 内存增长率:100MB/h → 稳定在 512MB

第4步:负载均衡优化

# 启用 Pod 反亲和
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
spec:
  replicas: 12
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - api-service
              topologyKey: kubernetes.io/hostname

效果:

  • Pod 分布更均匀
  • 节点负载更平衡

最终结果

指标优化前优化后提升
P99 延迟500ms80ms84% ↓
P50 延迟100ms30ms70% ↓
QPS 承载5k20k300% ↑
CPU 使用率85% (throttling)65% (稳定)-
内存使用不稳定稳定-
成本基准+20%性价比提升

案例2:AI 推理服务优化

场景描述

业务背景:

  • 图像识别推理服务
  • 模型:ResNet-50
  • 输入:批量图片(batch size: 32)
  • GPU:NVIDIA T4

初始问题:

  • GPU 利用率仅 40%
  • 推理吞吐量:200 images/s(预期:800+ images/s)
  • 模型加载时间长(30s)

调优过程

第1步:GPU 调度配置

apiVersion: v1
kind: Pod
metadata:
  name: ai-inference
spec:
  containers:
  - name: inference
    image: pytorch/pytorch:1.13.0-cuda11.6-cudnn8-runtime
    resources:
      limits:
        nvidia.com/gpu: 1
      requests:
        cpu: 4
        memory: 8Gi
    volumeMounts:
    - name: model-storage
      mountPath: /models
  volumes:
  - name: model-storage
    persistentVolumeClaim:
      claimName: model-pvc
  nodeSelector:
    accelerator: nvidia-t4

第2步:模型加载优化

问题:每次 Pod 重启都需要重新下载模型

解决方案:使用 PVC 缓存模型

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: model-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 50Gi

模型预加载脚本:

#!/usr/bin/env python3
import torch
import torchvision
import os

MODEL_PATH = "/models/resnet50.pth"

def preload_model():
    if os.path.exists(MODEL_PATH):
        print(f"Loading model from cache: {MODEL_PATH}")
        model = torch.load(MODEL_PATH)
    else:
        print("Downloading model...")
        model = torchvision.models.resnet50(pretrained=True)
        torch.save(model, MODEL_PATH)
        print(f"Model cached at: {MODEL_PATH}")
    
    model.eval()
    model.cuda()
    return model

if __name__ == "__main__":
    model = preload_model()
    print("Model ready for inference")

效果:

  • 模型加载时间:30s → 2s

第3步:批处理优化

#!/usr/bin/env python3
import torch
from torch.utils.data import DataLoader
import time

class InferenceBatchProcessor:
    def __init__(self, model, batch_size=32):
        self.model = model
        self.batch_size = batch_size
        self.device = torch.device("cuda")
    
    def process_batch(self, images):
        # 确保输入在 GPU 上
        images = images.to(self.device, non_blocking=True)
        
        # 使用 torch.no_grad() 节省内存
        with torch.no_grad():
            outputs = self.model(images)
        
        return outputs.cpu()
    
    def benchmark(self, num_batches=100):
        dummy_input = torch.randn(
            self.batch_size, 3, 224, 224
        ).to(self.device)
        
        # 预热
        for _ in range(10):
            self.process_batch(dummy_input)
        
        torch.cuda.synchronize()
        start = time.time()
        
        for _ in range(num_batches):
            self.process_batch(dummy_input)
        
        torch.cuda.synchronize()
        end = time.time()
        
        total_images = num_batches * self.batch_size
        throughput = total_images / (end - start)
        
        print(f"Throughput: {throughput:.2f} images/s")
        print(f"Latency: {(end - start) / num_batches * 1000:.2f} ms/batch")
        
        return throughput

# 使用示例
model = preload_model()
processor = InferenceBatchProcessor(model, batch_size=32)
processor.benchmark()

第4步:混合精度推理

#!/usr/bin/env python3
import torch

# 启用混合精度
model = model.half()  # FP16

# 或使用 TorchScript 优化
model_scripted = torch.jit.script(model)
model_scripted.save("model_scripted.pt")

效果:

  • 推理速度提升:200 images/s → 850 images/s
  • GPU 利用率:40% → 85%
  • 内存使用:8GB → 4GB

最终结果

指标优化前优化后提升
吞吐量200 img/s850 img/s325% ↑
延迟160ms38ms76% ↓
GPU 利用率40%85%113% ↑
模型加载30s2s93% ↓
内存使用8GB4GB50% ↓

案例3:数据库集群高可用

场景描述

业务背景:

  • MySQL 主从集群
  • 数据量:500GB
  • 读写比:7:3
  • 要求:RPO < 1分钟,RTO < 5分钟

初始问题:

  • 主库故障后手动切换,RTO > 30分钟
  • 从库延迟时有发生
  • 备份恢复测试不完善

调优过程

第1步:StatefulSet 部署

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
        - name: config
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 2
            memory: 4Gi
          limits:
            cpu: 4
            memory: 8Gi
      volumes:
      - name: config
        configMap:
          name: mysql-config
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 100Gi

第2步:主从复制配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  master.cnf: |
    [mysqld]
    server-id=1
    log-bin=mysql-bin
    binlog_format=ROW
    gtid_mode=ON
    enforce_gtid_consistency=ON
    max_connections=1000
    innodb_buffer_pool_size=4G
    innodb_flush_log_at_trx_commit=2
    sync_binlog=1
  
  slave.cnf: |
    [mysqld]
    server-id=2
    relay-log=relay-bin
    read_only=ON
    gtid_mode=ON
    enforce_gtid_consistency=ON
    max_connections=1000
    innodb_buffer_pool_size=4G

第3步:自动故障切换

使用 MySQL Operator 实现自动故障切换:

#!/bin/bash
# 安装 MySQL Operator

# 1. 添加 Helm 仓库
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update

# 2. 安装 Operator
helm install mysql-operator mysql-operator/mysql-operator \
  --namespace mysql-operator \
  --create-namespace

# 3. 部署 MySQL 集群
kubectl apply -f - <<EOF
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
  name: mysql-cluster
spec:
  secretName: mysql-secret
  tlsUseSelfSigned: true
  instances: 3
  router:
    instances: 2
  datadirVolumeClaimTemplate:
    accessModes:
      - ReadWriteOnce
    storageClassName: fast-ssd
    resources:
      requests:
        storage: 100Gi
  podSpec:
    resources:
      requests:
        cpu: 2
        memory: 4Gi
      limits:
        cpu: 4
        memory: 8Gi
EOF

第4步:备份恢复方案

#!/bin/bash
# MySQL 自动备份脚本

# 1. 创建备份 CronJob
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: CronJob
metadata:
  name: mysql-backup
spec:
  schedule: "0 2 * * *"  # 每天凌晨2点
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: mysql:8.0
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            command:
            - /bin/sh
            - -c
            - |
              mysqldump -h mysql-0.mysql \
                -u root -p\$MYSQL_ROOT_PASSWORD \
                --all-databases --single-transaction \
                --master-data=2 --flush-logs \
                | gzip > /backup/mysql-\$(date +%Y%m%d-%H%M%S).sql.gz
            volumeMounts:
            - name: backup
              mountPath: /backup
          volumes:
          - name: backup
            persistentVolumeClaim:
              claimName: mysql-backup-pvc
          restartPolicy: OnFailure
EOF

# 2. 创建备份存储
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-backup-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 500Gi
EOF

第5步:性能优化

-- MySQL 性能优化配置

-- 1. 调整缓冲池大小
SET GLOBAL innodb_buffer_pool_size = 4294967296;  -- 4GB

-- 2. 优化查询缓存
SET GLOBAL query_cache_size = 67108864;  -- 64MB
SET GLOBAL query_cache_type = 1;

-- 3. 调整连接数
SET GLOBAL max_connections = 1000;

-- 4. 优化慢查询日志
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
SET GLOBAL log_queries_not_using_indexes = 1;

-- 5. 创建必要的索引
ANALYZE TABLE orders;
OPTIMIZE TABLE products;

最终结果

指标优化前优化后提升
RTO30分钟3分钟90% ↓
RPO5分钟30秒90% ↓
查询性能基准+40%-
故障切换手动自动-
备份频率每周每天-

案例4:混合负载调度优化

场景描述

业务背景:

  • 集群同时运行:
    • Web 服务(CPU 密集)
    • 数据处理任务(I/O 密集)
    • 机器学习训练(GPU 密集)
    • 批处理作业(内存密集)

初始问题:

  • 资源利用率不均
  • 批处理作业影响在线服务
  • GPU 资源浪费

调优过程

第1步:节点分类

#!/bin/bash
# 节点分类标签

# CPU 密集型节点
kubectl label nodes node-1 workload-type=cpu-intensive
kubectl label nodes node-2 workload-type=cpu-intensive

# I/O 密集型节点(配置 SSD)
kubectl label nodes node-3 workload-type=io-intensive
kubectl label nodes node-4 workload-type=io-intensive

# GPU 节点
kubectl label nodes node-5 workload-type=gpu-intensive
kubectl label nodes node-6 workload-type=gpu-intensive

第2步:工作负载分类部署

# Web 服务(CPU 密集)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-service
spec:
  replicas: 6
  template:
    spec:
      nodeSelector:
        workload-type: cpu-intensive
      containers:
      - name: web
        image: web:latest
        resources:
          requests:
            cpu: 2
            memory: 2Gi
          limits:
            memory: 4Gi
      priorityClassName: high-priority

---
# 数据处理任务(I/O 密集)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: data-processor
spec:
  replicas: 4
  template:
    spec:
      nodeSelector:
        workload-type: io-intensive
      containers:
      - name: processor
        image: processor:latest
        resources:
          requests:
            cpu: 1
            memory: 4Gi
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: fast-storage-pvc
      priorityClassName: medium-priority

---
# 机器学习训练(GPU 密集)
apiVersion: batch/v1
kind: Job
metadata:
  name: ml-training
spec:
  template:
    spec:
      nodeSelector:
        workload-type: gpu-intensive
      containers:
      - name: training
        image: pytorch:latest
        resources:
          limits:
            nvidia.com/gpu: 1
            cpu: 4
            memory: 16Gi
      priorityClassName: low-priority
      restartPolicy: OnFailure

第3步:优先级和抢占配置

# 高优先级(在线服务)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "高优先级在线服务"

---
# 中优先级(数据处理)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: medium-priority
value: 100000
globalDefault: false
description: "中优先级数据处理"

---
# 低优先级(批处理)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: low-priority
value: 1000
globalDefault: false
description: "低优先级批处理任务"

第4步:资源配额管理

# Web 服务资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
  name: web-quota
  namespace: web
spec:
  hard:
    requests.cpu: "20"
    requests.memory: 40Gi
    limits.memory: 80Gi
    pods: "30"

---
# 批处理资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
  name: batch-quota
  namespace: batch
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 40Gi
    nvidia.com/gpu: "4"
    pods: "20"

最终结果

指标优化前优化后提升
CPU 利用率45%75%67% ↑
GPU 利用率30%80%167% ↑
在线服务稳定性不稳定稳定-
批处理完成时间基准+15%可接受
资源成本基准-25%-

总结与最佳实践

性能调优黄金法则

维度最佳实践避免
CPU移除 limits,只设置 requests过度限制导致 throttling
内存requests = limits内存泄漏导致 OOM
存储使用 SSD + 合适的 StorageClassOverlayFS 层数过多
网络统一 MTU,优化 DNS默认配置
调度使用亲和性/反亲和性所有 Pod 堆在一起

监控指标体系

# 关键监控指标
监控维度:
  应用层:
    - 请求延迟 (P50/P95/P99)
    - 错误率
    - QPS/TPS
  
  容器层:
    - CPU 使用率
    - 内存使用率
    - CPU throttling
    - OOM 次数
  
  节点层:
    - 负载均衡
    - 磁盘 I/O
    - 网络吞吐
  
  集群层:
    - Pod 调度延迟
    - API Server 响应时间
    - etcd 性能

调优流程模板

1. 问题识别
   └─ 监控告警 / 用户反馈

2. 数据收集
   ├─ 应用日志
   ├─ 系统指标
   └─ 性能 profile

3. 瓶颈定位
   ├─ CPU / 内存 / I/O / 网络
   └─ 应用代码 / 配置 / 架构

4. 制定方案
   ├─ 资源调整
   ├─ 代码优化
   └─ 架构改进

5. 实施验证
   ├─ 灰度发布
   ├─ A/B 测试
   └─ 性能对比

6. 总结归档
   ├─ 文档记录
   ├─ 经验沉淀
   └─ 监控完善

完成! 通过这些真实案例,你已经掌握了 Kubernetes 生产环境的系统化调优方法。

下一部分:命令速查与YAML模板库

Prev
第六部分:CNI 与 eBPF 网络深度实践
Next
第八部分:命令速查与YAML模板库