基础设施即代码(IaC)基础:定义、原则与工具对比
基础设施即代码(Infrastructure as Code, IaC)是平台工程与 SRE 实践的基石。它通过机器可读的定义文件(而非手动配置)来管理和配置基础设施,将传统运维的“手工操作”转变为“代码驱动”。本章将深入剖析 IaC 的核心定义、声明式与命令式的根本差异、主流工具 Terraform 与 Pulumi 的对比,以及 IaC 在云原生环境中的关键角色。
1. IaC 的定义与核心原则
IaC 是一种通过代码(而非手动流程)来定义、部署和管理基础设施的实践。其核心目标是实现基础设施的版本控制、自动化、可重复性和一致性。
核心原则:
- 幂等性(Idempotency): 无论执行多少次,最终状态始终与定义一致。
- 版本控制(Version Control): 所有基础设施定义文件(如 Terraform 的 .tf 文件)都应存储在 Git 中,支持回滚、审计与协作。
- 自动化(Automation): 通过 CI/CD 管道自动执行基础设施的创建、更新与销毁,消除人为错误。
- 自文档化(Self-Documenting): 代码本身就是基础设施的精确文档,无需额外维护独立的文档。
- 可测试性(Testability): 基础设施代码可以像应用代码一样进行单元测试、集成测试和合规性检查。
2. 声明式 vs 命令式:两种范式的根本差异
IaC 工具主要分为声明式(Declarative)和命令式(Imperative)两种范式。理解其差异是选择工具和设计架构的前提。
| 维度 | 声明式(Declarative) | 命令式(Imperative) |
|---|---|---|
| 核心思想 | 描述“最终状态是什么” | 描述“如何一步步达到状态” |
| 操作方式 | 用户定义目标状态,工具自动计算并执行变更 | 用户编写具体步骤(创建、删除、更新) |
| 幂等性 | 天然幂等,重复执行结果一致 | 需手动保证幂等,容易因状态不一致而出错 |
| 可读性 | 高,代码直接反映最终架构 | 低,代码反映的是操作流程,而非最终架构 |
| 典型工具 | Terraform, Pulumi (YAML/JSON), AWS CloudFormation | Ansible (Playbook), Chef (Recipe), Shell 脚本 |
| 适用场景 | 云资源编排、长期运行的基础设施 | 配置管理、一次性任务、复杂逻辑控制 |
平台工程建议: 在编排弹性伸缩任务时,优先采用声明式范式。例如,使用 Terraform 定义“集群期望节点数为 10”,而非编写脚本“如果节点数小于 10,则创建节点”。声明式能更好地应对云环境的动态变化,避免“配置漂移”。
3. Terraform 与 Pulumi 对比
Terraform 和 Pulumi 是目前最主流的声明式 IaC 工具。Terraform 使用 HCL(HashiCorp Configuration Language),而 Pulumi 允许使用通用编程语言(TypeScript, Python, Go, C# 等)。
| 对比维度 | Terraform | Pulumi |
|---|---|---|
| 语言 | HCL(领域特定语言) | 通用语言(TS, Python, Go, C#) |
| 状态管理 | 后端存储(S3, Consul, Terraform Cloud) | 后端存储(S3, GCS, Pulumi Cloud) |
| 模块化 | Registry 模块,版本化 | 包管理器(npm, pip, go mod) |
| 循环/条件 | count, for_each, 条件表达式 | 原生语言循环(for, while) |
| 调试体验 | Plan/Apply 流程,日志级别 | IDE 调试器,断点,堆栈跟踪 |
| 生态成熟度 | 极高,Provider 丰富,社区庞大 | 高,增长迅速,云原生支持好 |
| 学习曲线 | 中等(需学习 HCL) | 低(复用已有编程技能) |
选型注意: 如果团队以运维/SRE 为主,且对 HCL 接受度高,Terraform 是更稳妥的选择。如果团队以开发工程师为主,且希望利用 IDE 的代码补全、类型检查和调试能力,Pulumi 能显著提升效率。在弹性伸缩场景中,Pulumi 的循环和条件逻辑更适合编写复杂的伸缩策略。
4. IaC 在云原生环境中的角色
在云原生环境中,IaC 不仅是资源管理工具,更是整个平台工程体系的“粘合剂”。它连接了应用部署、网络策略、安全合规和成本管理。
- Kubernetes 集群管理: 使用 Terraform 或 Pulumi 创建 EKS/GKE/AKS 集群,并配置 Node Group、VPC、IAM 角色。
- 弹性伸缩策略定义: 通过 IaC 定义 HPA(Horizontal Pod Autoscaler)、Cluster Autoscaler 和 KEDA 触发器,实现“伸缩即代码”。
- GitOps 集成: IaC 代码存储在 Git 仓库中,通过 ArgoCD 或 Flux 自动同步到目标环境,实现“声明式 GitOps”。
- 合规与安全: 在 IaC 代码中嵌入安全策略(如禁止公开 S3 桶),通过 Policy as Code(如 OPA/Sentinel)在部署前自动拦截违规配置。
- 多环境一致性: 通过 IaC 模块化,确保开发、测试、生产环境的基础设施配置完全一致,消除“环境差异”问题。
5. 实践案例:使用 Terraform 定义弹性伸缩策略
以下是一个使用 Terraform 定义 AWS EKS 集群的 Cluster Autoscaler 和 HPA 的简化示例,展示 IaC 如何将伸缩策略代码化。
# 定义 EKS 集群的 Node Group 自动伸缩
resource "aws_eks_node_group" "example" {
cluster_name = aws_eks_cluster.example.name
node_group_name = "example-node-group"
node_role_arn = aws_iam_role.example.arn
subnet_ids = aws_subnet.example[*].id
scaling_config {
desired_size = 2
max_size = 10
min_size = 1
}
# 实例类型
instance_types = ["t3.medium"]
}
# 定义 HPA(通过 Kubernetes Provider)
resource "kubernetes_horizontal_pod_autoscaler_v2" "example" {
metadata {
name = "example-hpa"
}
spec {
max_replicas = 20
min_replicas = 2
scale_target_ref {
api_version = "apps/v1"
kind = "Deployment"
name = "example-app"
}
metric {
type = "Resource"
resource {
name = "cpu"
target {
type = "Utilization"
average_utilization = 70
}
}
}
}
}
关键点: 通过 IaC 定义伸缩策略后,任何对伸缩参数的修改(如调整 max_size 或 CPU 阈值)都需经过代码审查(Code Review)和 CI/CD 管道,确保变更可追溯、可回滚。这避免了运维人员直接在生产环境手动修改伸缩组带来的风险。