实战目标
在前一篇笔记中,我们学习了 Operator 的基本结构与 reconcile 机制。本篇将结合 LLM,构建一个简易的 AIOps Operator,使其能够:
- 接收用户声明的
AITask自定义资源。 - 根据配置定期采集目标 Deployment 的状态和指标。
- 当触发阈值或异常状态时,调用 LLM 进行根因分析。
- 根据 LLM 的决策,自动执行修复动作(如重启 Pod、扩容)。
这种将 AI 推理能力嵌入 Kubernetes 控制平面的方式,是 AIOps 平台化的重要方向。
AIOps Operator 设计
CRD 定义
我们定义一个名为 AutoHeal 的 CRD:
apiVersion: aiops.example.com/v1
kind: AutoHeal
metadata:
name: api-gateway-healer
namespace: prod
spec:
targetDeployment: api-gateway
namespace: prod
metricsSource: prometheus
query: |
histogram_quantile(0.99,
rate(http_request_duration_seconds_bucket[5m]))
threshold: 0.5
action: restart_pod
llmEndpoint: http://llm-service:8000/v1/chat
status:
phase: Monitoring
lastDecision: ""
lastExecutionTime: ""
控制器逻辑
控制器 reconcile 流程如下:
1. 读取 AutoHeal CR
2. 查询 Prometheus 获取当前指标
3. 若指标超过 threshold,构造 Prompt 调用 LLM
4. 解析 LLM 返回的 action
5. 执行 action(client-go 调用)
6. 更新 AutoHeal status
7. RequeueAfter 继续下一轮监控
核心代码示例
指标查询
func queryPrometheus(url, promql string) (float64, error) {
resp, err := http.Get(fmt.Sprintf("%s/api/v1/query?query=%s", url, url.QueryEscape(promql)))
if err != nil {
return 0, err
}
defer resp.Body.Close()
// 解析 JSON 提取 value
return parsePrometheusValue(resp.Body)
}
LLM 调用与决策
func askLLM(endpoint, context string) (string, error) {
prompt := fmt.Sprintf(`
你是一名 Kubernetes SRE。当前系统监控信息如下:
%s
请从以下动作中选择一个并直接返回动作名称:restart_pod / scale_up / noop
`, context)
reqBody, _ := json.Marshal(map[string]interface{}{
"model": "gpt-4",
"messages": []map[string]string{
{"role": "user", "content": prompt},
},
})
resp, err := http.Post(endpoint, "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return "", err
}
defer resp.Body.Close()
// 解析 LLM 输出
return parseLLMAction(resp.Body)
}
执行修复动作
func executeAction(ctx context.Context, c client.Client, action, namespace, deployment string) error {
switch action {
case "restart_pod":
// 删除 Pod 触发重新调度
pods := &corev1.PodList{}
if err := c.List(ctx, pods, client.InNamespace(namespace), client.MatchingLabels{"app": deployment}); err != nil {
return err
}
for _, pod := range pods.Items {
if err := c.Delete(ctx, &pod); err != nil {
return err
}
}
case "scale_up":
dep := &appsv1.Deployment{}
if err := c.Get(ctx, types.NamespacedName{Namespace: namespace, Name: deployment}, dep); err != nil {
return err
}
*dep.Spec.Replicas++
return c.Update(ctx, dep)
}
return nil
}
Reconcile 主流程
func (r *AutoHealReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var ah aiopsv1.AutoHeal
if err := r.Get(ctx, req.NamespacedName, &ah); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
value, err := queryPrometheus(ah.Spec.MetricsSource, ah.Spec.Query)
if err != nil {
return ctrl.Result{}, err
}
if value > ah.Spec.Threshold {
context := fmt.Sprintf("Deployment: %s/%s, P99 latency: %.2fs, threshold: %.2fs",
ah.Spec.Namespace, ah.Spec.TargetDeployment, value, ah.Spec.Threshold)
action, err := askLLM(ah.Spec.LLMEndpoint, context)
if err != nil {
return ctrl.Result{}, err
}
if err := executeAction(ctx, r.Client, action, ah.Spec.Namespace, ah.Spec.TargetDeployment); err != nil {
return ctrl.Result{}, err
}
ah.Status.LastDecision = action
ah.Status.LastExecutionTime = metav1.Now().Format(time.RFC3339)
ah.Status.Phase = "Healed"
} else {
ah.Status.Phase = "Monitoring"
}
if err := r.Status().Update(ctx, &ah); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{RequeueAfter: 60 * time.Second}, nil
}
部署与验证
- 使用 kubebuilder 生成 CRD 与 RBAC。
- 构建镜像并部署到集群。
- 创建 AutoHeal CR。
- 通过压测工具制造高延迟,观察 Operator 是否能自动触发修复。
kubectl apply -f config/crd/bases/aiops.example.com_autoheals.yaml
kubectl apply -f config/samples/aiops_v1_autoheal.yaml
kubectl logs -n aiops-system deployment/aiops-operator-controller-manager
设计要点与注意事项
- LLM 输出可靠性:LLM 可能产生不确定输出,建议将 action 限制在白名单内,并对输出进行校验。
- 安全控制:Operator 拥有较高权限,应通过 RBAC 最小化授权,并对危险操作增加审批机制。
- 可观测性:记录每次决策的上下文、指标、LLM 输出和执行结果,便于后续审计与模型优化。
- 回滚与限流:对自动修复操作设置冷却时间和最大执行次数,避免误操作扩大故障。
总结
通过将 LLM 决策能力封装到 Kubernetes Operator 中,我们实现了"声明式 AIOps":用户只需声明期望的修复策略,Operator 就能自主完成观测、推理和执行。这种模式为后续构建更复杂的 AIOps 平台奠定了坚实基础。