update mertics

This commit is contained in:
Ubuntu
2026-01-06 05:03:27 +00:00
parent 23116e9086
commit 98f4b0a617
5 changed files with 329 additions and 9 deletions
+48 -5
View File
@@ -219,26 +219,69 @@ curl http://localhost:8000/agents/alice-echo/status
GET /agents/{agent_name}/metrics GET /agents/{agent_name}/metrics
``` ```
**功能说明**
获取 Agent 的资源使用情况,包括:
- **requests/limits**: 资源配额(从 Pod spec 获取)
- **usage**: 实时资源使用情况(从 metrics-server 获取,需要集群安装 metrics-server)
- **timestamp**: metrics 数据的时间戳
**响应** **响应**
```json ```json
{ {
"name": "alice-echo", "name": "alice-echo",
"namespace": "ai-agents", "namespace": "ai-agents",
"resources": { "requests": {
"cpu_usage": "50m", "cpu": "100m",
"memory_usage": "128Mi", "memory": "128Mi"
"available": true },
} "limits": {
"cpu": "500m",
"memory": "512Mi"
},
"usage": {
"cpu": "14502n",
"memory": "8704Ki"
},
"timestamp": "2026-01-06T05:01:04Z",
"metrics_available": null
} }
``` ```
**字段说明**
| 字段 | 类型 | 说明 |
|------|------|------|
| name | string | Pod 名称 |
| namespace | string | 命名空间 |
| requests | object | 资源请求配额 |
| limits | object | 资源限制配额 |
| usage | object \| null | 实时资源使用(需要 metrics-server) |
| timestamp | string \| null | metrics 时间戳(ISO 8601 格式) |
| metrics_available | bool \| null | metrics-server 是否可用 |
**CPU 单位说明**
- `n` (nanocores): 1 核 = 1,000,000,000n
- `m` (millicores): 1 核 = 1,000m
- 例如: `14502n` = 0.014502m ≈ 0.000014 核
**内存单位说明**
- `Ki` (Kibibytes): 1024 字节
- `Mi` (Mebibytes): 1024 KiB
- 例如: `8704Ki` ≈ 8.5 MiB
**示例** **示例**
```bash ```bash
curl http://localhost:8000/agents/alice-echo/metrics curl http://localhost:8000/agents/alice-echo/metrics
``` ```
**注意事项**
- 如果集群未安装 metrics-server,`usage` 和 `timestamp` 将为 `null`
- metrics 数据由 Kubernetes metrics-server 提供,更新频率通常为 15-60 秒
- `usage` 显示的是 Pod 的实际资源消耗,不是配额
--- ---
### 5. 删除 Agent ### 5. 删除 Agent
+194
View File
@@ -0,0 +1,194 @@
## 实时 Metrics 功能修复报告
### 📋 问题描述
**原问题**:`/agents/{agent_name}/metrics` 接口返回的 metrics 始终一致,只显示 Pod 的资源配额(requests/limits),而不是实时的资源使用情况。
### ✅ 修复内容
#### 1. 修改 `k8s_manager.py::get_pod_metrics()` 方法
**修改前**:
```python
def get_pod_metrics(self, pod_name: str) -> Dict:
pod = self.v1.read_namespaced_pod(name=pod_name, namespace=self.namespace)
container = pod.spec.containers[0]
resources = container.resources
return {
"name": pod_name,
"requests": {...}, # 静态配额
"limits": {...} # 静态配额
}
```
**修改后**:
```python
def get_pod_metrics(self, pod_name: str) -> Dict:
# 1. 获取静态配额
pod = self.v1.read_namespaced_pod(...)
resources = pod.spec.containers[0].resources
# 2. 获取实时使用情况(通过 metrics.k8s.io API)
from kubernetes.client import CustomObjectsApi
custom_api = CustomObjectsApi()
metrics = custom_api.get_namespaced_custom_object(
group="metrics.k8s.io",
version="v1beta1",
namespace=self.namespace,
plural="pods",
name=pod_name
)
# 3. 返回完整数据
return {
"name": pod_name,
"namespace": self.namespace,
"requests": {...},
"limits": {...},
"usage": { # 🆕 实时使用
"cpu": "14502n",
"memory": "8704Ki"
},
"timestamp": "..." # 🆕 更新时间
}
```
#### 2. 更新 `app.py::PodMetricsResponse` 模型
**修改前**:
```python
class PodMetricsResponse(BaseModel):
name: str
requests: Dict
limits: Dict
```
**修改后**:
```python
class PodMetricsResponse(BaseModel):
name: str
namespace: Optional[str] = None
requests: Dict
limits: Dict
usage: Optional[Dict] = None # 🆕 实时使用
timestamp: Optional[str] = None # 🆕 时间戳
metrics_available: Optional[bool] = None # 🆕 可用性标志
```
#### 3. 更新 API 文档
在 `API_DOCUMENTATION.md` 中添加了详细的字段说明和单位解释。
### 📊 测试结果
#### 测试 1: 单个 Agent 多次查询
```bash
# 查询 alice-echo 三次
测试 1: CPU=13812n, Memory=8704Ki, Time=2026-01-06T05:00:18Z
测试 2: CPU=14502n, Memory=8704Ki, Time=2026-01-06T05:01:04Z
测试 3: CPU=15234n, Memory=8704Ki, Time=2026-01-06T05:02:18Z
```
✅ **结果**:CPU 使用率实时变化,时间戳更新
#### 测试 2: 多个 Agent 对比
| Agent | CPU 使用 | 内存使用 | CPU 限制 | 内存限制 |
|-------|----------|----------|----------|----------|
| alice-echo | 14502n (0.014m) | 8704Ki (8.5Mi) | 500m | 512Mi |
| bob-chat | 10010n (0.010m) | 10840Ki (10.6Mi) | 500m | 512Mi |
| carol-code | 5330n (0.005m) | 10868Ki (10.6Mi) | 500m | 512Mi |
| jina-search | **897912n (0.897m)** | **41416Ki (40.4Mi)** | 500m | 512Mi |
| my-agent | 14780n (0.015m) | 8688Ki (8.5Mi) | 500m | 512Mi |
✅ **结果**:不同 Agent 显示不同的实时使用情况
### 🔍 技术细节
#### Metrics API 调用
```python
# Kubernetes Metrics API 端点
GET /apis/metrics.k8s.io/v1beta1/namespaces/{namespace}/pods/{pod_name}
# 响应格式
{
"kind": "PodMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {...},
"timestamp": "2026-01-06T05:01:04Z",
"containers": [
{
"name": "echo-agent",
"usage": {
"cpu": "14502n",
"memory": "8704Ki"
}
}
]
}
```
#### 单位说明
**CPU**:
- `n` (nanocores): 1 核 = 1,000,000,000 nanocores
- `m` (millicores): 1 核 = 1,000 millicores
- 转换: `14502n = 0.014502m ≈ 0.000014 核`
**内存**:
- `Ki` (Kibibytes): 1 KiB = 1024 bytes
- `Mi` (Mebibytes): 1 MiB = 1024 KiB
- 转换: `8704Ki = 8.5 MiB ≈ 8.9 MB`
### 🎯 功能特性
1. **实时监控**:通过 Kubernetes metrics-server 获取实时数据
2. **降级支持**:如果 metrics-server 不可用,仍返回配额信息
3. **时间戳**:显示 metrics 数据的更新时间
4. **完整信息**:同时显示配额(limits/requests)和使用(usage)
### 📝 使用示例
```bash
# 获取单个 Agent 的 metrics
curl http://localhost:8000/agents/alice-echo/metrics
# 监控 CPU 使用率
watch -n 5 'curl -s http://localhost:8000/agents/alice-echo/metrics | jq ".usage.cpu"'
# 对比多个 Agent
for agent in alice-echo bob-chat carol-code; do
echo "$agent:"
curl -s http://localhost:8000/agents/$agent/metrics | jq ".usage"
done
```
### ⚠️ 注意事项
1. **metrics-server 依赖**:需要集群安装 metrics-server
```bash
kubectl get deployment metrics-server -n kube-system
```
2. **更新频率**:metrics-server 通常每 15-60 秒更新一次数据
3. **网络延迟**:metrics API 调用可能增加约 50-200ms 响应时间
4. **权限要求**:需要 kubeconfig 有权限访问 metrics.k8s.io API
### ✅ 修复完成
- [x] 修改 `k8s_manager.py::get_pod_metrics()`
- [x] 更新 `app.py::PodMetricsResponse` 模型
- [x] 更新 API 文档
- [x] 创建测试脚本 `test_realtime_metrics.sh`
- [x] 验证多个 Agent 的实时数据
- [x] 确认 CPU/内存使用率实时变化
**问题状态**: ✅ 已解决
**修复时间**: 2026-01-06
**测试通过**: ✅ 5/5 Agents 显示实时数据
+4
View File
@@ -223,8 +223,12 @@ class PodStatusResponse(BaseModel):
class PodMetricsResponse(BaseModel): class PodMetricsResponse(BaseModel):
"""Pod资源使用响应""" """Pod资源使用响应"""
name: str name: str
namespace: Optional[str] = None
requests: Dict requests: Dict
limits: Dict limits: Dict
usage: Optional[Dict] = None # 实时使用情况(需要 metrics-server)
timestamp: Optional[str] = None # metrics 时间戳
metrics_available: Optional[bool] = None # metrics-server 是否可用
class MessageResponse(BaseModel): class MessageResponse(BaseModel):
+41 -4
View File
@@ -411,11 +411,10 @@ class K8sManager:
pod_name: Pod名称 pod_name: Pod名称
Returns: Returns:
Pod资源使用信息 Pod实时资源使用信息和配额信息
""" """
try: try:
# 注意: 需要集群安装metrics-server # 获取 Pod 配额信息
# 这里提供基本的资源配额信息
pod = self.v1.read_namespaced_pod( pod = self.v1.read_namespaced_pod(
name=pod_name, name=pod_name,
namespace=self.namespace namespace=self.namespace
@@ -424,8 +423,9 @@ class K8sManager:
container = pod.spec.containers[0] container = pod.spec.containers[0]
resources = container.resources resources = container.resources
return { result = {
"name": pod_name, "name": pod_name,
"namespace": self.namespace,
"requests": { "requests": {
"cpu": resources.requests.get("cpu") if resources.requests else None, "cpu": resources.requests.get("cpu") if resources.requests else None,
"memory": resources.requests.get("memory") if resources.requests else None "memory": resources.requests.get("memory") if resources.requests else None
@@ -435,6 +435,43 @@ class K8sManager:
"memory": resources.limits.get("memory") if resources.limits else None "memory": resources.limits.get("memory") if resources.limits else None
} }
} }
# 尝试获取实时使用情况(需要 metrics-server)
try:
from kubernetes.client import CustomObjectsApi
custom_api = CustomObjectsApi()
# 调用 metrics.k8s.io API
metrics = custom_api.get_namespaced_custom_object(
group="metrics.k8s.io",
version="v1beta1",
namespace=self.namespace,
plural="pods",
name=pod_name
)
# 提取实时使用数据
if metrics and "containers" in metrics:
container_metrics = metrics["containers"][0]
usage = container_metrics.get("usage", {})
result["usage"] = {
"cpu": usage.get("cpu"),
"memory": usage.get("memory")
}
result["timestamp"] = metrics.get("timestamp")
logger.info(f"✅ 获取到实时资源使用: CPU={usage.get('cpu')}, Memory={usage.get('memory')}")
else:
result["usage"] = None
logger.warning(f"⚠️ Metrics 数据格式异常")
except Exception as metrics_error:
logger.warning(f"⚠️ 无法获取实时资源使用(可能未安装 metrics-server): {str(metrics_error)}")
result["usage"] = None
result["metrics_available"] = False
return result
except ApiException as e: except ApiException as e:
logger.error(f"获取Pod资源信息失败: {e}") logger.error(f"获取Pod资源信息失败: {e}")
raise Exception(f"获取Pod资源信息失败: {e.reason}") raise Exception(f"获取Pod资源信息失败: {e.reason}")
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
echo "🔍 测试实时 Metrics 功能"
echo "======================================"
echo ""
# 获取所有运行中的 agents
agents=$(curl -s http://localhost:8000/agents | jq -r '.agents[].name' | head -5)
echo "📊 查询前 5 个 Agent 的实时资源使用情况:"
echo ""
for agent in $agents; do
echo "Agent: $agent"
echo "----------------------------------------"
metrics=$(curl -s http://localhost:8000/agents/$agent/metrics)
# 提取数据
cpu_usage=$(echo $metrics | jq -r '.usage.cpu // "N/A"')
memory_usage=$(echo $metrics | jq -r '.usage.memory // "N/A"')
cpu_limit=$(echo $metrics | jq -r '.limits.cpu // "N/A"')
memory_limit=$(echo $metrics | jq -r '.limits.memory // "N/A"')
timestamp=$(echo $metrics | jq -r '.timestamp // "N/A"')
echo " 实时使用:"
echo " CPU: $cpu_usage"
echo " Memory: $memory_usage"
echo " 资源限制:"
echo " CPU: $cpu_limit"
echo " Memory: $memory_limit"
echo " 更新时间: $timestamp"
echo ""
done
echo "======================================"
echo "✅ 测试完成"
echo ""
echo "💡 说明:"
echo " - CPU 单位: n=纳核(nanocores), m=毫核(millicores)"
echo " - Memory 单位: Ki=KiB, Mi=MiB"
echo " - 实时数据每 15-60 秒更新一次(由 metrics-server 决定)"