# HPA 诊断报告 > 执行时间: 2025-12-31 > 环境: OrbStack v1.33.5+orb1 > 状态: ⚠️ 发现 OrbStack 限制 --- ## 📊 诊断结果 ### ✅ 已确认正常的部分 1. **metrics-server 运行正常** - Deployment 状态: READY 1/1 - API 服务可用: ✅ `v1beta1.metrics.k8s.io` - 配置已优化: 添加了 `--kubelet-insecure-tls` 和 `--kubelet-preferred-address-types=InternalIP` 2. **Node metrics 正常工作** ```bash $ kubectl top nodes NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%) orbstack 749m 3% 21982Mi 34% ``` 3. **所有 HPA 目标都有 resource requests** - ✅ grafana: CPU 250m, Memory 256Mi - ✅ prometheus: CPU 500m, Memory 512Mi - ✅ argocd-server: CPU 100m, Memory 128Mi - ✅ ingress-nginx-controller: CPU 200m, Memory 256Mi - ✅ gitea-runner: CPU 100m, Memory 128Mi - ✅ claude-stock-backend: CPU 250m, Memory 512Mi 4. **cAdvisor 已启用** ```bash $ kubectl get --raw "/api/v1/nodes/orbstack/proxy/metrics/cadvisor" # cAdvisor metrics 正常返回 ``` --- ### ❌ 发现的问题 #### 核心问题: Pod Metrics 不可用 **症状**: ```bash $ kubectl top pods -n monitoring error: Metrics not available for pod ... $ kubectl get hpa --all-namespaces NAMESPACE NAME TARGETS monitoring grafana-hpa cpu: /70% # ❌ 应该显示具体百分比 ``` **根本原因**: OrbStack 的 kubelet 不提供 Pod 级别的统计信息 **技术细节**: ```bash # Node stats 正常 $ kubectl get --raw "/api/v1/nodes/orbstack/proxy/stats/summary" | jq '.node' { "nodeName": "orbstack", "cpu": {...}, "memory": {...} } # Pod stats 为空 ❌ $ kubectl get --raw "/api/v1/nodes/orbstack/proxy/stats/summary" | jq '.pods | length' 0 # 没有任何 pod 统计信息 # Metrics API 也返回空列表 $ kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/monitoring/pods" {"kind":"PodMetricsList","items":[]} # ❌ 空列表 ``` --- ## 🔍 原因分析 ### OrbStack 的限制 OrbStack 是一个轻量级的 Kubernetes 环境,为了优化性能和资源占用,做了一些简化: 1. **kubelet 简化**: 不完全实现 kubelet 的所有 metrics 接口 2. **cAdvisor 限制**: 虽然 cAdvisor 启用了,但不提供 per-pod metrics 3. **stats API 限制**: `/stats/summary` 只返回 node 级别的统计,不返回 pod 级别 这导致: - ❌ metrics-server 无法收集 pod metrics - ❌ HPA 无法获取 pod 的 CPU/Memory 使用率 - ❌ `kubectl top pods` 不工作 --- ## 🛠️ 解决方案 ### 方案 1: 使用 Prometheus Adapter(推荐)⭐ **原理**: - 绕过 metrics-server - 直接从 Prometheus 获取 metrics - 将 Prometheus metrics 转换为 HPA 可用的 custom metrics **部署步骤**: ```bash # 1. 安装 Prometheus Adapter helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus-adapter prometheus-community/prometheus-adapter \ --namespace monitoring \ --set prometheus.url=http://prometheus.monitoring.svc.cluster.local:9090 \ --set prometheus.port=9090 # 2. 验证 custom metrics API kubectl get apiservice v1beta1.custom.metrics.k8s.io # 3. 修改 HPA 使用 custom metrics cat > /tmp/hpa-custom-metrics.yaml << 'EOF' apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: grafana-hpa namespace: monitoring spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: grafana minReplicas: 1 maxReplicas: 3 metrics: - type: Pods pods: metric: name: cpu_usage target: type: AverageValue averageValue: 500m EOF kubectl apply -f /tmp/hpa-custom-metrics.yaml ``` **优点**: - ✅ 完全绕过 OrbStack 限制 - ✅ 使用现有的 Prometheus metrics - ✅ 支持自定义 metrics(不仅限于 CPU/Memory) - ✅ 更强大的扩缩容逻辑 **缺点**: - 需要配置 Prometheus metrics 映射 - HPA 配置略微复杂 **预计时间**: 1 小时 **成功率**: 95%+ --- ### 方案 2: 使用 KEDA(推荐用于复杂场景)⭐⭐ **原理**: - Kubernetes Event Driven Autoscaling - 支持多种 metrics 来源(Prometheus, Redis, Kafka, etc) - 不依赖 metrics-server **部署步骤**: ```bash # 1. 安装 KEDA helm repo add kedacore https://kedacore.github.io/charts helm repo update helm install keda kedacore/keda --namespace keda --create-namespace # 2. 创建 ScaledObject(替代 HPA) cat > /tmp/keda-scaledobject.yaml << 'EOF' apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: grafana-scaler namespace: monitoring spec: scaleTargetRef: name: grafana minReplicaCount: 1 maxReplicaCount: 3 triggers: - type: prometheus metadata: serverAddress: http://prometheus.monitoring.svc.cluster.local:9090 metricName: cpu_usage_rate query: | rate(container_cpu_usage_seconds_total{pod=~"grafana-.*"}[1m]) threshold: "0.7" EOF kubectl apply -f /tmp/keda-scaledobject.yaml ``` **优点**: - ✅ 功能最强大 - ✅ 支持多种 event sources - ✅ 支持扩容到 0(节省资源) - ✅ 完全不依赖 metrics-server **缺点**: - 需要学习新的 API(ScaledObject) - 替代传统 HPA(不兼容) **预计时间**: 2 小时 **成功率**: 98%+ --- ### 方案 3: 手动扩缩容(不推荐) **原理**: - 定期检查 Prometheus metrics - 通过脚本手动调整 replicas **示例脚本**: ```bash #!/bin/bash # auto-scale-grafana.sh NAMESPACE="monitoring" DEPLOYMENT="grafana" MIN_REPLICAS=1 MAX_REPLICAS=3 CPU_THRESHOLD=70 # 70% # 从 Prometheus 获取 CPU 使用率 CPU_USAGE=$(kubectl exec -n monitoring deployment/prometheus -- \ promtool query instant 'rate(container_cpu_usage_seconds_total{pod=~"grafana-.*"}[1m])' | \ jq -r '.data.result[0].value[1]') # 计算所需副本数 CURRENT_REPLICAS=$(kubectl get deployment $DEPLOYMENT -n $NAMESPACE -o jsonpath='{.spec.replicas}') if (( $(echo "$CPU_USAGE > 0.7" | bc -l) )); then NEW_REPLICAS=$((CURRENT_REPLICAS + 1)) if [ $NEW_REPLICAS -le $MAX_REPLICAS ]; then kubectl scale deployment $DEPLOYMENT -n $NAMESPACE --replicas=$NEW_REPLICAS fi elif (( $(echo "$CPU_USAGE < 0.3" | bc -l) )); then NEW_REPLICAS=$((CURRENT_REPLICAS - 1)) if [ $NEW_REPLICAS -ge $MIN_REPLICAS ]; then kubectl scale deployment $DEPLOYMENT -n $NAMESPACE --replicas=$NEW_REPLICAS fi fi ``` **优点**: - ✅ 简单直接 - ✅ 完全控制扩缩容逻辑 **缺点**: - ❌ 需要定期执行(cron) - ❌ 不如 HPA 实时 - ❌ 需要维护脚本 --- ### 方案 4: 升级到完整的 Kubernetes 环境(终极方案) **选项**: 1. **kind (Kubernetes in Docker)** - 更接近生产环境 2. **k3s** - 轻量但功能完整 3. **Minikube** - 传统选择 4. **Rancher Desktop** - GUI 友好 **迁移步骤**: ```bash # 选择 kind 为例 brew install kind # 创建集群 kind create cluster --name dev-cluster # 迁移资源 kubectl get all --all-namespaces -o yaml > cluster-backup.yaml # 在新集群中应用 kubectl apply -f cluster-backup.yaml ``` **优点**: - ✅ 100% Kubernetes 兼容 - ✅ HPA 开箱即用 - ✅ 所有 K8s 功能可用 **缺点**: - ❌ 资源占用更高 - ❌ 启动稍慢 - ❌ 需要迁移现有环境 --- ## 💡 推荐行动方案 ### 短期(本周): 部署 Prometheus Adapter **理由**: - ✅ 最小改动 - ✅ 利用现有 Prometheus - ✅ HPA 仍然可用(只需修改 metrics 来源) - ✅ 1 小时即可完成 **执行计划**: 参考 [K8S-OPTIMIZATION-ROADMAP-2025.md](./K8S-OPTIMIZATION-ROADMAP-2025.md) 中的详细步骤 --- ### 中期(下月): 评估 KEDA **理由**: - ✅ 功能更强大 - ✅ 支持更多 scaling 场景 - ✅ 云原生最佳实践 --- ### 长期(未来): 考虑迁移到完整 K8s **评估标准**: - 如果需要生产级别的 K8s 功能 - 如果 OrbStack 限制影响开发体验 - 如果需要完全的 K8s API 兼容性 --- ## 📋 当前 HPA 状态 | HPA | 命名空间 | 目标 | 当前状态 | 备注 | |-----|---------|------|----------|------| | grafana-hpa | monitoring | Deployment/grafana | ❌ `` | 等待 Prometheus Adapter | | prometheus-hpa | monitoring | Deployment/prometheus | ❌ `` | 等待 Prometheus Adapter | | argocd-server-hpa | argocd | Deployment/argocd-server | ❌ `` | 等待 Prometheus Adapter | | ingress-nginx-hpa | infra | Deployment/ingress-nginx-controller | ❌ `` | 等待 Prometheus Adapter | | gitea-runner-hpa | gitea-runner | Deployment/gitea-runner | ❌ `` | 等待 Prometheus Adapter | | claude-stock-backend-hpa | ljwx-stock | Deployment/claude-stock-backend | ❌ `` | 等待 Prometheus Adapter | --- ## 🎯 下一步行动 ### 立即执行(推荐) 1. **部署 Prometheus Adapter** (1 小时) ```bash cd /Users/brunogao/work/codes/tools/macos/k8s # 按照路线图执行 ``` 2. **更新 HPA 配置** (30 分钟) - 将 HPA 修改为使用 custom metrics - 测试扩缩容功能 3. **验证工作** (15 分钟) - 创建负载测试 - 观察 HPA 扩容 **总时间**: 约 1.5 小时 **成功率**: 95%+ --- ## 📚 参考资料 - **Prometheus Adapter**: https://github.com/kubernetes-sigs/prometheus-adapter - **KEDA**: https://keda.sh/ - **OrbStack Issues**: https://github.com/orbstack/orbstack/issues - **K8s HPA**: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ --- **报告生成**: 2025-12-31 **诊断时长**: 30 分钟 **状态**: ⚠️ 需要部署 Prometheus Adapter