学习目标
学完本章你应该能够:
- 讲清软件交付从「瀑布 → 精益 → 敏捷 → DevOps → SRE → AIOps」的演进脉络,以及每一阶段要解决的核心矛盾。
- 说清 AIOps 的严格定义、三阶段(监控 → 分析 → 自动化)、四大优势,以及它为什么必须与云原生结合。
- 讲明大模型给 AIOps 带来的两次机遇(数据建模 + 数据分析),并用「构建 AI 应用的五层理论」解释落地路径。
- 区分 LLM 与 AIOps 结合的核心技术栈:Prompt 工程、JSON Mode、Function Calling、RAG、微调,并理解各自解决什么问题。
- 画出一条真实 DevOps 流水线,分清 SLI / SLO / 错误预算,并能算月度错误预算消耗。
- 讲清 IaC 的三大特性(声明式、有状态、幂等)带来的优势,以及与 CLI/API「命令式」管理的本质区别。
- 跑通
terraform init / plan / apply / destroy全流程,理解 state 文件、provider、registry、模块、workspace 与多环境管理。 - 借助 ArgoCD + Crossplane,理解并复现「YAML → 基础设施」的 PaaS 自建思路。
前置知识:用过 Git 和至少一种 CI 工具;知道 Docker / Kubernetes 基本概念;对 Prometheus 指标有耳闻即可。
本章你会动手做的事:
- 用腾讯云 + Terraform 开通一台 CVM,跑通
plan → apply → destroy。 - 把 Teraform 代码按
main/output/variable/version标准布局拆分,并用模块 + 目录隔离 dev/test 多环境。 - 用 Crossplane 的 YAML 创建一个 VPC + 子网 + 虚拟机,再交给 ArgoCD 体验「YAML to Infra」。
从精益、敏捷到 DevOps 的发展脉络
软件交付模式的演进,本质上是企业为了更快、更稳地响应市场变化而不断探索的过程。早期瀑布模型强调阶段清晰,但反馈周期长、变更成本高。随后精益(Lean)思想被引入软件开发,核心是消除浪费、持续流动;敏捷(Agile)则进一步强调小步快跑、拥抱变化,通过迭代和增量交付缩短反馈环。
DevOps 在敏捷基础上,将开发(Dev)与运维(Ops)之间的壁垒打通,倡导"you build it, you run it"的文化。它不只是工具链的整合,更是组织流程、度量和协作方式的变革。典型的 DevOps 流水线包含:需求管理、代码提交、持续集成(CI)、持续交付(CD)、部署发布、运行监控、反馈改进。
之所以把 AIOps 定义为「下一代的 DevOps」,是因为 AIOps 是在 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 ← 失败案例回灌成新的需求
说实话我第一次看 DevOps 流水线图的时候觉得就那么回事儿,等真上手搭过几次才发现,流水线本身就是公司工程文化的镜子——你团队怎么协作,流水线就长什么样。
小团队 CI/CD 工具怎么选
| 工具 | 定位 | 优点 | 我踩过的坑 |
|---|---|---|---|
| Jenkins | 老牌 CI/CD 引擎 | 插件多,啥都能干 | Jenkinsfile 一长就乱,master 节点一挂全员瘫痪 |
| GitLab CI | GitLab 内置 CI | .gitlab-ci.yml 跟代码一起走 | shared runner 排队能等到天荒地老,得自己搭 runner |
| ArgoCD | GitOps CD 控制器 | 声明式、UI 直观、K8s 原生 | 只管 CD 不管 CI;manifest repo 与代码 repo 解耦后维护成本上升 |
我个人觉得小团队 GitLab CI 一把梭就够了;规模上来或者要搞 GitOps 就上 ArgoCD,CI 保留 GitLab CI / GitHub Actions。Jenkins 现在基本不再主动选了,维护成本太高。
什么是 AIOps
AIOps 的定义非常明确:它是一种使用人工智能技术来简化运维工作流的技术方案,采用的技术包括机器学习与数据分析等。
从这个定义可以直接得出一个重要结论:无论是机器学习还是数据分析,数据对 AIOps 而言都是一个核心基础——没有高质量的数据,一切智能都是空中楼阁。
AIOps 的三个阶段
flowchart LR
A[监控
数据来源
历史+实时] --> B[分析
归纳/分类/异常检测/性能/关联分析
→ 优化建议] --> C[自动化
按建议或任务自动执行流程]- 监控(数据来源):包含历史数据和实时数据,是整个 AIOps 的数据来源。
- 分析:对历史数据和实时数据做归纳、分类、异常检测、性能分析、数据关联分析,并据此输出优化建议。
- 自动化:根据优化建议或既定任务,自动执行运维自动化流程。
AIOps 的优势主要体现在分析与自动化这两个环节。
AIOps 的四大优势
结合上面的三阶段,AIOps 的核心价值可以归纳为四点:
- 持续观测海量数据流:人工难以持续盯住整个监控数据流或日志流,而 AIOps 擅长处理庞大的数据量,对数据的敏感度远超人工。
- 解决运维团队孤岛问题:业务团队之间相互孤立,运维团队理解的上下文有限。AIOps 通过业务指标 + 日志 + 追踪三种多模态数据做关联分析,随时发现问题。
- 预测问题并提前解决:借助机器学习对数据建模实现预测,而不是靠用户反馈或告警来被动响应。
- 根因分析:借助机器学习快速处理大量数据并建模,最终定位问题产生的根本原因。
实现 AIOps 的抽象层
从下到上大致是:
业务应用层 虚拟机 / 容器 / 分布式应用等不同形态
↓
数据接入层 日志 / 分布式追踪 / 指标 —— AIOps 的核心基础
↓
运维接口能力 重启 / 回滚 / 配置 / 调整参数 —— 智能化闭环的最后一环
- 数据层是核心基础:这也是 OpenTelemetry 这类「一网打尽」技术备受关注的原因。
- 运维接口能力:以前很难抽象化,但借助 K8s 的声明式能力,重启服务、回滚配置、调整参数、回滚发布版本都变得很容易实现。这是 AIOps 必须与云原生结合的重要原因之一。
容易忽略的元数据
在数据接入层,除了日志、监控、指标这些核心数据,还有一类实践上常被忽略、但实施 AIOps 平台时非常有用的数据——元数据,分为三类:
| 元数据类型 | 内容 | 用途 |
|---|---|---|
| 服务元数据 | 编码语言、版本、SDK 核心版本 | 让平台了解服务细节,辅助更深入的根因分析 |
| 部署元数据 | 部署形式(容器/VM)、Pod、工作负载、所在节点/机房 | 让平台了解部署层面的细节 |
| 业务元数据 | 运维/开发元数据(所属团队、负责人等标识) | 产生告警时快速找到对应业务团队与负责人 |
AIOps 为什么之前发展不顺、现在又火了
AIOps 自 2016 年提出至今约 8 年,发展一直不算顺利,但最近又被重新提起来。很重要的一个原因就是:大模型给 AIOps 提供了一个全新的发展机会。国内大模型发展迅速,可选择的大模型也很多。
大模型与 AIOps 的结合
大模型与 AIOps 的关系主要体现在两点:数据建模与数据分析。
- 数据分析:AIOps 环节中大量数据靠人工处理很困难,而大模型恰恰非常擅长处理文本数据(日志、告警),极大降低了数据分析的难度。
- 数据建模:可借助大模型来编写数据建模的算法(时序预测、分类等),大模型就像一位拥有十几年运维经验的专家,帮我们快速迁移到 AIOps 平台。
传统根因分析的痛点 vs 大模型的新可能
传统运维在故障根因分析时的做法是:先把时间轴框出来,把不同指标和日志按固定时间轴对齐,然后纵向切分周期内的所有指标和日志,人工递归找上游/下游问题,直到递归到最上游或最下游。
这个方式的问题很明显:
- 工作量极大、数据量大、指标维度多,几乎只有运维专家能胜任,且依赖专家经验。
- 递归存在多个路线选择,人工选错路线会投入大量无效时间,效率非常低。
大模型出现后,多模态运维数据处理成为可能。所谓多模态数据即日志、指标、追踪等。可以借助大模型实现类似「混合专家」的模式:
- 有一个 日志 Agent(Log 专家)、指标 Agent(指标专家)、分布式追踪专家,分别分析不同模态的数据。
- 分析完后由大模型整合分析结果,输出故障可能产生的原因。
结合大模型,还能:
- 对故障发生时刻引出的各种多模态数据做分析解释,甚至提出建议。
- 结合内部运维专家知识库找到解决办法。
新的人机交互方式:自然语言
大模型与 AIOps 结合后,产生了一种以自然语言为核心的交互方式。以前查监控日志只能通过 UI/命令行/API,现在大模型能理解语义,并把语义里的内容转化为函数调用的参数:
- 例如「查最近 7 天数据库层面的报错信息」,大模型能转换为调用
get_database_log函数。 - 能从语义中解析出时间范围周期、报错关键字、LEVEL 等参数,获取数据后返回结果。
构建 AI 应用的五层理论
要把大模型落地到 AIOps,需要跨越五层鸿沟:
flowchart TB
L0[模型层
各大模型 API 接入] --> L1[Prompt 层
提示词工程 zero-shot / few-shot]
L1 --> L2[思维链层
模型链式调用/多步思考]
L2 --> L3[Agent 层
自主思考/决策/行动的智能体]
L3 --> L4[多 Agent 协同层
任务拆分/协作分工]- 模型层:主要指各种大模型 API 的接入。
- Prompt(提示语):提示词工程,比如常见的 zero-shot 和 few-shot。提示词的质量很大程度决定大模型输出的质量(是否给模型提供示例也是关键)。
- 思维链:模型层面的链式调用,把一个模型输出作为下一次调用的输入,实现多步思考。
- Agent:具备自主思考、决策、行动的智能体,是大模型与 AIOps 领域里非常垂直的研究方向(课程后续会带大家开发 Agent)。
- 多 Agent 协同:单个 Agent 无法满足任务时,把任务拆分,让不同的 Agent 协作分工、相互调用。
核心技术栈:从上到下
除了五层理论,大模型落地 AIOps 的核心技术(底层都以 prompt 质量决定输出质量):
Prompt Engineering 提示词质量决定输出质量
↓
JSON Mode 稳定输出 JSON,作为 LLM 与程序之间的桥梁
↓
Function Calling 把方法封装成函数调用,实现链式调用、意图识别
↓
RAG 检索增强生成,用个人/运维专家知识库解决幻觉与不懂业务
↓
微调 现阶段 GPT-4 等不能微调、实践上用得少,建议先用现成大模型
实施 AIOps 的五大挑战
虽然挑战都比较大,但换个层面讲也要保持耐心与信心,因为每个挑战目前都有对应解决方案:
| 挑战 | 说明 | 应对思路 |
|---|---|---|
| 运维场景严肃性 | 对错误容忍度极低 | 用 RAG 技术极大缓解大模型的幻觉问题 |
| 数据隐私/安全/合规 | 数据安全性限制多 | 把开源大模型私有化部署(量化、裁剪等低成本方式) |
| 高质量运维数据标注缺失 | 语料和知识库普遍不足 | 逐步积累、先聚焦聚类+人工标注核心场景 |
| 大模型难处理海量实时数据 | token 限制 + 成本,不能逐条分析 | 先用机器学习对日志聚类,只把异常日志交给大模型 |
| 如何结合存量 DevOps 工具 | 让大模型调用现有运维工具 | 通过 Function Calling / Agent 把大模型与工具连接 |
大模型应用自身的可观测性
开发大模型应用时,自身也需要可观测性,例如:
- Agent 里继承各种工具:要看调用链、调用结果、不同调用链的调用关系。
- 调试不同的提示语(prompt 里面的 system)。
- 在线调试:不同提示语立即修改、立即查看,而不是重新运行一遍程序。
- 统计 token 消耗与费用。
这些需求可以借助大模型工程平台(如 Dify、Langfuse)实现。Langfuse 是开源的、价格也比较便宜;Dify 是很好的开源替代方案。
AIOps 与云原生:数据接入与运维接口
除了大模型,云原生架构也极大加速了 AIOps 发展,解决的是数据接入层和运维接口能力两大痛点:
- 运维接口能力(声明式):没有统一平台时,单独实现重启、配置变更、配置回滚这些接口能力很不容易。但业务整体采用云原生架构后,借助声明式通过 YAML 文件就能实现调整配置、回滚版本等。AIOps 平台调用运维接口时就拥有统一的方式。
- 数据接入层(OpenTelemetry / eBPF):最近两年很火的 OpenTelemetry 能统一日志、指标、追踪,是一个「All-in-One」的整体解决方案,一次性集成解决三种数据的采集问题。借助 eBPF 技术还能实现零侵入的指标收集与监控(如 Cilium、Falco)。
分布式追踪系统原理
用 OpenTelemetry 构建分布式追踪系统很简单:
- 每个业务被抽象为一个 Span。
- 请求被发起时的入口服务称为 Root Span(根节点),如图中的服务 A。
- 服务 A 调用服务 B、服务 C,B/C 又调用下游服务,整个调用链就是一次分布式追踪。
- Span 之间的边界反映父子关系:Span C 是 Span A 的子节点。
- 右侧的调用时序图直观展示不同服务在时间线上的调用情况,也能倒推出 Span 之间的父子关系。
flowchart LR
A[服务A
Root Span] --> B[服务B]
A --> C[服务C]
B --> D[服务D]
C --> E[服务E]AIOps 常用算法与应用案例
在广件应用场景里,可以通过机器学习简化运维工作流程,例如故障预警、持续预测、故障分类、异常检测。按算法类别可分为:统计分析、持续分析与预测、机器学习分类、异常检测。
| 场景 | 常用算法 |
|---|---|
| 故障预警 | LSTM(长短期记忆网络)、XGBoost 等 |
| 异常检测 | Z-score、滑动窗口 + 聚类等 |
| 流量预测 | 预测波峰波谷的时间序列算法 |
| 日志聚类 | 日志提取 → 分词 → 词向量 → 降维 → 聚类(如 DBSCAN) |
日志聚类的核心流程:日志提取、分词、把分词转化为词向量、降维,最后用聚类算法实现聚类。最核心的步骤是借助**词频 + 逆文本频率指数(TF-IDF)**得到日志的特征向量,之后做降维,最后用 DBSCAN 等聚类算法把海量日志聚类为正常日志、错误日志、WARN 级别等。
运维知识库与数字分身
大模型结合 Agent 的一个典型场景是构建个人运维知识库 / 数字分身:
- 流业务方通过询问 Agent 解决常见运维问答,而不是询问运维本人,例如「监控面板怎么看?」「memory_overcommit 指标是什么意思?」「分配给我的账号密码」「如何申请更高指标权限」「自动填写工单」等。
- 同理,可以构建公司级的业务运维专家知识库:把运维专家的知识和经验通过 RAG 提供给大模型,相当于「克隆运维专家」——不仅能解决技术问题,还能解决专家知识的存储、快速检索、在不同专家之间的流动与汇总问题。
历史故障驱动的根因推断
运维知识库还有一个很不错的用法:用历史故障 + 专家经验(向量数据库)来推断新故障的原因。例如当出现「支付接口失败率 > 50%、持续 5 分钟」这类故障时:
- 借助 Agent 从向量数据库找出 Top-N 个历史类似故障及专家解决方案。
- 结合历史故障推断本次故障的原因和解决方向。
- 交给大模型处理,过程中让大模型做反思(Self-Reflection)来提高 RAG 准确率。
- 最终把本次故障加入向量数据库,实现知识库的实时更新,相当于拥有了「不断学习新知识的内部 AI 运维专家」。
一个完整的智能化运维流程
最终目标是构建一个智能化的运维闭环:
flowchart TB
A[指标报警] --> B[异常检测机制
分析指标异常原因]
B --> C[Agent 结合日志+追踪数据做根因分析]
C --> D[向量数据库匹配专家知识库]
D --> E[把 prompt+日志+追踪+专家知识
+历史类似故障交给大模型判断]
E --> F{能否自动修复?}
F -->|能| G[调用其他 Agent 多Agent协同主动修复]
F -->|不能| H[调用人类帮助 Agent
与人类交互]课程后续的训练营会带大家探索并实践这个简单的智能化运维流程。
基础设施即代码(IaC)概述
在进入容器和 Kubernetes 之前,需要先掌握基础设施即代码(IaC),因为后续模块会用到这一技术。
从创建云资源的三种方式说起
创建云资源一般有三种途径:
- UI 控制台:通过界面开通产品、做配置。体验好、无门槛,但缺点明显:
- 除你之外没人知道在界面上到底操作了什么(不可审计、不可复现)。
- 需要开通管理员级权限或子账户授权,管理上不够安全。
- 体验取决于云厂商控制台能力(有的创建一台 VM 需要 VPC、子网、安全组、镜像、登录方式、密码、带宽、计费等一大堆东西)。
- API / CLI 命令行工具:每家用厂商都提供 API 或命令行工具(腾讯云 CLI、阿里云 CLI、AWS CLI),背后都调用自家 API。可以在 CI 流水线中创建云资源、拉起整套开发环境,也能用 SDK 集成做自动化。门槛更高,需要编程或 CLI 经验。CLI/API 本质上都是「命令式」的基础设施管理方式。
- IaC(Infrastructure as Code):以代码的方式把基础设施定义出来,用代码实现对基础设施的增删改查。因为只需要用 IaC 代码描述最终想达成的状态,它是一种「声明式」的基础设施管理方式——不必关注命令执行流程,只关注最终结果。
IaC 的三大特性
- 声明式:基础设施定义代码可方便地存储在 Git 仓库,并实现版本控制。
- 有状态:能够把 IaC 定义与真实云资源状态进行对比,并自动应用差异部分(新增/删除/修改)。
- 幂等:每次执行 IaC 代码都产生相同结果,不会因执行顺序或次数不同而改变。
IaC 带来的优势
- 代码定义的就是基础设施最终状态,运行结果人人一致、可复现。
- 借助 Git 版本控制,知道任何人、何时、对基础设施做了何种变更;故障时可回滚 IaC 代码。
- 结合 Git 实现 CI 层面的质量门禁(合并前的 review、变更检查)。
- 变更前 IaC 工具会输出清晰的影响范围:创建了什么、删除/更新了什么,而不是靠人写文档描述过程。
- 一条命令、几分钟就能拉起一整套复杂基础设施——对有私有部署/私有交付团队尤其重要,离开 IaC 交付很难。
六大应用场景
- 用代码(声明式)定义和创建基础设施。
- 把既有的云资源统一导入,做统一管理。
- 更安全地变更:执行前列出影响范围,人工确认后再变更。
- 与 CI/CD 工具整合,形成基础设施管理的工作流。
- 提供可复用的模块,供其他团队复用。
- 团队实现标准化的基础设施管理流程(不再依赖某个人在控制台点点点)。
主流 IaC 工具
- Terraform:本节课重点,最著名的 IaC 工具。
- Crossplane:运行在 Kubernetes 平台上,能让你以 Kubernetes 声明式的思想、通过 CRD 来管理基础设施。
两者都支持主流云厂商(国内:腾讯、阿里、华为;国外:AWS、Azure、GCP)。
Terraform 核心概念与架构
Terraform 是 IaC 的代表工具,使用自创的 HCL(HashiCorp Configuration Language)语言定义基础设施。
为什么用 HCL 而不是 YAML / JSON
HCL 是一种DSL(领域特定语言)。配置语言在复杂场景下,模块复用能力和编程能力很关键,而这正是 YAML/JSON 支持较差的地方,导致它们在大规模配置场景下比较尴尬。HCL 设计时希望同时保留 YAML/JSON 的可读性优势,同时增加动态编程特性——写起来很像编程,但它是面向配置的编程语言。
例如生成一段 JSON 配置,用 HCL 往往只需三行就能表达 JSON 需要写多行的内容。细节:HCL 是给人编写、给 Terraform 读取的;真正调用云厂商 API 时,大部分情况还是用 JSON(这是 Terraform 内部做的接口层转换)。
常见使用范式
- Terraform + Ansible:Terraform 管理基础设施,Ansible 做服务器配置(二者可一起用)。
- Terraform 管 K8s 集群:用 Terraform 开通云厂商集群;测试场景就安装 K3s,快速得到测试集群;生产级可直接管理托管集群(腾讯 TKE、阿里 ACK/EKS、AWS EKS)。
- 最简易测试流程:有测试需求时,用 Terraform + IaC 代码,一条命令拉出一套带公网访问能力的测试 K8s 集群。
总体架构
┌──────────────────────────────────────────────────────┐
│ HCL 配置代码(期望状态) → Terraform Core │
│ ↘ │
│ Terraform 来读取 state 文件(当前状态) │
│ ↙ │
│ 对比差异 → 调用 provider → 云厂商 API │
└──────────────────────────────────────────────────────┘
- Terraform Core:核心编排引擎。加载 HCL 配置(期望状态)与 state 文件(当前状态),做差异对比,并把差异转化为调用云平台 API 的行为。
- Provider:Terraform Core 本身不具备与云厂商直接交互的能力,靠 Provider(类似 Terraform 的插件、与核心引擎解耦)实现。Provider 将 HCL 配置映射到云厂商具体的 API 请求参数;一个 Terraform 文件里可用多个 Provider。
- Registry:存储主流云厂商 Provider 的地方。每个 Provider 文档会告诉你如何安装、如何配置密钥、创建各种资源的示例代码。不需要死记硬背,知道怎么查怎么用即可。
~>(悲观约束符)——同时约束最旧和最新版本,允许小版本号更新、限制大版本号更新。Terraform 核心命令
Terraform 最常见的四类命令:init / plan / apply / destroy。
| 命令 | 作用 | 说明 |
|---|---|---|
terraform init | 初始化依赖 | 拉取 Provider 并下载到项目根目录 .terraform/;引入新依赖或拿到别人代码后先执行 |
terraform plan | 预览变更 | 在 apply 之前确认本次变更的影响是否符合预期 |
terraform apply | 应用变更 | 有交互式确认;CI 中可用 -auto-approve 跳过二次确认 |
terraform destroy | 销毁资源 | 只删除由 Terraform 创建并记录在 state 文件里的资源,不会误删其它资源 |
init 的细节:目录结构
执行 terraform init 后:
- Provider 存放在项目根目录的
.terraform/下,下载到的是一个二进制可执行文件,而且二进制是与平台相关的(不同平台的依赖不能复用)。 - 会生成
.terraform.lock.hcl文件,类似 Go/NodeJS 的依赖锁定文件,用来锁定依赖版本。 - 若项目依赖了某个 Module,也会一并下载(Module 是为了实现代码复用而引入的概念,稍后介绍)。
plan 的对比逻辑
运行 terraform plan 时,Terraform 把**期望状态(HCL 代码 / .tf 文件)与当前状态(state 文件)**做对比。例如期望状态定义两台虚拟机 + 一台数据库,而当前状态只记录了一台虚拟机 + 一台数据库,plan 就会提示你需要新增一台虚拟机。
关键细节:期望状态和真实状态里的每个资源都有一一对应的内部唯一 ID 来标识。
state 文件
terraform apply 会在项目目录下生成 terraform.tfstate 文件,以 JSON 格式记录基础设置的真实状态。要点:
- 文件中可能包含敏感信息(如虚拟机密码),保管要非常小心。
- 单机使用可安全放本地或 Git 私有仓库;团队协作时放远端(对象存储 / Terraform Cloud),而不是放进 Git。
- 执行
destroy后该文件会随之清空。
import:导入既有资源
如果资源是在用 Terraform 之前通过控制台创建的,state 文件里没有记录,需要用 terraform import 导入:
terraform import tencentcloud_instance.web <资源ID>
- 参数中的资源名必须与
resource块中写的对象名称一一对应。 - 运行后 Terraform 会从云厂商拉取该 ID 的所有信息,重新生成 state 文件,把它变成由 Terraform 管理。
- 注意:并不是所有资源都支持导入。
apply 的四种状态组合
用「配置(IaC 代码)/ state 文件 / 真实状态」三者的组合,判断 apply 时的行为:
| 配置 (IaC) | state 文件 | 真实环境 | apply 行为 | 说明 |
|---|---|---|---|---|
| 有 | 无 | 无 | 创建 | 全新资源 |
| 有 | 有 | 无 | 创建 | state 记载有误,以 IaC 代码为准(会先调云厂商接口核真实环境) |
| 有 | 有 | 有 | 什么都不做 | 三者一致 |
| 无 | 有 | 有 | 删除 | 从代码里删掉了该资源 |
| 无 | 无 | 有 | 什么都不做 | 该资源非 Terraform 管理,不会删除 |
| 无 | 有 | 无 | 更新 state 文件 | 真实已不存在 |
flowchart LR
C{配置存在?} -->|是| S1{state有?} -->|无| CREATE[创建]
S1 -->|有| R1{真实有?} -->|无| CREATE
R1 -->|有| NOP1[什么都不做]
C -->|否| S2{state有?} --- R2{真实有?}state 的两种存储方式与 remote backend
- 本地存储(local):一开始了解、使用 Terraform 时很方便。但文件在本地,不利于协作——两人 state 不同又先后变更会产生不一致。
- 远端存储(remote backend):中心化存储 place,多人变更时都从中心拉取最新 state,不需要担心一致性问题。
远端存储方式包括:Terraform Cloud、对象存储(AWS S3 / 腾讯 COS / 阿里 OSS) 等。
Terraform Cloud
5 人以下免费,超过 5 人收费。在 Terraform Cloud 里创建组织和 workspace,代码里直接指定用 Terraform Cloud 作为后端存储。
terraform {
backend "remote" {
organization = "your-org"
workspaces {
name = "default-project"
}
}
}
用 COS / S3 做 backend
除了 Terraform Cloud,可用 AWS S3、腾讯 COS、阿里 OSS 存储 state:
- S3 可指定加解密存储,还要配 DynamoDB 实现原子性操作(阻止两人同时变更)。
- 腾讯 COS 做 backend 时,需要 region、bucket、app_id、prefix 等参数。
COS 迁移实操要点:先用本地 state 创建 COS 桶(私有 + SSE256 加密),配置好 backend 参数(region / bucket / app_id / prefix)后,执行 terraform init,它会识别 backend 变更并提示执行迁移;输入 yes 后本地 terraform.tfstate 会被清空,state 成功迁移到 COS。
state 相关命令
terraform refresh # 本地 state 与远端不一致时,从远端更新 state(如你在控制台改过资源)
terraform state list # 列出 state 记录的所有资源
terraform state rm # 删除 state 里保存的某条状态(destroy 失败时可尝试删异常状态后重跑)
terraform state pull # 从远端 backend 拉取 state
terraform state push # 将本地 state 推送到远端 backend
Terraform 项目布局(Layout)与变量
把所有 IaC 写在一个 .tf 文件里可读性和维护性都很差。官方推荐的良好布局是把一个文件拆成四个文件:
| 文件 | 职责 |
|---|---|
main.tf | 主要业务逻辑;逻辑多可拆成多个子文件(如 cvm.tf / cos.tf),放同一目录下 Terraform 统一加载 |
output.tf | 定义运行结束输出的内容(如公网 IP、登录密码等);值可以是硬编码,也可引用资源对象;可标记为敏感数据避免打印 |
variables.tf | 定义输入参数并在 main 里引用(如 secret_id/key、region 等);支持校验函数(如长度 > 3)、敏感标记 |
versions.tf | 定义 Provider 版本,固定依赖版本,避免上游更新导致代码不可用 |
# variables.tf —— 声明输入参数
variable "region" {
description = "基础设施地域"
type = string
default = "ap-hongkong"
}
variable "ssh_password" {
type = string
sensitive = true # 敏感数据,plan 时不显示
validation {
condition = length(var.ssh_password) > 3
error_message = "密码长度必须大于3"
}
}
变量的 5 种设置方式与优先级
设置 variable 一共 5 种方式,优先级从高到低覆盖:
- 命令行:
terraform apply -var="foo=bar"。 - 配置文件:
terraform.tfvars文件(所有参数集中配置)。 - 环境变量:前缀
TF_VAR_(如TF_VAR_region、TF_VAR_secret_id)——推荐方式,尤其配合不把密钥写进代码。 - 默认值:在
variables.tf里定义default(提供基础值)。 - 交互式输入:以上方式都取不到时,apply 会以交互式方式让你输入。
优先级:命令行 > 配置文件 > 环境变量 > 默认值。例如你在 variables.tf 里定义了默认值,但又用环境变量设置了同名参数,则以环境变量为准。
Terraform 实战:VM + K3s + ArgoCD
用一个综合例子走一遍「标准布局 + 模块化 + 多环境」:开通虚拟机 → 安装 K3s → 安装 ArgoCD,全部通过 IaC 管理。
目录拆分为多文件
在这个例子里,不用单个 main.tf,而是拆成:
.
├── main.tf # (这里不需要,因为拆成下面三个业务文件)
├── cvm.tf # 开通虚拟机
├── k3s.tf # 在虚拟机上安装 K3s
├── argocd.tf # 安装 ArgoCD
├── variables.tf # 入参:secret_id / secret_key / region / ssh_password
├── output.tf # 输出:public_ip、kube_config、ssh_password
└── versions.tf # provider 版本固定(腾讯云 + helm)
所有参数值都从 variables 里取(var.secret_id 等),不再重复定义。安装 K3s 用一个 K3s 模块,安装 ArgoCD 用官方 Helm 模块。
depends_on:显式依赖
安装 Helm 前必须先有 K3s 集群,所以 Helm 处用了 depends_on 显式指定依赖 K3s 模块:
# argocd.tf
resource "helm_release" "argocd" {
name = "argocd"
repository = "https://argoproj.github.io/argo-helm"
chart = "argo-cd"
namespace = "argocd"
create_namespace = true
depends_on = [module.k3s] # 等 K3s 模块跑完才装 ArgoCD
}
依赖有两种:
- 隐式依赖:一个模块的输出作为另一个模块的输入(如 K3s 引用虚拟机的 IP 和密码),Terraform 自动识别。
- 显式依赖:模块之间没有相互引用时,只能通过
depends_on指定执行顺序。 Terraform 的 plan 会依据依赖关系形成有向无环图(DAG),再按 DAG 顺序执行各模块。可用terraform graph生成该图。
运行与 graph
terraform init
TF_VAR_secret_id=<id> TF_VAR_secret_key=<key> terraform apply -auto-approve
terraform graph | dot -Tsvg > graph.svg # 可视化依赖关系
用 terraform graph 生成的 SVG 就是 Terraform 构建的 DAG:所有资源的执行依赖和步骤都记录在这张图里。
HCL 进阶:表达式、函数与元参数
相较 YAML/JSON,HCL 因具备编程特性,能生成复杂结构。
表达式与函数
- 表达式:引用模板变量、运算符、条件表达式做流程控制;
for表达式可以把生成的块当作程序一样,生成 N 个资源块。 - 函数:字符串处理、集合操作等方法都能找到。常用
templatefile函数——定义自己的 shell 脚本模板文件,用 Terraform 内置变量替换模板里变量值重新生成文件,对处理复杂情况很有帮助。
四个元参数
元参数的作用域主要是 resource 和 module,用来控制资源的创建和销毁过程:
| 元参数 | 作用 |
|---|---|
depends_on | 显式声明资源依赖关系,生成 DAG 保证执行顺序 |
count | 创建 N 个完全一致的资源,web[0]、web[1]… 带索引访问 |
for_each | 类似 count,但更好控制,适合每台配置不同的场景(如不同子网);先声明集合再循环使用 |
lifecycle | 控制创建/删除行为:before/阻止删除/忽略差异/引用变化时替换资源;常用「先建后删」实现零停机 |
count 与 for_each 区别:count 创建的资源完全一致;当要创建两台属于不同子网的虚拟机时,for_each 能更好地控制。Provisioner
Provisioner 用于在本地或远端虚拟机中执行一组动作,三个最常用的:
| 类型 | 作用 | 注意点 |
|---|---|---|
file | 把本地文件拷贝到远端虚拟机(类似 scp) | 传配置文件、shell 脚本时好用 |
local-exec | 执行本地命令 | 有平台差异:Linux 能跑的命令放 Windows 可能跑不了 |
remote-exec | 在远端虚拟机执行命令 | 可用 inline 写多行命令,也可指定远端 shell 脚本(通常先 file 传脚本再 remote-exec 运行) |
多环境管理
怎么为同一套基础设施创建多环境(dev / test / prod)?有三种方案:
方案一:目录隔离(缺点明显)
Terraform 把状态记录在 state 文件,最直接的方式就是区分 state 文件。把 IaC 代码复制到不同目录(目录名即环境名),各自拥有专属 state 文件。
缺点:修改 IaC 代码需同时修改多个环境目录下的相同文件,时间久了环境差异会越来越大、越来越难维护。
方案二:Workspace(需维护上下文)
terraform workspace 本质上也是对 state 文件做区分,但它是一种内置功能:在同一份 Terraform 代码下创建子目录放不同 state 文件,实现不同环境/workspace 的区分。
terraform workspace list # 默认只有 default
terraform workspace new dev # 创建并切换到 dev workspace
terraform workspace new testing # 创建 testing
terraform workspace select dev # 切换回 dev
只需维护一份代码即可创建 N 个环境。但它额外增加了上下文负担——执行任何命令都必须清楚自己所在 workspace,一不小心就会在错误的 workspace 执行错误的命令。
方案三:模块 + 目录隔离(推荐)
兼顾目录与 workspace 二者优点的方案是用模块(Module)+ 目录隔离。
模块概念很像程序里的 class,目的是复用 Terraform 代码,让代码组织更具结构与灵活。分两类:
- 根模块:包含所有工作目录下的 .tf 文件——你创建的任意 demo 目录都是根模块。
- 子模块:通过引用方式使用外部模块(本地模块、Registry 模块、其他来源)。K3s 那个模块就是 Registry 里的模块。
重构为模块的思路:
demo/
├── modules/
│ ├── cvm/ # 虚拟机模块:main.tf + variables.tf + outputs.tf + versions.tf
│ └── k3s/ # K3s 模块:main.tf + variables.tf + outputs.tf
├── dev/ # dev 环境目录
│ ├── main.tf # 只引用模块,几乎无业务逻辑
│ └── variables.tf
└── testing/ # testing 环境目录(结构同 dev)
- 每个模块独立工作,输出通过 outputs 暴露。
- 环境目录下的
main.tf逻辑极简,只引用 cvm 模块 + k3s 模块并传参。 - 用 module 输出(public_ip)作为下一个模块输入,形成隐式依赖,Terraform 自动先建 cvm 再建 k3s。
# dev/main.tf —— 引用模块
module "cvm" {
source = "../modules/cvm"
secret_id = var.secret_id
secret_key = var.secret_key
password = var.ssh_password
}
module "k3s" {
source = "../modules/k3s"
public_ip = module.cvm.public_ip
private_ip = module.cvm.private_ip
}
output "kube_config" {
value = module.k3s.kube_config
}
好处:修改 IaC 只需改 module,环境代码几乎不变,不会导致各环境在维护中产生差异。
设计模块的原则
- 以产品功能为维度拆分模块。
- 为模块设置必要入参和逻辑条件判断,让同一模块在不同参数下更灵活(如根据环境名判断 dev 用按量付费、生产用包年包月)。
- 入参提供有用的默认值,降低使用难度、减少必须传参数量。
- 一定要设置 output,它是把不同模块串联起来的必要条件。
Crossplane:把云资源变成 Kubernetes CRD
Crossplane 是一个 Kubernetes 控制器(Operator),能让你以 CRD 的方式定义基础设施:
- 用声明式方式管理基础设施,支持多云与混合云。
- 甚至可以在 Kubernetes 里运行 Terraform,实现「YAML → Infra」——把一段代码部署到集群就能自动开通基础设施。
- 尤其适合自研 PaaS 平台:提供 UI 表单让开发同学填单,后端把表单生成 YAML 部署到集群,就能自动创建基础设施。
工作原理
Crossplane 由 CRD(描述 Crossplane 资源对象,如虚拟机、VPC、COS 对象存储) 和 Controller(控制循环,不断 watch CRD 变化,变化时自动执行基础设施变更) 组成。它与 Terraform 设计相近:有核心、有 Provider,核心能力由 Provider 提供;提供商市场(如 Boundless)里能找到大量第三方 Provider。
注意:国内云厂商对 Crossplane Provider 的投入更新频率比 Terraform Provider 低,但不影响使用。
用 Crossplane 创建腾讯云 CVM
在安装好 Crossplane 的 K3s 集群里,通过 YAML 创建 VPC + 子网 + CVM:
- Install Provider:
Provider.yaml,把腾讯云 Provider 安装进去。 - ProviderConfig:通过文件把 secret_id / secret_key 传进去(引用一个 Secret)。
- Secret:在 crossplane-system 命名空间存放 credential 信息。
- VPC:只需一个 CIDR block。
- Subnet:可用区 + CIDR +
spec.forProvider.vpcIdRef(引用上面创建的 VPC)。 - CVM:实例名、可用区、计费类型、镜像 ID、实例类型、磁盘类型 + 引用 VPC/子网 ID。
kubectl apply -f vpc.yaml
kubectl apply -f subnet.yaml
kubectl apply -f cvm.yaml
kubectl get vpcs,subnets,cvms # 查看状态,READY 从 false → true
reference 是否命名正确;② secret_id/key 是否有效(无效时换一组并重新 apply ProviderConfig/Secret);③ 可用区、命名空间是否写对(如 crossplane-system 与 crossplane 混淆)。Kubernetes 会等 Crossplane 控制器完成后状态才变 true。ArgoCD + Crossplane 自建 PaaS(YAML to Infra)
把 Crossplane 的 YAML(基础设施代码)放进 Git 仓库,用 ArgoCD 同步到集群,实现「提交 YAML → 自动建/删基础设施」:
- 安装 ArgoCD:加 chart 仓库并安装,取出 admin 密码,端口转发访问 8080。
- 添加仓库(Repository):在 settings → repositories 里添加 Git 仓库(需要 personal access token)。
- 创建应用:填写仓库、路径(如 module2/tencent/cvm)、目标 namespace,设为自动同步。
- 变更即上线:修改仓库里的 VPC YAML(如新增 VPC2 + 改 CIDR),ArgoCD 按轮询拉变更并同步到集群,Crossplane 监听到新 CRD 后调用腾讯 API 创建;ArgoCD UI 里点 Refresh 可跳过同步间隔手动触发。删除时把 YAML 从仓库删掉同步,资源也会被删除。
flowchart LR
REPO[(Git 仓库
跨plane YAML)] -->|ArgoCD 同步| K8S["K8s 集群
CRD: VPC/子网/CVM"]
K8S -->|watch 变更| XP[Crossplane Provider]
XP -->|调用 API| CLOUD[腾讯云资源]至此你就实现了一个「ArgoCD + Crossplane 自建 PaaS」的最小闭环:Infra 作为代码存入 Git,增删改都走 GitOps,无需人工介入。
总结
云原生基础不仅是容器和 Kubernetes,更是一套围绕 DevOps、SRE、AIOps 的现代化工程体系。本章核心脉络:
- 演进脉络:瀑布 → 精益 → 敏捷 → DevOps → SRE → AIOps,后者不是替代前者,而是在协作、可靠性、智能三层叠加能力。
- AIOps 三阶段:监控(数据来源)→ 分析 → 自动化;数据层是核心基础,运维接口能力借助 K8s 声明式得以抽象化,因此 AIOps 必须与云原生结合。
- 大模型两大机遇:数据建模 + 数据分析;用「五层理论」(模型 → Prompt → 思维链 → Agent → 多 Agent 协同)落地,核心技术栈含 JSON Mode、Function Calling、RAG。
- 五大挑战:场景严肃性、数据隐私合规、数据标注缺失、海量实时数据、结合存量工具——每个都有应对方案。
- IaC:声明式、有状态、幂等三大特性;Terraform 用 HCL,核心是
init/plan/apply/destroy+ state + provider + registry。 - 多环境:目录 / workspace / 模块+目录三种方案,推荐模块 + 目录隔离并遵守标准布局。
- PaaS:ArgoCD + Crossplane 实现「YAML → Infra」的 GitOps 自建 PaaS。
说真的这一章全是概念,看着最枯燥,但真到后面写 Operator、调 LLM、做流量预测的时候,回头再看会发现每一步都对得上。DevOps 给你流水线,SRE 给你 SLO,AIOps 在这俩基础上才能落地。
自测题与动手练习
三阶段:① 监控(数据来源,含历史/实时数据)→ ② 分析(归纳/分类/异常检测/关联分析)→ ③ 自动化(按建议或任务自动执行)。
因为无论是机器学习还是数据分析,处理对象都是数据——没有高质量数据,一切的智能分析都无从谈起。
② OpenTelemetry 统一日志/指标/追踪,是 All-in-One 方案,一次集成解决三种数据采集;eBPF 实现零侵入的指标收集与监控(如 Cilium、Falco)。
核心技术栈(都以 Prompt 质量为基础):Prompt Engineering → JSON Mode(稳定输出,作为 LLM 与程序桥梁)→ Function Calling(封装函数调用、链式、意图识别)→ RAG(用知识库解决幻觉/不懂业务)→ 微调(现阶段实践用得少,建议先用现成大模型)。
三大特性:声明式(只描述最终状态)、有状态(对比差异并自动应用)、幂等(每次执行结果都相同)。
state 文件以 JSON 记录真实状态,可能含敏感信息(如密码);单机可放本地/私有 Git,团队协作时放远端(COS/S3/Terraform Cloud),destroy 后清空。
模块化让修改只发生在 module,环境目录只引用模块、几乎不变,不会让各环境差异越来越大,同时通过模块输出(public_ip)串联隐性依赖。
write→plan→apply;Crossplane 是 K8s 控制器,用 CRD/YAML 声明式管理基础设施,Controller 持续 watch CRD 变化并调用云厂商 API。YAML → Infra 流程:把 Crossplane 的 YAML 存入 Git → ArgoCD 同步到集群 → Crossplane 监听到 CRD 变更 → 调腾讯 API 创建/删除资源。增删改全走 GitOps,无需人工介入,适合自研 PaaS。
动手练习(建议真做一遍):
- 用腾讯云 + Terraform 开通一台 CVM,体验
plan看变更 →apply→destroy全流程;再把密钥改用TF_VAR_环境变量方式传(而不是写进代码)。 - 把 IaC 按
main/output/variables/versions拆分,再用 Crossplane 的 YAML(VPC + 子网 + CVM)创建资源,最后接入 ArgoCD 体验一次「改 Git → 自动建资源」。 - 把 Teraform 代码重构为「模块 + dev/testing 目录」结构,改一次 module 让两个环境同时生效,体会模块化多环境的收益。
本章小结
- 软件交付从瀑布→精益→敏捷→DevOps→SRE→AIOps 持续演进,后者不是替代前者,而是在协作、可靠性、智能三层叠加能力。
- AIOps = 使用 AI(ML/LLM)简化运维工作流;三阶段是监控→分析→自动化,数据是核心基础,运维接口能力靠 K8s 声明式抽象 —— 所以 AIOps 必须与云原生结合。
- 大模型给 AIOps 带来数据建模 + 数据分析两次机遇;用「五层理论」落地,核心技术栈为 Prompt/JSON Node/Function Calling/RAG/微调,落地有五大挑战但都有对策。
- 传统根因分析靠「人工纵向切周期 + 递归上下游」,效率低易选错路线;大模型实现多模态数据 + 混合专家处理,还催生自然语言交互与 Agent 协作。
- IaC 三大特性(声明式/有状态/幂等)带来可审计、可复现、可回滚的收益;Terraform 用 HCL,version 固定用
~>,state 绝不能提交公开 Git。 - 多环境推荐模块 + 目录隔离并遵守标准四文件布局;Paas 自建可走 ArgoCD + Crossplane 的 YAML→Infra 闭环。
- 下一章进入容器和 Kubernetes,届时会用到本章的 IaC 能力搭建测试集群。