DevOps 运维中 AI 那些事
把 AI 放进运维的真实分工:哪些决策该交给规则、哪些适合概率性判断,如何先建可观测性与数据门禁,再用只读、起草、受限执行、闭环四阶段落地,并用采纳率和 MTTR 验证。
| 项目 | 说明 |
|---|---|
| 适用环境 | Kubernetes 1.29、Prometheus 2.x、Loki 2.x、Promtail 2.x、Alertmanager 0.22+ |
| 示例边界 | prompt 与命令可直接复制;厂商、型号、驱动相关参数需按实际环境核对 |
| 前置条件 | 已有指标、日志、告警栈;具备 kubectl 只读权限 |
| 最后核对 | 2026-10-27 |
先说结论
- AI 只改变「判断」环节,不改变「观察 → 判断 → 行动」的循环。
- 确定性规则优先:告警触发、变更放行、配额权限、SLO 目标不交给模型。
- 任何自动执行前,都必须在出口转换回确定性校验:dry-run、diff、白名单、审计。
- 先有可观测性和统一口径,再谈 AI;数据质量是效果的上限。
- 从最耗时的环节开始,用采纳率和 MTTR 量化,再决定是否扩大。
这两年运维群里最常见的一类对话是:贴一段报错,问谁看得懂。以前碰到这种问题,要翻文档、翻历史工单、翻 Prometheus,运气不好还得翻半年前的变更记录;现在大家的第一反应是丢给模型。这篇要解决的问题是:AI 到底应该在运维链路里站在哪个位置、为什么是那个位置、以及怎么把它接进去而不翻车。它背后最基础的机制只有一句话——运维的每一次动作都是一次"观察 → 判断 → 行动"的决策循环,而 AI 改变的只是"判断"这个环节的决策路径:把原本靠人从大量非结构化信息里归纳因果的过程,变成由模型先做概率性归纳、再由人裁决;至于"观察"要喂给它什么、"行动"能不能自动执行,仍然由确定性的数据底座和规则体系决定。换句话说,AI 的输出质量上限由输入数据质量决定,这就是"先建可观测性与标准化、再谈 AI"的根本原因。
#一、原理层:AI 进入运维链路,改变的是哪一段决策路径
#1.1 运维的本质是一个决策循环
任何一个运维动作,无论多简单,都走同一条链路:
- 观察:从日志、指标、链路、事件、版本记录、硬件状态里收集信息;
- 判断:把现象归类、定位根因、排出优先级,决定先做什么、后做什么;
- 行动:执行变更,比如加副本、改配置、重启、扩容、标记故障。
过去这条链路的瓶颈几乎都在"观察"和"判断":信息分散在十几个系统里,值班的人大半时间花在找信息而不是分析信息;找到之后,判断又依赖个人经验和历史记忆。
AI 进入运维,本质上是在这段循环里做两件事:在"观察"环节承担信息聚合与压缩(把几百行日志变成几类、把几十个面板浓缩成一个上下文包),在"判断"环节提供概率性的因果候选("现象 X 最可能是原因 A、B、C,按概率排序,每条给验证命令")。它没有改变循环本身,改变的是循环里每段的时间占比和决策的起始点。
#1.2 决策路径有两种形态:确定性规则与概率性判断
要判断一个环节该不该交给 AI,先看这个决策能不能被形式化。
确定性规则路径:条件可穷举、判定可复现、结果可审计。典型如:阈值告警(CPU 连续 5 分钟超过 90%)、配额校验(请求量超过 Pod 上限就拒绝调度)、格式转换、幂等的回滚动作(删掉失败 Job 的重试计数)。这类路径应该继续用代码、规则引擎和 PromQL 表达式实现,因为人可以在评审会上逐行念出来、可以用 promtool 校验、可以在事故发生前穷举测试。
概率性判断路径:输入非结构化、语义有歧义、结论依赖长期上下文和经验。典型如:几百行 SEL(系统事件日志,System Event Log)里区分真故障与插拔噪音、上万行编译日志里定位"第一个真正的错误"、根据历史用量估算 requests/limits、判断一条网络策略变更会不会误伤相邻网段。这类路径恰恰是语言模型的长处,也是它真正改变决策质量的地方。
两者之间有一条硬边界:任何要自动执行的决策,都必须先在出口处转换回确定性校验——dry-run、diff、白名单、审计日志。模型可以提议,但"放行"这件事永远由确定性检查说了算。这也是后文所有落地的前提。
#1.3 底层事实:数据质量决定 AI 效果
模型在运维场景里的表现,上限不是由模型本身决定,而是由喂给它的数据决定。可以把这个事实拆成三句话:
- 缺失导致臆测:该采样的指标没采、该留的上下文没留,模型只能按"平均情况"猜,而平均情况在线上事故里几乎总是错的;
- 脏数据导致误判:日志里混着脱敏不彻底的 token、时区不统一的 timestamp、口径不一致的字段,模型会把这些噪音当成特征,输出看似合理实则跑偏的结论;
- 口径不一致导致无法复用:两个团队对"5xx"的定义不同、两个环境对"CPU 使用率"的取数不同,模型给出的规则和阈值就无法在不同环境间迁移。
所以"先可观测性、再 AI"不是顺序洁癖,而是因果必然:AI 的输出质量是输入质量的函数。喂全量日志不仅贵,而且会把模型的注意力稀释掉;喂结构化、过滤过、采样过、口径一致的数据,它才能做有意义的聚类和归因。原文里那句"全量日志丢给模型成本很高,先过滤、采样、脱敏,再喂",说的就是这个底层事实。
#1.4 三档定位与三条红线
基于上面的推导,AI 在运维里能站的位置可以明确分成三档,每档的决策路径和风险完全不同:
| 档位 | 做的事情 | 决策路径 | 风险 |
|---|---|---|---|
| 只读顾问 | 给只读账号、只读 API,只输出分析和建议 | 概率性判断,人工全权裁决 | 最低,最容易起步 |
| 变更起草 | 产出 diff、YAML、脚本,走正常评审 | 概率性输出 + 确定性评审 | 中,人仍是审批人 |
| 自动执行 | 只限幂等、可回滚、影响面可控的动作 | 确定性校验 + 白名单 + 审计 | 高,必须逐步放开 |
三条红线我一直在守:
- 不直接给它生产写权限;
- 不让它碰密钥和凭据;
- 它给的每条命令、每个参数,都要能验证。
第三条最容易被忽略——运维场景里幻觉的代价不是"答错了",是"改炸了"。有一个简单的判断标准可以随身带:这条命令你不敢在评审会上念出来,就别让它自动执行。
#1.5 哪些环节仍必须确定性规则优先
原理层最后要划清的是:AI 不是要替代规则,而是要在规则的骨架里填空。以下环节保持确定性优先:
- 告警触发本身:阈值、for 时长、抑制关系,用 Prometheus rules + Alertmanager 表达,不用模型判断"要不要报警";
- 变更的放行闸门:dry-run、diff、灰度比例、回滚预案,全部是可执行代码,不是模型建议;
- 配额、限额、权限:资源 requests/limits、RBAC(基于角色的访问控制,Role-Based Access Control)、网络策略,任何情况下都不能由模型动态放宽;
- SLO 的目标值:SLO 得业务来定,模型只负责把业务目标翻译成规则。"用户能接受多久不可用"这件事,模型不知道。
如果把这节压缩成一句话:AI 负责把"找信息、想原因"的成本打下来,规则负责保证"动生产"的安全性。
| 环节 | 规则负责 | AI 负责 | 判定标准 |
|---|---|---|---|
| 告警触发 | 阈值、for 时长、抑制关系 | 规则审阅、降噪建议 | promtool 可校验,人能逐行念出来 |
| 变更放行 | dry-run、diff、灰度、回滚预案 | 起草 diff、列影响面与回滚点 | 输出能在评审会上被逐条复核 |
| 配额与权限 | requests/limits、RBAC、NetworkPolicy | 历史用量分析、草案 | 模型不能动态放宽任何限制 |
| SLO 目标 | 业务定值、错误预算 | 翻译成规则、解释影响 | 业务方签字确认 |
| 根因定位 | 数据采集、基线、日志时间窗 | 聚类、时间线、候选根因排序 | 每条结论都有可执行验证命令 |
| 自动执行 | 白名单、幂等、审计日志 | 提出动作候选 | 可回滚、可审计、人可随时接管 |
#二、操作层(一):先立数据底座——可观测性与标准化
下面进入可复现的部分。为了不编造环境,先约定本文的示例环境:Linux 服务器(systemd、cgroup v2),Kubernetes 集群以 1.29 为例,可观测性栈以 Prometheus 2.x + node_exporter + Loki 2.x + Promtail + Alertmanager 为例。这些工具与原文提到的 PromQL、LogQL 生态一致;版本号不同不影响命令形态,遇差异以你实际环境的文档为准。
前置条件:Prometheus、Loki、Promtail、Alertmanager、node_exporter 已安装(可用包管理器或官方二进制部署);Kubernetes 环境已有 kubectl 访问权限。所有示例命令假设在能访问目标集群的机器上执行。
#2.1 指标采集:node_exporter + Prometheus
指标是 AI 判断中最可信的输入,因为它结构化、可校验。先保证时序数据是干净的。
启动 node_exporter(默认监听 9100):
node_exporter --web.listen-address=":9100"
# 验证抓取是否正常
curl -s http://127.0.0.1:9100/metrics | grep -E '^node_cpu_seconds_total' | head -5预期输出是形如 node_cpu_seconds_total{cpu="0",mode="idle"} 1.23e+06 的一组序列。看到这个输出,说明采集可用了。
在 Prometheus 的 prometheus.yml 里加上抓取目标:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: node
static_configs:
- targets: ['127.0.0.1:9100']改完配置后用 promtool 校验并热加载:
promtool check config prometheus.yml
curl -X POST http://127.0.0.1:9090/-/reload对 Kubernetes 集群,把 static_configs 换成 kubernetes_sd_configs(服务发现,service discovery),让 Prometheus 自动发现节点和 Pod,并保证每个 target 上有统一的 namespace、pod、app 标签——这些标签是后面所有按维度聚合查询的基础。标签命名不统一,是"口径不一致"最常见的来源。
#2.2 日志接入:Promtail + Loki
日志是 AI 排障的主要输入,但也是最脏的数据。接入阶段就要做好两件事:结构化标签和对齐时间。
Promtail 抓取 systemd journal 的配置示例(以 Promtail 2.x 为例):
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /var/log/promtail/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: journal
journal:
max_age: 12h
labels:
job: systemd-journal
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: unit
- source_labels: ['__journal__hostname']
target_label: host启动与验证:
promtail -config.file=promtail.yaml
# 用 logcli 查一下有没有日志进来
logcli query '{job="systemd-journal"}' --limit=20预期能看到带 unit、host 标签的日志行。先把 unit、host、namespace、app 这类标签打好,后续"按服务聚合、按主机过滤、重建故障时间线"才有依据。 这也是 AI 能正确聚类的前提。
#2.3 告警规则:Prometheus rules + Alertmanager
先把确定性骨架立起来,AI 才有地方"填空"。以下规则对应原文的典型场景:"过去一小时 5xx 比例超过 1% 的服务"——它依赖应用暴露 http_requests_total{code,method,namespace,service} 这类指标(常见 exporter 如 Prometheus HTTP client 库自带)。
groups:
- name: availability.rules
rules:
- alert: High5xxRatio
expr: |
sum by (namespace, service) (
rate(http_requests_total{code=~"5.."}[5m])
) / sum by (namespace, service) (
rate(http_requests_total[5m])
) > 0.01
for: 10m
labels:
severity: warning
annotations:
summary: "{{ $labels.namespace }}/{{ $labels.service }} 5xx 占比超过 1% 持续 10 分钟"校验规则文件:
promtool check rules rules/*.yml父子告警的抑制是降噪的关键一环。Alertmanager 配置示例(以 Alertmanager 0.22+ 的 matchers 语法为例):
route:
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: default
inhibit_rules:
- source_matchers: ['severity="critical"']
target_matchers: ['severity=~"warning|info"']
equal: ['namespace']
receivers:
- name: default
webhook_configs:
- url: 'http://oncall-hook:8080/alert'这条抑制规则的含义是:同一 namespace 下已经有 critical 告警时,warning/info 级别的告警被抑制,避免"数据库挂了"和"数据库延迟升高"两块告警同时轰炸值班群。抑制关系要按服务依赖来建,而服务依赖图正是可以让 AI 起草、再由人审的一种变更。 这一节之后,AI 的建议才有确定的落点。
#2.4 喂给 AI 之前的数据门禁:过滤、采样、脱敏
数据底座的最后一道工序是门禁,它直接决定 AI 输出的可信度。
- 过滤:只保留与目标问题相关的层级。比如只取 error/warn 级别、只取目标服务;
- 采样:全量喂给模型成本高、且会稀释注意力。先抽样,比如取每个类别的前 N 条代表样本;
- 脱敏:日志里常见 token、内网地址、用户信息。以下 sed 示例(macOS/Linux 均可用)把疑似密钥和内网 IP 替换掉后再继续处理:
sed -E \
-e 's/(sk-[A-Za-z0-9_-]{8,})/<REDACTED_TOKEN>/g' \
-e 's/([0-9]{1,3}\.){3}[0-9]{1,3}/<REDACTED_IP>/g' \
app.log > app.sanitized.log
# 采样:只取前 200 行作为分析样本
head -200 app.sanitized.log > app.sample.log门禁原则再强调一遍:模型不该看到它不需要看到的字段。 这既是质量要求,也是合规红线——原文明确说,别图省事用公共 API 处理内网日志。
#三、操作层(二):AI 辅助决策的场景与可复现示例
数据底座立起来之后,AI 才可以进入"判断"环节。下面按原文覆盖的领域给出可落地的命令与 prompt 示例。所有 prompt 都以 ~~~text 给出,可以直接复制使用;命令以本文约定的环境为准。
#3.1 日志分析:异常聚类与时间线重建
日志分析是 AI 收益最高的场景之一,因为它的输入天然是文本、输出天然是归纳。操作模式是:先过滤采样脱敏,再给模型喂"数据 + 任务 + 约束"。
示例 prompt(异常聚类):
你是 SRE 值班助手。下面是 order 服务最近 30 分钟的 ERROR 日志,已脱敏、已按时间排序(每行:ts level service msg)。
任务:
1. 把日志聚类成不超过 5 类,每类给出:2 条代表样本、可能根因、下一步验证命令;
2. 标出你认为最可能影响线上用户的一类;
3. 只使用日志中出现的字段,禁止编造日志中没有的指标名或配置参数。
日志如下:
[粘贴 app.sample.log 的内容]故障后的时间线重建则要求数据本身带可靠时间戳,这正是 2.2 里强调"对齐时间、打标签"的原因。把多个组件的日志按时间对齐后丢给模型,让它还原"先发生什么、后发生什么、哪个是因哪个是果"。时间线重建对值班的价值在于:它把"几万行错误"压缩成"一段可读的故事",人只需要验证故事的关键节点。
#3.2 指标查询:PromQL / LogQL 生成
用自然语言生成 PromQL 和 LogQL 是最高频的功能。关键前提是 prompt 里写清指标名和标签,否则模型只能猜——这正是 2.1 里"标签统一"的直接回报。
示例 prompt(生成 PromQL):
环境:Prometheus,指标 http_requests_total 的标签有 code、method、namespace、service。
请生成 PromQL:统计过去 1 小时 5xx 占比超过 1% 的服务,按 namespace、service 聚合输出。
要求:使用 rate() 与 sum by();只输出 PromQL 表达式,不要解释。对应可直接在 Prometheus 里运行的表达式:
sum by (namespace, service) (
rate(http_requests_total{code=~"5.."}[1h])
) / sum by (namespace, service) (
rate(http_requests_total[1h])
) > 0.01验证方式很简单:在 Prometheus 的 Graph 页面切换到 Table 视图,看是否有行返回、行数与预期服务数是否一致。PromQL 写错没关系,因为它在系统里立刻可验证——这正是"概率性输出 + 确定性校验"的标准形态。
LogQL 同样可用自然语言生成,逻辑与 PromQL 类似(以下按 Loki 2.x 语法):
sum by (namespace) (
count_over_time({namespace="prod"} |= "ERROR" [5m])
)#3.3 告警:规则审阅、降噪与上下文聚合
告警环节 AI 能干三件事,对应原文的三条:
第一,规则审阅。 把现有告警规则贴给模型,让它指出:阈值是否合理、关键路径是否覆盖、节点重启时会不会产生风暴。prompt 示例:
下面是 Prometheus 告警规则(贴上 rules/*.yml 内容)。环境:Kubernetes 1.29,30 个节点,约 200 个服务。
请审查:
1. 每个阈值是否合理(结合告警规模);
2. 有没有覆盖关键路径(可用性、容量、数据面);
3. 哪些规则在节点重启/滚动发布时会触发告警风暴,给出改进建议。
输出格式:规则名 → 问题 → 建议。只引用规则中存在的字段。第二,降噪。 把告警列表和已知的服务依赖关系给模型,让它建议父子告警的抑制规则,人审定后落到 Alertmanager 的 inhibit_rules(如 2.3 所示)。重点提示:抑制规则宁少勿多,抑制错了会真的吞掉故障信号。
第三,触发后的上下文聚合。 这是最能缩短 MTTR(平均修复时间,Mean Time To Repair)的一项——值班的人最耗时间的不是分析,是找信息。做法是写一个固定脚本,告警触发时自动把相关事件、最近变更、相关日志拉到一个文件,再把这个文件喂给模型做诊断初稿。脚本示例:
#!/usr/bin/env bash
set -euo pipefail
NS="${1:?usage: $0 <namespace> <app>}"
APP="$2"
OUT=/tmp/alert-context-$(date +%s).txt
{
echo "== 最近事件 =="
kubectl get events -n "$NS" --sort-by=.lastTimestamp | tail -30
echo "== 最近 GitOps 变更(24 小时内)=="
git -C /srv/gitops log --since="24 hours ago" --oneline --deploy/ | head -20
echo "== 最近 ERROR 日志 =="
kubectl logs -n "$NS" deploy/"$APP" --since=30m --tail=300 2>/dev/null \
| grep -iE 'error|timeout|refused' | head -80
} > "$OUT"
cat "$OUT"
# 把 $OUT 的内容贴给模型,让它输出诊断初稿注意 /srv/gitops 是示例路径,替换为你实际的 GitOps 仓库位置。这一步的价值在于:信息收集变成固定动作,模型只负责在完整上下文上做判断,而不是在残缺信息上猜。
#3.4 故障定位:Kubernetes 排错
K8s 排错的难点不是知识,是信息分散。标准做法是先把信息收齐,再一起喂给模型。以下命令组(把 <ns>、<pod>、<node> 替换为实际取值):
kubectl get pod -n <ns> -o wide
kubectl describe pod <pod> -n <ns>
kubectl logs <pod> -n <ns> --previous
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -30
kubectl describe node <node> | grep -A5 Allocated然后把输出贴进下面的 prompt:
环境:Kubernetes 1.29,命名空间 prod,Deployment order 的 Pod 处于 Pending 状态。
以下是排错信息(命令输出原样贴入):
[贴 kubectl get pod -o wide 输出]
[贴 kubectl describe pod 输出]
[贴 kubectl get events 最近 30 条]
请按"现象 → 可能原因(按概率降序)→ 每条对应的验证命令"输出。
约束:只能使用上面信息里出现的字段与对象,不要编造不存在的告警或指标名。常见场景(Pending 的调度原因在 events 里、CrashLoopBackOff、OOMKilled、ImagePullBackOff、PVC 绑定失败、DNS 解析不通、NetworkPolicy 拦截),模型通常都处理得不错,因为这类问题在社区里已经被反复讨论,训练数据充足。
但有一个明确的适用边界:etcd 慢、apiserver 限流、CNI 数据面异常这类控制面问题,模型给出的结论普遍偏浅,动不动就是"检查网络""重启 kubelet"。这类问题的判断依赖排障者自己的指标数据(etcd 的 fsync 延迟、apiserver 的 APF 队列深度、节点上的 conntrack 表),属于"数据不全时模型只能给平均答案"的典型,必须回到 2.1 的指标采集自查。K8s 排错里模型是信息整理器,不是根因判别器。 控制面各组件的职责边界见 Kubernetes 核心组件详解与实战,应用侧的完整部署链路见 一个 jar 包部署到 k8s 上的全流程。
#3.5 硬件层:服务器、网络、显卡、内存
硬件场景的共性是:工具输出反人类、行数多、重复性高,正好是 AI 擅长压缩的信息类型。更完整的机房故障场景(磁盘、慢盘、多路径、超融合、网络与 SDN)见 机房故障处置手册。
巡检信息一次收齐(以下命令在目标服务器上执行):
lspci -nn | grep -Ei 'nvidia|ethernet|infiniband|raid|nvme'
dmidecode -t system -t memory -t processor | head -100
ipmitool sel elist | tail -50
ipmitool sensor list | grep -Ei 'temp|fan|psu|power'
numactl --hardware把输出贴给模型,让它做四件事:SEL 日志归类(几百行里哪些是真故障、哪些是插拔和重启产生的噪音)、故障预测(SMART 属性、EDAC 的 CE/UE 计数、MCE 日志的趋势,指出哪块盘、哪条内存该重点关注)、RAID 状态解读(storcli/perccli 的输出翻译成"几号盘、什么状态、重建进度、下一步动作")、验收清单生成(上架、扩容、换件之后的检查项)。
RAID 解读示例命令(需要服务器配置了 Broadcom MegaRAID 阵列卡并安装 storcli):
storcli /c0 show
storcli /c0/eall/sall show all | grep -Ei 'State|Size|S.M.A.R.T'SMART 与 EDAC 趋势检查:
smartctl -a /dev/nvme0n1
smartctl -l selftest /dev/sda
grep -H . /sys/devices/system/edac/mc/mc*/ce_count 2>/dev/nullGPU 与算力是运维新增的大头。Xid 错误的定位(原文场景):
dmesg -T | grep -i 'NVRM: Xid' | tail -20
nvidia-smi topo -m
nvidia-smi dmon -c 10
dcgmi diag # 需要已安装 NVIDIA DCGM示例 prompt:
dmesg 中出现:NVRM: Xid (PCI:0000:3b:00.0): 79, pid=..., GPU has fallen off the bus
环境:NVIDIA H200,驱动 550.xx,CUDA 12.4,单节点 8 卡,训练任务使用 NCCL 通信。
请给出:
1. Xid 79 的常见原因排序;
2. 按顺序给出排查命令;
3. 什么情况下应 reset GPU、什么情况下应 RMA。
约束:命令限于 Linux 常见工具,不要编造厂商私有参数。性能瓶颈定位则把 nvidia-smi topo -m、dcgmi diag、nvidia-smi dmon 的输出一起贴给模型,让它结合 NVLink 拓扑、PCIe 代际与宽度、NUMA 亲和性判断跨卡访问是不是瓶颈;多机训练的通信问题(NCCL 报错、IB/RoCE 的 PFC/ECN 配置、链路速率协商不上)让它核对配置一致性。这里的判断要自己复核——GPU 拓扑的结论必须和 nvidia-smi topo -m 的实际输出对得上。
内存分析要同时看内核、cgroup、应用运行时三层:
dmesg -T | grep -i 'Out of memory' | tail -20
cat /sys/fs/cgroup/memory.events
kubectl get pod -n <ns> | grep -i oom
# 连续采样内存趋势:间隔 10 分钟跑两次,对比增长
cat /proc/meminfo
numastat把输出贴给模型,让它判断到底是宿主 OOM 还是 cgroup limit 触发、谁先被杀;泄漏判断则让它看 slab、PageTables、anon、file cache 哪一块在长(配合 numastat、/proc/meminfo 多次采样);运行时的 JVM GC 日志、Go 的 pprof、Python 内存增长,让它给排查路径和参数建议。
内存场景的明确坑:模型给的运行时参数数值(堆大小、GOGC、max-old-space-size)经常是"合理但不适合你"的,必须结合自己的实际负载再确认一遍。这就是"数据不足时模型输出平均答案"的实例——它不知道你的流量模型,只能给通用区间。
#3.6 配置变更前的差异分析(网络)
这是原文里"性价比最高"的用法之一:把变更前后两份配置 diff 加上一句意图描述,让模型找会不会误伤。
示例 prompt(对应原文场景"放行 10.20.0.0/16 到数据库段的 5432"):
变更意图:在防火墙 A 上新增一条规则,放行源 10.20.0.0/16 到数据库段 10.30.0.0/24 的 TCP 5432。
厂商:H3C;型号:S6850;软件版本:V7 示例(以你的实际型号版本为准)。
下面是变更前后的规则集,按生效顺序排列。
请审查:
1. 新规则是否被更早的规则遮蔽(shadowing),或遮蔽了更晚的规则;
2. 除意图流量外,是否意外放行其他源/目的;
3. 与既有 ACL 是否有重复或冲突。
输出时标注规则行号,只引用给出的行。网络故障定位的思路可以这样固化:把 mtr、traceroute、tcpdump 结果、交换机端口计数、丢包位置喂给模型,让它给出下一步该查什么。
mtr -rw -c 20 <target-ip>
traceroute -n <target-ip>
tcpdump -i eth0 host <target-ip> -c 100 -w /tmp/cap.pcap网络的坑写在前面:厂商私有 CLI 差异太大。H3C、华为、锐捷、Cisco 的语法经常被混着用,模型一本正经地给你一段混合了四家语法的配置是常态。所以 prompt 里必须锁死厂商、型号、软件版本,最好直接贴一份现网配置当 style 参考(即"few-shot")。差异分析这种用法相对安全,因为输出的是审查意见;但配置起草这类输出,必须走评审并且逐条和厂商手册核对。
#3.7 资源分配:requests/limits 建议
请求建议必须基于历史用量,而不是拍脑袋。方法:先用 PromQL 算历史分位数值,再按"先给 p95 requests,limits 放宽 1.5 到 2 倍"这类规则批量生成,最后人工过一遍。
基于 cAdvisor/kubelet 指标的 p95 CPU 用量(7 天窗口):
histogram_quantile(0.95,
sum by (le, namespace, pod) (
rate(container_cpu_usage_seconds_total{namespace="prod"}[7d])
)
)把查询结果(每个 pod 的 p95 值)喂给模型,让它批量生成 requests/limits 的 diff 草案,再交给人工评审。这里模型做的是重复性计算和格式生成,决策依据(p95、1.5–2 倍、安全边界)都在 prompt 里写死 —— 决策规则是人定的,模型只负责执行翻译。
#3.8 应用构建与 CI/CD
构建场景里 AI 的收益集中在两类:格式优化和"找第一个错误"。
Dockerfile 优化,把现有 Dockerfile 丢给它改,多阶段构建、层缓存顺序、镜像瘦身、非 root 用户、.dockerignore。一个多阶段构建的通用形态示例(以 Go 应用为例):
FROM golang:1.22 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/svc ./cmd/svc
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /app/svc /app/svc
ENTRYPOINT ["/app/svc"]gcr.io/distroless/static-debian12:nonroot 标签默认以非 root 运行,对应"非 root 用户"的要求。
构建失败定位:编译日志动辄几千行,真正的第一个错误可能埋在第 200 行。让模型找"第一个真正的错误"而不是最后一条报错,它做得比人快很多。也可以先用命令粗筛:
# 看第一条真正报错(而不是最后一条)
grep -n -m1 -Ei '(^|:) (error|fatal):' build.log
# 或看前 5 个报错行
grep -n -Ei '(error|fatal):' build.log | head -5流水线与仓库工程:GitHub Actions、GitLab CI、Jenkins、Argo Workflows 的 YAML 起草与优化(缓存策略、并发控制、矩阵构建、构建机资源分配);把近期流水线失败归类为代码问题、环境问题、flaky test、资源不足——分类清楚之后才知道该修什么;把 PR diff 和受影响的模块列表给模型,让它列影响面和回滚点作为评审参考;从 commit 记录生成 release note 和 changelog,人工润色。最后这一个是原文里"最省心"的活:
git log --oneline --no-merges v1.2.0..v1.3.0#3.9 反过来:AI 自身的部署与算力
这是运维这两年新增的活,而且量不小。推理服务部署(vLLM、SGLang、TensorRT-LLM、TGI)各有各的参数体系。以下以 vLLM 为例(需要 vLLM 0.6+、两张 GPU、模型权重可访问;示例模型名 meta-llama/Llama-3.1-8B-Instruct 请替换为你实际有权访问的模型):
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--tensor-parallel-size 2 \
--max-model-len 8192 \
--max-num-seqs 64 \
--gpu-memory-utilization 0.9 \
--enable-prefix-cachingmax-num-seqs、gpu-memory-utilization、max-model-len、tensor-parallel-size、enable-prefix-caching 这些参数相互影响:取决于模型大小、卡数、显存和预期并发。让模型解释参数含义和相互影响是可以的,但最终值必须压测出来,这是硬规矩。
启动后用 OpenAI 兼容端点验证:
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"meta-llama/Llama-3.1-8B-Instruct","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'压测时用 curl 的计时变量做初步观测(time_starttransfer 近似 TTFT,真正精确的 TTFT 要看服务端指标):
curl -s -o /dev/null -w 'ttfb=%{time_starttransfer}s total=%{time_total}s\n' \
http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"meta-llama/Llama-3.1-8B-Instruct","messages":[{"role":"user","content":"ping"}],"max_tokens":1}'K8s 编排上的要点(原文列出的决策面):GPU 调度靠 device plugin、节点标签与污点、GPU 共享策略;权重管理在 PVC、对象存储、还是直接打进镜像之间取舍(几十 GB 的镜像,拉一次想死);服务编排用 Deployment 还是 LeaderWorkerSet/Job 取决于多机推理的 pod 拓扑;弹性按队列长度扩缩容时,冷启动动辄几分钟,扩容策略要提前考虑。
算力切分选型:MIG 适合隔离要求高、模型小的场景;time-slicing 适合开发测试环境多任务共享;MPS 介于两者之间。选错了要么浪费显存,要么任务互相拖慢。多机并行策略(TP、PP、EP)怎么选,取决于模型结构、卡间互联(NVLink 还是跨机 IB)和 batch 形态,让模型给初稿、实测校准。
网关与配额(限流、按团队配额、Token 计费、多模型路由、灰度)通常用 AI Gateway 类产品,但规则还是得自己定。
监控要看对指标:GPU utilization 是个很骗人的数字——显存占满了但计算单元空转,利用率照样显示很高。真正该看的是显存占用、等待队列长度、TTFT、TPOT、输出 token 吞吐、以及 KV cache 命中率。
私有化与数据安全:Embedding 服务、向量库、RAG(检索增强生成,Retrieval-Augmented Generation)链路、模型权重和数据的访问控制,这是合规红线,别图省事用公共 API 处理内网日志。
#3.10 渐进落地路径:四阶段
从决策路径推导出的落地顺序是确定的——先走只读(概率性判断、低风险),再起草(概率性输出 + 评审),再受限自动执行(确定性校验包裹),最后闭环。原文的四阶段如下:
阶段一(一到两周):只读。 只接日志、配置、监控数据,只做分析和解释,不给任何写权限。这一阶段的目标是让团队建立"哪些问题问它有用"的直觉。
阶段二:起草。 让它产出 diff、YAML、脚本,走现有评审流程。这一阶段要统计采纳率——如果采纳率低于一半,说明 prompt 或者场景选错了,别急着往下走。
阶段三:受限自动执行。 选三五个低风险动作,白名单 + 审批 + 完整审计日志。每自动执行一次都要能事后复盘。可执行动作只限幂等、可回滚、影响面可控的一类:调整副本数、重启某个无状态 Deployment、清理过期镜像。
阶段四:闭环。 告警触发后自动收集上下文、生成诊断、给出处置建议,部分场景自动恢复(即 3.3 的上下文聚合脚本 + 受限执行的白名单)。
每一阶段都要保证:可回滚、有审计、人能随时接管。跳步骤直接上自动执行的团队,基本都吃过亏。
#四、验证层:怎么确认"做对了"
AI 环节最容易犯的错是把"模型说了"当成"做对了"。验证分三层:命令级、配置级、效果级。
#4.1 命令级验证:AI 给的每条命令先本地校验
- PromQL/LogQL:直接在 Prometheus Graph / LogQL web UI 里跑,看有没有返回、行数是否符合预期;
- Kubernetes YAML:先 dry-run 和 diff,再谈 apply:
kubectl apply --dry-run=client -f deployment.yaml -o yaml
kubectl diff -f deployment.yaml- Helm 渲染与差异(
helm diff需要 helm-diff 插件):
helm template <release> <chart> -n prod --values values-prod.yaml > /tmp/rendered.yaml
helm diff upgrade <release> <chart> -n prod --values values-prod.yaml- 配置合法性一律用官方校验器:
promtool check config prometheus.yml、promtool check rules rules/*.yml。
#4.2 配置级验证:交叉验证与文档溯源
- 固件与驱动版本矩阵:模型给的服务器型号、BIOS、BMC、NIC 固件、驱动、CUDA 版本之间的兼容关系只能当初稿,必须拿厂商兼容列表交叉验证——它经常把不同代际的参数混在一起,说得还很确定;
- 字段溯源:模型给出的指标名、CRD 字段、配置参数,如果在官方文档里查不到,那就是编造的。查不到的字段一律不用;
- 现网 style 参考:它起草的配置要和现网同类配置逐行对比,语法、缩进、版本必须一致。
#4.3 效果级验证:用量化指标判断是否值得
- 采纳率:阶段二必须统计。示例统计脚本(adoption.csv 每行是"时间,结果",1 表示采纳、0 表示否决):
awk -F, '$2==1{a++} END{printf "采纳率 %d%%(%d/%d)\n", 100*a/NR, a, NR}' adoption.csv- MTTR:对比接入 AI 前后,从告警触发到恢复的平均时长。重点看"信息收集耗时"是否下降,因为那是原文判断多数团队最耗时的环节;
- 推理服务参数:
max-num-seqs、gpu-memory-utilization等最终值必须跑压测,用 TTFT、TPOT、输出吞吐、显存占用判定,不能凭模型建议直接上线。
#4.4 验证层的判定标准
一句话:每条从 AI 来的命令、配置、参数,都能在你自己的系统里被复验,且复验通过后才算"做对了"。 任何一步复验不过,都按"模型输出不可用"处理,而不是"人肉补一句再放行"。
#五、边界与坑:幻觉、数据不足、误报
最后列几个真实踩过的坑,每一条都能在原理层找到原因。
幻觉。 编造参数名、编造指标名、编造 CRD 字段。它给的字段在文档里查不到,那就是编的。这个坑的根源是概率性判断的特性:模型在填充概率最高的 token,而不是在查数据库。防护手段就是 4.2 的字段溯源——所有关键字段必须有文档依据。
数据不足。 样本太少时,模型只会给通用答案:运行时参数"合理但不适合你"、控制面问题"检查网络/重启 kubelet"。这不是模型笨,是输入缺少你的环境信息。对策是把版本号、拓扑、历史用量写进 prompt,给它尽量完整的上下文。
误报。 告警降噪做过头会吞掉故障信号,做少了又回到告警风暴。抑制规则(inhibit_rules)宁少勿多,且必须按真实依赖关系建。同样,模型建议的缩容一定要留安全边界:按平均值压到极限,平时没事,流量一冲就雪崩,至少留出一倍余量。
上下文污染。 长对话里前面一个错误结论会被反复引用强化。重要问题开新会话,别怕麻烦。
版本漂移。 它不知道你线上跑的是什么版本。每次都把版本号写进 prompt("Kubernetes 1.29""Prometheus 2.x""驱动 550.xx"),描述越具体,越不容易给你不同代际混用的参数。
权限蔓延。 一开始只读,后来图省事给了写权限,再后来就是事故。权限要收,不要放。
数据外泄。 日志里有 token、内网地址、用户信息。要么私有化部署,要么先脱敏(2.4 的命令)。这是合规红线,不是效率问题。
成本失控。 让它跑全量日志,账单会教你做人。先过滤、采样、脱敏再喂,控制输入量。
技能退化。 新人不再读文档,只会问 AI,遇到它没见过的问题就完全没思路。这个比技术风险更长期,团队要有意识地保留"读文档、读源码、看指标"的能力。
最危险的是"看起来对"的答案。 一眼假的东西你会去查,看起来合理的你会直接用。运维场景里幻觉的代价不是"答错了",是"改炸了"。对所有看起来合理的输出,默认先怀疑,再验证。
#六、收尾:从最耗时的环节开始
别一上来就搞平台、搞 Agent、搞自动化闭环。先找你日常最耗时的那个环节——多数团队是"故障发生时的信息收集"和"配置变更前的检查"——把 AI 接进去,用两周,量一下是不是真的省了时间(采纳率、MTTR 都是可以量化的指标)。省了再往下走,没省就换个场景试。
先立可观测性,再谈 AI;AI 负责把"找信息、想原因"的成本打下来,规则负责保证"动生产"的安全性。工具是要算投入产出的,AI 也一样。
#延伸阅读
- 机房故障处置手册:从磁盘到 SDN 控制器的根因、预防与规章 —— 硬件与网络场景的 SOP,以及 AI 只读助手的边界。
- 一个 jar 包部署到 k8s 上的全流程 —— 部署链路、探针与回滚,正好是 AI 起草变更时的上下文来源。
- Kubernetes 核心组件详解与实战 —— 控制面与 kubelet 的机制,决定模型结论能不能落地。
- Argo CD 实战:用 GitOps 把 CI/CD 部署搬进 Kubernetes —— 变更走 Git、可审计、可回滚的完整实现。
相关阅读
Related留言讨论
0 条还没有留言,来说点什么吧。