学习目标
学完本章你应该能够:
- 讲清软件交付从「瀑布 → 精益 → 敏捷 → DevOps → SRE → AIOps」的演进脉络,以及每一阶段解决的核心矛盾。
- 画出一条真实 DevOps 流水线的阶段(Plan/Code/Build/Test/Scan/Deploy/Verify/Monitor/Feedback),并说清 Jenkins、GitLab CI、ArgoCD 的定位差异。
- 用自己的话区分 SLI / SLO / 错误预算,并能算出一个具体服务的月度错误预算消耗。
- 讲清 AIOps 如何用 LLM 做 NL→PromQL、日志摘要、RAG 知识库与决策 Agent,以及「人在环里」的必要性。
- 说清 Terraform 与 Crossplane 的核心工作流与选型取舍,以及 state 漂移、force-unlock 等高频坑。
前置知识:用过 Git 和至少一种 CI 工具;知道 Docker / Kubernetes 的基本概念;对 Prometheus 指标有耳闻即可。
本章你会动手做的事:
- 用 Sloth 的 YAML 生成一份 Prometheus SLO recording rule,并跑通
sloth generate。 - 把你项目的一条 Prometheus 查询改写成「NL 问题 → PromQL」的 prompt 模板。
- 写一份最小
main.tf用terraform plan预览一个 EKS 集群的变更(不真 apply)。
从精益、敏捷到 DevOps 的发展脉络
软件交付模式的演进,本质上是企业为了更快、更稳地响应市场变化而不断探索的过程。早期瀑布模型强调阶段清晰,但反馈周期长、变更成本高。随后精益(Lean)思想被引入软件开发,核心是消除浪费、持续流动;敏捷(Agile)则进一步强调小步快跑、拥抱变化,通过迭代和增量交付缩短反馈环。
类比:瀑布模型像「盖楼前先画完整图纸、封顶才能入住」,改需求等于拆墙重建;敏捷像「先搭毛坯、每两周住进去体验一轮再改」,反馈快但得接受边住边装修。DevOps 则是把「盖楼的设计师」和「入住后的物业」合并成一个团队——你设计的楼,你自己负责它别塌。
DevOps 在敏捷基础上,将开发(Dev)与运维(Ops)之间的壁垒打通,倡导" you build it, you run it “的文化。它不只是工具链的整合,更是组织流程、度量和协作方式的变革。典型的 DevOps 流水线包含:需求管理、代码提交、持续集成(CI)、持续交付(CD)、部署发布、运行监控、反馈改进。
说实话我第一次看 DevOps 流水线图的时候觉得就那么回事儿,等真上手搭过几次才发现,流水线本身就是公司工程文化的镜子——你团队怎么协作,流水线就长什么样。
flowchart LR
A[瀑布模型
阶段清晰/反馈慢] --> B[精益
消除浪费/持续流动]
B --> C[敏捷
小步快跑/拥抱变化]
C --> D[DevOps
打通 Dev 与 Ops]
D --> E[SRE
用软件工程做运维]
E --> F[AIOps
ML/LLM 智能决策]一条真实流水线长啥样
下面这条是我自己搭过、踩过坑、能跑起来的典型 Web 服务流水线,每个阶段我都标了对应的工具:
[Plan 需求] Jira / Linear / 飞书项目 ← 工程师拆卡,写 AC
↓
[Code 编码] Git + GitHub/GitLab ← feature 分支,commit message 关联 issue
↓
[Build 构建] Docker buildx + BuildKit ← 多阶段镜像构建,推 Harbor
↓
[Test 测试] pytest / go test + SonarQube ← 单测+覆盖率+静态扫描
↓
[Scan 安全] Trivy + Grype ← 扫镜像 CVE,扫 IaC 配置
↓
[Deploy 部署] ArgoCD GitOps ← 监听 manifest repo,自动 sync
↓
[Verify 验证] Prometheus + Blackbox Exporter ← 部署后 smoke test + SLO 检查
↓
[Monitor 监控] Grafana + Loki + Tempo ← 指标/日志/链路三件套
↓
[Feedback 反馈] 告警 → On-call → 复盘 → Jira ← 失败案例回灌成新的需求
flowchart LR
P[Plan] --> C[Code] --> B[Build] --> T[Test] --> S[Scan]
S --> D[Deploy] --> V[Verify] --> M[Monitor] --> F[Feedback]
F -->|回灌新需求| PJenkins vs GitLab CI vs ArgoCD
这三个我都被坑过。简单说下区别,省得你选型时再走一遍:
| 工具 | 定位 | 优点 | 我踩过的坑 |
|---|---|---|---|
| Jenkins | 老牌 CI/CD 引擎 | 插件多,啥都能干 | Jenkinsfile 一长就乱,master 节点一挂全员瘫痪 |
| GitLab CI | GitLab 内置 CI | .gitlab-ci.yml 跟代码一起走 | shared runner 排队能等到天荒地老,得自己搭 runner |
| ArgoCD | GitOps CD 控制器 | 声明式、UI 直观、K8s 原生 | 不是 CI,只管 CD;manifest repo 与代码 repo 解耦后维护成本上升 |
我个人觉得小团队 GitLab CI 一把梭就够了,CI 和 CD 都能用。规模上来或者要搞 GitOps 就上 ArgoCD,CI 还保留 GitLab CI / GitHub Actions。Jenkins 我现在基本不主动选了,维护成本太高。
下面给一段 GitLab CI 的最小可用配置,CI 阶段构建并推送镜像,CD 阶段更新 manifest repo 触发 ArgoCD:
# .gitlab-ci.yml —— 应用代码 repo 里的配置
stages:
- build
- test
- publish
- deploy
variables:
IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA # 用 commit 短 SHA 做镜像 tag,可追溯
# 构建阶段:用 BuildKit 跑多阶段构建
build:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker buildx build -t $IMAGE --push .
only:
- main
# 测试阶段:Go 单测 + 覆盖率
test:
stage: test
image: golang:1.22
script:
- go test -race -coverprofile=coverage.out ./...
- go tool cover -func=coverage.out
only:
- main
# 部署阶段:更新 manifest repo 里的镜像 tag,ArgoCD 监听到变化自动 sync
deploy:
stage: deploy
image: alpine/git
script:
- git clone https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/team/manifests.git
- cd manifests
- sed -i "s|image:.*|image: $IMAGE|" apps/myapp/deployment.yaml
- git commit -am "chore(myapp): bump to $CI_COMMIT_SHORT_SHA"
- git push
only:
- main
注意 sed 替换镜像 tag 这种写法很糙,生产里我会用 yq 或者 Kustomize 的 images 字段来改,避免误伤其它行。
SRE 与 AIOps 核心概念
SRE(Site Reliability Engineering) 由 Google 提出,主张用软件工程方法解决运维问题。其关键实践包括:
- SLO/SLI/SLA:用可量化的服务等级目标(SLO)、指标(SLI)和协议(SLA)来管理可靠性。
- 错误预算:允许在一定范围内发生故障,从而平衡创新速度与稳定性。
- Toil 管理:将重复性手工操作自动化,降低运维负担。
- 混沌工程:通过受控故障注入验证系统韧性。
AIOps(Artificial Intelligence for IT Operations) 则是将人工智能,尤其是机器学习和大模型技术,应用于运维数据的分析、决策与自动化执行。Gartner 将 AIOps 定义为结合大数据与机器学习,支持 IT 运维全过程的平台能力。
SLI / SLO / 错误预算:到底怎么算
说实话这三个词刚看的时候很容易混。我后来用一句话记:SLI 是你量的数据,SLO 是你承诺的目标,错误预算是 1 减 SLO 剩下那点 “允许坏掉” 的额度。
flowchart LR
SLI[SLI
你量的数据
成功率] --> SLO[SLO
你承诺的目标
≥99.9%]
SLO --> BUD[错误预算
1 - SLO
=0.1% 允许坏掉]
BUD -->|烧光| FREEZE[冻结新功能
全员修稳定性]举个具体数字例子。一个 HTTP API 服务:
- SLI:成功率 =
1 - http_requests_total{code=~"5.."} / http_requests_total - SLO:30 天内成功率 ≥ 99.9%
- 错误预算:1 - 99.9% = 0.1%
如果月请求量是 1 亿次,那这个月的错误预算就是 10 万次 5xx。一旦 5xx 超过 10 万次,错误预算烧光,新功能上线就得冻结,全员修稳定性。
错误预算的消耗速度比你想的快。我有一次凌晨 Pod OOM 重启了 5 分钟,429 + 500 加起来烧掉了一个月预算的 30%,第二天 SRE 群就炸了。
Sloth 自动生成 SLO 规则
手写 Prometheus SLO 规则巨痛苦,几百行 recording rule 一不小心就写错。我后来直接上 Sloth,它用一份简洁的 YAML 自动生成符合 Prometheus 最佳实践的 recording rule 和 alert rule。
# sloth.yaml —— Sloth 的 SLO 声明
version: "prometheus/v1"
service: "api-gateway"
labels:
owner: "team-platform"
slos:
- name: "requests-availability"
objective: 99.9 # 99.9% 成功率
description: "API 网关 5xx 比例 SLO"
sli:
events:
error_query: sum(rate(http_requests_total{job="api-gateway",code=~"5.."}[{{.window}}]))
total_query: sum(rate(http_requests_total{job="api-gateway"}[{{.window}}]))
alerting:
name: ApiGatewayAvailabilityBurnRate
labels:
category: availability
annotations:
summary: "API 网关可用性错误预算消耗过快"
page_alert:
labels:
severity: pageteam
ticket_alert:
labels:
severity: slack
然后用一条命令生成最终的 Prometheus rule:
sloth generate -i sloth.yaml -o prometheus-slo-rules.yaml
生成的 YAML 里会自动包含 5m/30m/1h/2h/6h/1d 等多个窗口的 multi-window multi-burn-rate 告警规则,比手写靠谱太多。这里有个坑:Sloth 的 error_query 和 total_query 里的 {{.window}} 占位符必须保留,它生成时会替换成各个窗口长度,别手贱去改成固定时间。
如果不想引入新工具,纯 Prometheus recording rule 也能写,长这样:
# prometheus-slo-rules.yaml —— 纯手写版(精简)
groups:
- name: slo-requests-availability
rules:
# 5 分钟窗口的 SLO 完成度
- record: slo:sli_error:ratio_rate5m
expr: |
sum(rate(http_requests_total{job="api-gateway",code=~"5.."}[5m]))
/
sum(rate(http_requests_total{job="api-gateway"}[5m]))
# 错误预算消耗速率
- record: slo:error_budget:burn_rate5m
expr: slo:sli_error:ratio_rate5m / (1 - 0.999)
# 告警:5 分钟 burn rate > 14.4 倍(约 2% 预算/小时)
- alert: SLOBurnRateHigh
expr: slo:error_budget:burn_rate5m > 14.4
for: 2m
labels:
severity: pageteam
annotations:
summary: "SLO 错误预算消耗速率过高"
Toil 自动化的真实例子
Toil 这个词很 Google,落到日常其实就是那堆"手动又不创造价值"的事。我列几个我亲手干过、后来全部自动化掉的活儿:
- 证书续期:Let’s Encrypt 证书 90 天到期,每次手动
acme.sh --issue。后来上 cert-manager,CRD 一声明,自动续期,再也忘不了。 - 磁盘清理:日志盘 80% 告警,登机器
rm -rf /var/log/*.gz。后来写了个 CronJob 跑 logrotate + 上传 OSS,告警基本消失。 - 扩容缩容:大促前手动 kubectl scale。HPA + Cluster Autoscaler 配好之后,按 QPS 自动扩,准确率比人手判断高。
- 值班交接:每次发周报手动整理本周告警。后来 Alertmanager 推到 Alertmanager → n8n → 飞书表格,自动出周报。
下面这段 cert-manager 的 Certificate CR 我贴出来,因为这个是我觉得 ROI 最高的 toil 自动化案例:
# certificate.yaml —— Let's Encrypt 自动签发
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-gateway-tls
namespace: prod
spec:
secretName: api-gateway-tls # 证书会写到这个 Secret 里
duration: 2160h # 90 天
renewBefore: 360h # 提前 15 天续期,留足失败重试时间
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- api.example.com
踩坑提示:renewBefore 别设太短。我设过 24h,结果续期当天 Let’s Encrypt 限流了,证书没续上,第二天直接过期。15 天才是稳妥值。
大模型与 AIOps 的结合关系
大语言模型(LLM)为 AIOps 带来了新的交互与决策能力:
- 自然语言接口:运维人员可以用自然语言查询指标、生成查询语句(如 PromQL、SQL)。
- 日志/事件摘要:LLM 可对海量日志进行聚类、摘要和根因解释。
- 知识沉淀与推理:将 SOP、故障报告、架构文档作为知识库,LLM 可基于 RAG(检索增强生成)进行推理。
- 决策 Agent:通过 Function Calling 调用运维 API,实现自动扩容、重启、回滚等动作。
自然语言查 PromQL 的 Prompt 示例
这是我线上在用的一个 prompt 模板,专门做 NL → PromQL。注意我把指标元数据塞进了 system prompt,不塞的话模型会瞎编指标名,比如把 http_requests_total 写成 http_request_count。
你是一名资深 SRE,擅长编写 Prometheus PromQL 查询语句。
# 可用指标清单(严格遵守,禁止臆造指标名)
- http_requests_total{job, method, code, path}
- http_request_duration_seconds_bucket{job, le}
- container_cpu_usage_seconds_total{pod, namespace}
- container_memory_working_set_bytes{pod, namespace}
- kube_pod_status_phase{namespace, phase}
- node_cpu_seconds_total{node, mode}
# 用户问题
{user_question}
# 输出要求
1. 只输出一条 PromQL 语句,不要解释
2. 涉及速率统一用 rate(),区间用 [5m]
3. 直方图分位数用 histogram_quantile(0.95, sum by (le)(rate(...[5m])))
4. 如果用户问题涉及不存在的指标,直接回复 "UNSUPPORTED"
举几个真实的 NL → PromQL 例子:
| 用户问题 | 期望 PromQL |
|---|---|
| api-gateway 最近的 5xx 比例 | sum(rate(http_requests_total{job="api-gateway",code=~"5.."}[5m])) / sum(rate(http_requests_total{job="api-gateway"}[5m])) |
| prod 命名空间 CPU 使用率 P95 | histogram_quantile(0.95, sum by (le)(rate(container_cpu_usage_seconds_total{namespace="prod"}[5m]))) |
| 哪个节点的 idle CPU 最高 | topk(1, sum by (node)(rate(node_cpu_seconds_total{mode="idle"}[5m]))) |
踩坑提示:千万别让 LLM 直接执行生成的 PromQL。我有次让它执行 rate(metric[5m]),它把 [5m] 改成 [5d],结果 Prometheus 直接 OOM 了——30 天的高基数指标一拉直接爆内存。正确做法是 LLM 生成 → 校验白名单 → 人在环里点确认 → 才发到 Prometheus。
RAG 故障知识库架构(文字版)
RAG 这块我画过一版文字架构图,大概长这样:
┌─────────────────────────────┐
运维同学 │ 前端:飞书机器人 / Web UI │
"订单服务 500" └──────────────┬──────────────┘
│ 自然语言问题
▼
┌─────────────────────────────┐
│ Query Rewriting │
│ 把口语改成检索友好的关键词 │
└──────────────┬──────────────┘
│ 改写后的 query
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌────────────────────┐ ┌─────────────────────┐
│ Embedding Model │ │ 向量库 Milvus │ │ 关键词库 ES │
│ bge-large-zh │ │ Top-K 语义召回 │ │ BM25 召回 │
└──────────────────┘ └────────────────────┘ └─────────────────────┘
│ │ │
└──────────────────────┼──────────────────────┘
▼
┌──────────────────────────┐
│ Reranker(bge-reranker)│
│ 精排,取 Top 3 │
└──────────────┬───────────┘
▼
┌──────────────────────────┐
│ LLM 生成回答 │
│ 注入:召回文档 + 告警上下文 │
└──────────────┬───────────┘
│
▼
┌──────────────────────────┐
│ 输出:根因分析 + 处置步骤 │
│ + 引用来源链接 │
└──────────────────────────┘
flowchart TB
Q[自然语言问题] --> QR[Query Rewriting 改写]
QR --> E[Embedding + 向量库 Milvus 语义召回]
QR --> K[关键词库 ES BM25 召回]
E --> R[Reranker 精排 Top3]
K --> R
R --> L[LLM 生成回答
注入召回文档+告警上下文]
L --> O[根因分析 + 处置步骤 + 引用来源]知识源大概是这几类:历史故障复盘文档(Confluence)、SOP runbook(Git 仓库 markdown)、告警历史(Alertmanager webhook 落库)、代码注释(GitLab API 抓)。文档更新走 Airflow 定时任务,每天增量 reindex。
这里有个坑被同事吐槽过:召回的文档不能太长。一开始我把整篇复盘文档塞 prompt,结果 LLM 抓不到重点,回答巨长还没用。后来改成 chunk + reranker,每个 chunk 800 token 左右,rerank 后只给 Top 3,效果立刻好很多。
DevOps、SRE、AIOps 三者的区别与联系
| 维度 | DevOps | SRE | AIOps |
|---|---|---|---|
| 核心目标 | 加速交付、打通协作 | 保障可靠性、量化运营 | 智能分析、自动决策 |
| 关注阶段 | 开发到交付全流程 | 生产运行与可靠性 | 数据驱动的运维全链路 |
| 主要手段 | CI/CD、自动化、文化变革 | SLO、错误预算、自动化 | ML、LLM、可观测数据 |
| 关系 | 基础文化与流程框架 | 可靠性工程实践 | 智能化能力增强 |
三者并非替代关系。DevOps 提供协作框架,SRE 提供可靠性工程方法,AIOps 提供数据与智能决策能力,三者叠加才能构建现代化的运维体系。
我个人觉得小公司别一上来就想着 AIOps。先把 CI/CD 跑顺、SLO 量化起来,再考虑接 LLM。我们团队就是反过来,AIOps 调了一堆大模型 demo,结果 CI 还在手动跑,被领导一句话打回原形:连部署都不稳定,谈什么智能运维。
基础设施即代码(IaC)概述
IaC 是云原生交付的重要支柱,通过声明式配置管理基础设施,实现版本化、可回滚、可复现。主流工具包括:
- Terraform:HashiCorp 出品的声明式 IaC 工具,通过 Provider 对接多云资源,Module 实现模板复用。
- Crossplane:基于 Kubernetes CRD 的 IaC 方案,将云资源抽象为 K8s 资源,实现 GitOps 式的平台工程。
Terraform 的核心工作流为 write -> plan -> apply -> destroy,状态文件(state)是管理依赖与变更的关键。通过 workspace 或 workspace + backend 分离,可以实现多环境(dev/staging/prod)隔离。
Crossplane 则更进一步,将基础设施资源纳入 Kubernetes 控制平面,结合 Composition 和 Claim 机制,允许平台团队封装内部 PaaS,实现自服务能力。
Terraform 完整示例:建一个 EKS
下面这份 main.tf 是我实际在用的最小可用 EKS 模板,AWS 官方那个 eks module 巨方便,省掉了一堆 VPC / 子网 / IAM 的手工拼接。
# main.tf —— AWS EKS 最小可用集群
terraform {
required_version = ">= 1.5"
# 远端 backend:state 存到 S3,加 DynamoDB 锁
# 这里有个坑:bucket 和 table 必须先手动建好,terraform 自己管不了 backend 资源
backend "s3" {
bucket = "my-tf-state-prod"
key = "eks/prod/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tf-locks"
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
# VPC:用官方 module,开内网 + 公网子网
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "prod-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true # 省钱:只开一个 NAT,生产里要 HA 就别用 single
enable_dns_hostnames = true # EKS 必须开,否则 CoreDNS 解析有问题
}
# EKS 集群
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = "prod-cluster"
cluster_version = "1.30"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
enable_irsa = true # 启用 IRSA,让 Pod 用 IAM Role 而不是 node IAM
eks_managed_node_groups = {
general = {
instance_types = ["t3.large"]
desired_size = 2
min_size = 1
max_size = 4
disk_size = 50
}
}
# 坑:cluster_endpoint_public_access 默认是 false,kubectl 连不上
cluster_endpoint_public_access = true
}
output "cluster_endpoint" {
value = module.eks.cluster_endpoint
}
工作流就三步:
terraform init # 拉 provider + 初始化 backend
terraform plan # 先 dry-run 看变更,重点 review destroy 那一栏
terraform apply # 确认无误再 apply
踩坑提示:state 文件绝对不能提交 git。我有一次见实习生把 terraform.tfstate 提交到公开 repo,里面明文存了 DB 密码、access key,当天就触发安全告警,全员轮换密钥。正确做法是 state 放 S3/OSS,git 里加 .gitignore:
# .gitignore
*.tfstate
*.tfstate.*
crash.log
.terraform/
.terraform.lock.hcl
*.tfvars # 含密钥的 tfvars 也不进 git,用 *.tfvars.example 做模板
state 漂移与 force-unlock
state 漂移是 Terraform 最头疼的事。常见来源:同事手动在控制台改了资源、AWS 自动加了默认 tag、其它 IaC 工具交叉管理。漂移后 terraform plan 会爆出一堆"鬼变更”。
# 检测漂移
terraform plan -detailed-exitcode # exit code 2 = 有漂移
# 同步真实状态(不修改云资源,只改 state)
terraform refresh # 老命令,新版已废弃
terraform apply -refresh-only # 新写法,只刷新 state
# 实在拉不回来,手动改 state
terraform state list # 看 state 里有哪些资源
terraform state rm aws_xxx.foo # 从 state 里移除(资源留在云上)
terraform import aws_xxx.foo id # 把云上已有资源导入 state
force-unlock 是另一个我踩过的大坑。terraform apply 中途网络断了,DynamoDB 锁没释放,下次 plan 直接报 “Error acquiring the state lock”。这种情况只能 force-unlock:
terraform force-unlock <LOCK_ID> # 强制释放锁
但 force-unlock 是危险操作,必须确认前一个 apply 真的退出了。我有次没确认就 unlock,结果两个 apply 并行跑,state 被写崩,恢复了一晚上。所以 unlock 之前先去 DynamoDB 看一眼 lock 那条记录的 Info 字段,确认是不是僵尸锁。
Crossplane:把云资源变成 K8s CRD
Crossplane 思路不一样,它把 AWS/Azure/GCP 的资源都包装成 K8s 自定义资源(CRD)。你写个 Bucket CR,Crossplane 控制器就去给你建 S3。好处是基础设施和应用都走 kubectl + GitOps 一套流程。
下面是个完整例子:平台团队用 Composition 封装一个"标准存储桶",业务团队只要 Claim 一下就能拿到。
# composition.yaml —— 平台团队定义:标准 S3 桶
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: standard-bucket
labels:
provider: aws
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XBucket
resources:
- name: bucket
base:
apiVersion: s3.aws.crossplane.io/v1beta1
kind: Bucket
spec:
forProvider:
region: ap-northeast-1
acl: private
versioningConfiguration:
status: Enabled # 强制开版本控制,防误删
lifecycleConfiguration:
rules:
- id: expire-logs
status: Enabled
expirationInDays: 30 # 30 天后自动清理
patches:
- fromFieldPath: "spec.bucketName"
toFieldPath: "metadata.annotations[crossplane.io/external-name]"
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.region"
业务团队只要写 Claim(跟写 Pod 一样简单):
# claim.yaml —— 业务团队申请一个桶
apiVersion: platform.example.com/v1alpha1
kind: BucketClaim
metadata:
name: order-service-logs
namespace: prod
spec:
bucketName: order-service-logs-prod-2025
region: ap-northeast-1
kubectl apply -f claim.yaml
kubectl get bucketclaim order-service-logs -n prod -w
踩坑提示:Crossplane 删资源是异步的,kubectl delete bucketclaim 之后云上资源可能还在,Deletion 卡在 Waiting for external resource to be deleted。S3 桶如果非空就删不掉,得先清空对象或者配 lifecycle 规则。生产里我一定会在 Composition 里强制加 lifecycleConfiguration,防止 bucket 永远删不掉。
Terraform vs Crossplane 怎么选
我自己的判断:
- 基础设施新建、跨云、一次性大量资源:用 Terraform,速度快、生态成熟、本地校验方便。
- 持续 reconcile、与应用同生命周期、GitOps 流派:用 Crossplane,跟 ArgoCD 配合体验极佳。
- 混合用:Terraform 建集群本身(VPC/EKS),Crossplane 跑在集群里管业务用的云资源(DB、桶、队列)。这是我现在生产线上的方案。
flowchart TB
S{资源类型与诉求}
S -->|新建/跨云/一次性大量| T[Terraform
write→plan→apply]
S -->|持续 reconcile/GitOps| C[Crossplane
kubectl + Composition/Claim]
S -->|混合| M[Terraform 建底座
+ Crossplane 管业务资源]总结
云原生基础不仅是容器和 Kubernetes,更是一套围绕 DevOps、SRE、AIOps 的现代化工程体系。理解这些概念之间的演进关系与互补关系,是后续学习 AIOps 实战、Client-go 开发、Operator 开发以及可观测性技术的必要前提。
说真的这一章全是概念,看着最枯燥,但真到后面写 Operator、调 LLM 的时候,回头再看会发现每一步都对得上。DevOps 给你流水线,SRE 给你 SLO,AIOps 在这俩基础上才能落地——不然你 LLM 生成的 PromQL 连指标都没采集,生成的扩容决策连 SLO 都没算,纯属空中楼阁。
自测题与动手练习
自测题(合上书能答出来,才算懂):
- 用一句话区分 SLI、SLO、错误预算;并算:某服务 SLO=99.95%、月请求 2 亿次,月度错误预算是多少次 5xx?
- 为什么说「只靠网关验证」在 AIOps 语境下不成立?DevOps、SRE、AIOps 三者是替代关系还是叠加关系?
- 为什么说 LLM 生成的 PromQL「绝不能直接执行」?正确的「人在环里」流程是什么?
- Terraform 的 state 漂移通常由哪些原因引起?
terraform force-unlock为什么是危险操作、执行前必须确认什么? - Terraform 和 Crossplane 的核心工作流有什么本质区别?什么场景适合「混合用」?
动手练习(建议真做一遍):
- 写一份
sloth.yaml描述你的某个服务的 SLO,跑sloth generate看生成的 multi-window burn-rate 规则长啥样。 - 把你最常用的一个 Prometheus 查询,套进文中的 NL→PromQL prompt 模板,验证模型能否稳定输出正确指标名(而非臆造)。
- 写一份最小
main.tf(哪怕只是建一个 S3 bucket),跑terraform init && terraform plan,体验「dry-run 看变更」再决定要不要 apply。
本章小结
- 软件交付从瀑布→精益→敏捷→DevOps→SRE→AIOps 持续演进,后者不是替代前者,而是在协作、可靠性、智能三层叠加能力。
- DevOps 流水线(Plan→…→Feedback)是工程文化的镜子;Jenkins/GitLab CI/ArgoCD 定位不同,小团队 GitLab CI 一把梭,规模上来上 ArgoCD。
- SLI 是量到的数据、SLO 是承诺的目标、错误预算=1-SLO 是「允许坏掉」的额度;SLO 烧光要冻结新功能。
- AIOps 用 LLM 做 NL→PromQL、日志摘要、RAG 知识库、决策 Agent,但生成的动作必须「人在环里」确认,绝不能直接自动执行。
- IaC 是云原生交付支柱:Terraform 走
write→plan→apply、state 是核心且不能提交 git;Crossplane 把云资源变 K8s CRD,适合 GitOps 流派;二者可混合。 - 下一章起可以顺着这条脉络进入 AIOps 实战、Client-go / Operator 开发与可观测性技术。