目录
敏捷与 Scrum 看板方法 DevOps 文化 团队协作 声明式设计
01

声明式基础设施理念

背景 为什么需要声明式管理?

传统运维使用命令式脚本(Shell、Python 脚本)执行一系列步骤来配置服务器。这种方式存在几个问题:不可重现(同一脚本在不同时间执行可能结果不同)、不可审计(难以追踪谁修改了什么)、容易产生配置漂移(手动修改后与脚本不一致)。

第一性原理: 声明式基础设施的核心是「将期望状态作为事实来源」。用户通过配置文件(如 Terraform 的 HCL、Kubernetes 的 YAML)描述系统的期望状态,工具负责将实际状态调整为期望状态。这种模式将运维从「写脚本执行」转变为「写配置管理」,实现了可版本控制可审计可重现

原理 声明式 · 命令式 · 幂等 · 可重现

特性命令式声明式
描述方式步骤序列(怎么做)目标状态(做什么)
幂等性依赖脚本实现天然幂等
可重现性低(依赖执行环境)高(配置即状态)
代码复用低(函数/模块)高(模块/资源抽象)
审计追溯困难(执行日志)简单(Git 历史)
命令式 vs 声明式 命令式 (Imperative) 1. 安装 nginx 2. 复制配置文件 3. 启动 nginx 4. 打开防火墙端口 声明式 (Declarative) 资源: nginx 版本: 1.24 · 端口: 80 配置: /etc/nginx/nginx.conf 图:命令式关注步骤,声明式关注状态
图:命令式关注步骤,声明式关注状态
▸ 命令式 vs 声明式对比 (Shell vs Terraform)
# 命令式 Shell 脚本 (安装 nginx) apt-get update apt-get install -y nginx=1.24.0 cp nginx.conf /etc/nginx/nginx.conf systemctl start nginx ufw allow 80 # 声明式 Terraform 配置 resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" user_data = <<-EOF #cloud-config packages: - nginx=1.24.0 write_files: - path: /etc/nginx/nginx.conf content: ${file("nginx.conf")} EOF }

演进 脚本 → 配置管理 → 声明式 → GitOps

  • Shell 脚本 (1990s): 命令式,难以维护和复用
  • 配置管理 (2000s): Puppet/Chef 引入声明式 DSL
  • Terraform (2014): 面向云资源的声明式工具,状态管理
  • GitOps (2017+): 声明式 + Git 为事实来源,自动同步
"声明式基础设施是运维从『自动化』走向『代码化』的标志。它让基础设施像应用代码一样被管理——版本控制、代码审查、CI/CD。"
—— IaC 设计哲学

取舍 设计中的权衡

⚡ 声明式 vs 灵活性
声明式工具提供了更好的可维护性,但在处理条件逻辑和复杂流程时不如命令式灵活。需要结合使用 HCL 的条件和循环功能。
🔧 幂等 vs 性能
声明式工具通过检测状态变化来避免重复操作,但额外的状态对比会增加执行时间。对于大型基础设施,需要合理的规划和模块划分。
📊 学习曲线 vs 长期收益
声明式工具的学习曲线较陡,但长期来看,可维护性和团队协作的收益远超学习成本。
02

Terraform 工作原理与状态管理

背景 Terraform 如何管理云资源?

Terraform 是 HashiCorp 开发的声明式基础设施即代码工具,专为管理云资源(AWS、Azure、GCP 等)而设计。它的核心能力包括:资源依赖解析状态管理执行计划模块化

第一性原理: Terraform 的本质是一个「状态驱动的资源编排引擎」。它通过 terraform apply 将用户定义的配置转换为实际的云资源,并将当前状态存储在 terraform.tfstate 文件中。每个资源在状态中都有唯一的资源 ID,用于跟踪资源的生命周期。状态文件不仅是存储,还是资源依赖图的缓存,使得 Terraform 可以高效地执行增量更新。

原理 资源图 · 状态文件 · 锁 · 模块

核心工作流程:

  1. 编写配置: 使用 HCL 编写资源定义
  2. 初始化: terraform init 下载 Provider 和模块
  3. 生成计划: terraform plan 对比当前状态与期望状态
  4. 应用变更: terraform apply 执行变更,更新状态文件
Terraform 工作流程 配置 (.tf) 期望状态 Plan 差异分析 Apply 执行变更 状态 .tfstate 循环:状态反馈给计划阶段,对比生成差异 远程状态存储 (S3/Terraform Cloud) + 状态锁 (DynamoDB) 防止并发冲突 图:Terraform 工作流程,状态文件是核心
图:Terraform 工作流程,状态文件是核心
▸ Terraform 状态管理与远程存储
# 使用 S3 存储远程状态,DynamoDB 实现锁 terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock" } } # 查看当前状态 terraform show # 状态列表 terraform state list # 移除某个资源(不删除实际资源) terraform state rm aws_instance.web # 导入已有资源到状态 terraform import aws_instance.web i-1234567890abcdef0

演进 本地状态 → 远程状态 → 状态锁 → 工作区

  • 本地状态 (Terraform 0.x): 状态文件保存在本地,团队协作困难
  • 远程状态 (Terraform 0.9+): 支持 S3、Azure Storage 等远程后端
  • 状态锁 (Terraform 0.11+): 使用 DynamoDB 等实现并发控制
  • 工作区 (Terraform 0.10+): 支持多环境(dev/staging/prod)共享同一套配置
"状态管理是 Terraform 最核心也最具争议的部分。状态文件让 Terraform 具备了『记忆』,但同时也引入了团队协作和安全性挑战。远程状态 + 锁机制的引入使得 Terraform 真正可用于生产环境。"
—— Terraform 设计哲学

取舍 设计中的权衡

📦 状态 vs 无状态
状态文件让 Terraform 可以增量更新,但一旦状态损坏或丢失,恢复成本很高。需要定期备份状态和启用远程存储。
🔒 锁 vs 并发
状态锁防止并发冲突,但在极端情况下可能导致死锁。需要合理设置锁超时和重试策略。
⚡ 模块 vs 复杂性
模块化可以提高复用性,但模块嵌套过深会增加学习成本和调试难度。需要平衡模块粒度。
03

Ansible 无 agent 架构

背景 为什么 Ansible 不需要安装客户端?

Puppet 和 Chef 需要在目标服务器上安装 Agent,管理成本高且存在兼容性问题。Ansible 的设计目标之一是无 Agent——通过 SSH 协议直接管理远程服务器。这种架构降低了维护成本,也使得 Ansible 可以管理更广泛的设备(包括网络设备和云实例)。

第一性原理: Ansible 的无 agent 架构本质是「利用现有的 SSH 连接来执行任务」。控制节点通过 SSH 连接到目标主机,执行 Python 脚本(或 shell 命令),然后断开连接。所有操作都是一次性的,不需要在目标主机上持久化运行任何服务。这种设计极大地简化了部署审计,但也意味着 Ansible 更适合配置管理临时任务,而非持续监控。

原理 SSH 连接 · 模块 · Playbook · 幂等性

Ansible 核心组件:

  • 控制节点: 运行 Ansible 的机器
  • Inventory: 目标主机列表
  • 模块: 执行特定任务的单元,如 copyyumservice
  • Playbook: 用 YAML 编写的一系列任务
Ansible 无 agent 架构 控制节点 Playbook / Module SSH 目标主机 Python · 无 Agent 目标 2 目标 3 Ansible 通过 SSH 同时管理多台主机 模块执行流程:控制节点 → SSH 发送模块代码 → 目标主机执行 → 返回结果 图:Ansible 无 agent 架构,通过 SSH 直接管理目标主机
图:Ansible 无 agent 架构,通过 SSH 直接管理目标主机
▸ Ansible Playbook 示例
# 安装并启动 nginx - name: Install nginx hosts: webservers become: yes tasks: - name: Install nginx package yum: name: nginx state: present - name: Copy nginx config copy: src: nginx.conf dest: /etc/nginx/nginx.conf notify: restart nginx - name: Enable and start nginx service: name: nginx state: started enabled: yes handlers: - name: restart nginx service: name: nginx state: restarted # 执行 Playbook ansible-playbook -i inventory.ini nginx.yml

演进 Agent 模式 → 无 Agent → Ansible 自动化平台

  • Agent 模式 (2000s): Puppet/Chef 需要在每台服务器安装 Agent
  • 无 Agent (2012+): Ansible 通过 SSH 管理,无需安装客户端
  • Ansible Tower (2015): Web 界面与 RBAC,企业级管理
  • Ansible Automation Platform (2020+): 集成事件驱动、分析、治理
"Ansible 的无 agent 架构是一次『去繁就简』的创新。它让配置管理工具的门槛大幅降低,也让安全审计变得更加轻松。"
—— Ansible 设计哲学

取舍 设计中的权衡

⚡ SSH vs Agent 效率
SSH 连接建立和认证有开销,对于大规模管理(数千台服务器)性能不如 Agent 模式。可以使用 ansible-pull 或持久化连接优化。
🔧 幂等 vs 执行速度
Ansible 模块天然是幂等的,但幂等检查需要额外的状态判断,会增加执行时间。对于非关键任务,可以使用 force: yes 跳过检查。
📊 配置管理 vs 编排
Ansible 擅长配置管理,但对于复杂的依赖和资源编排(如创建云资源并等待),Terraform 更适合。两者可以结合使用。
04

不可变基础设施

背景 为什么修改服务器比替换服务器更危险?

传统运维模式是可变基础设施:通过 SSH 连接到服务器,执行命令修改配置、安装更新、调试问题。这种方式的问题在于:配置漂移(不同服务器之间状态不一致)、难以回滚(修改后无法回退到之前状态)、不可重现(手动修改的操作难以追溯)。

第一性原理: 不可变基础设施的核心是「绝不修改正在运行的服务器」。当需要更新时,创建新的服务器实例(基于新的镜像),然后将流量切换到新实例,最后销毁旧实例。这种模式确保了一致性——所有运行中的服务器都是通过相同的镜像构建的,没有累积的漂移。同时,回滚变得极其简单——只需将流量切换回旧版本的镜像。

原理 镜像构建 · 金丝雀发布 · 自动回滚

不可变基础设施最佳实践:

  • 构建不可变镜像: 使用 Packer 构建包含应用和配置的 AMI/Docker 镜像
  • 自动替换: 使用 Terraform/Auto Scaling Group 自动替换实例
  • 金丝雀发布: 逐步替换实例,监控成功率
  • 自动回滚: 故障时自动切回旧镜像
可变 vs 不可变基础设施 可变基础设施 1. SSH 连接到服务器 A 2. 执行 apt-get update 3. 修改 nginx 配置 4. 重启服务 5. 服务器状态:不一致 / 可漂移 不可变基础设施 1. 构建新镜像 (v2) 2. 启动新实例 (基于 v2) 3. 验证新实例健康 4. 切换流量到新实例 5. 销毁旧实例 (v1) 图:可变 vs 不可变,不可变确保一致性和可回滚
图:可变 vs 不可变,不可变确保一致性和可回滚
▸ Packer + Terraform 实现不可变基础设施
# Packer 构建镜像 (AWS AMI) { "builders": [{ "type": "amazon-ebs", "region": "us-east-1", "source_ami": "ami-0c55b159cbfafe1f0", "instance_type": "t2.micro", "ssh_username": "ubuntu" }], "provisioners": [{ "type": "shell", "inline": [ "sudo apt-get update", "sudo apt-get install -y nginx", "sudo systemctl enable nginx" ] }] } # Terraform 使用镜像 resource "aws_launch_template" "web" { image_id = data.aws_ami.latest.id instance_type = "t2.micro" user_data = <<-EOF #!/bin/bash # 启动时运行用户数据 EOF } # Auto Scaling Group 实现自动替换 resource "aws_autoscaling_group" "web" { launch_template { id = aws_launch_template.web.id } min_size = 3 max_size = 6 }

演进 可变 → 不可变 → 滚动替换

  • 可变 (传统): 手动修改,配置漂移难以控制
  • 不可变 (2013+): 通过替换实例实现更新,一致性好
  • 滚动替换 (2015+): 逐步替换实例,实现零宕机
  • 金丝雀 + 自动回滚 (2017+): 结合指标监控,实现自动化决策
"不可变基础设施是『把服务器当作 cattle 而不是 pets』哲学的终极体现。它让运维从 SSH 修补的泥潭中解脱出来,真正实现了自动化和可编程。"
—— 基础设施设计哲学

取舍 设计中的权衡

⚡ 替换 vs 修补
替换新实例比修补现有实例更耗时(等待新实例启动、健康检查),但替换避免了累积的漂移和难以追踪的副作用。
🔧 镜像构建 vs 即时配置
构建镜像需要提前准备,对于快速变化的配置可能不够灵活。结合 Ansible 进行镜像构建是一种常见模式。
📦 存储 vs 回滚
不可变基础设施需要保留旧版本镜像,以便快速回滚。合理的镜像保留策略可以平衡存储成本和回滚能力。
05

配置漂移

背景 实际状态与期望状态不一致怎么办?

即使采用了 IaC,运维人员仍然可能通过 SSH 临时修改服务器,或者某些自动化工具意外更改了配置。这种实际状态与期望状态之间的差异就是配置漂移。漂移可能导致安全漏洞、应用故障、难以调试等问题。

第一性原理: 配置漂移的本质是「系统的实际状态偏离了代码中定义的状态」。解决漂移的方案有两种:检测 + 修复(定期扫描并纠正偏离)和预防(使用不可变基础设施和自动化工具减少手动操作)。理想的策略是预防为主,检测为辅

原理 漂移检测 · 自动修复 · 审计追溯

检测方法:

  • 定期执行 terraform plan 对比当前状态与期望状态
  • 持续监控: 使用 AWS Config、Google Cloud Asset Inventory
  • 日志审计: 记录所有变更操作

修复策略:

  • 自动修复: terraform apply -auto-approve 定时执行
  • 手动修复: 人工介入,确认变更合理性
  • 替换实例: 如果漂移严重,直接替换实例
配置漂移检测与修复 期望状态 Git + IaC 对比 实际状态 运行时 检测到漂移 → 修复操作 修复选项:自动应用 IaC (terraform apply) / 手动修正 / 替换实例 图:配置漂移检测流程,对比期望与实际状态
图:配置漂移检测流程,对比期望与实际状态
▸ 漂移检测与修复自动化
# 定时执行 Terraform plan 检测漂移 (Cron 作业) 0 6 * * * cd /path/to/terraform && terraform plan -no-color > /var/log/terraform-plan.log # 如果检测到漂移,自动修复 (谨慎使用) 0 7 * * * cd /path/to/terraform && terraform apply -auto-approve # 使用 AWS Config 检测漂移 resource "aws_config_config_rule" "terraform_drift" { name = "terraform-drift-detection" source { owner = "AWS" source_identifier = "CLOUDWATCH_LOGS_GROUP_NOT_ENCRYPTED" } } # Ansible 检测漂移 (ansible-diff) ansible-playbook -i inventory.ini nginx.yml --check --diff

演进 手动检测 → 自动检测 → 自动修复 → 预防

  • 手动检测 (早期): 运维人员定期检查配置差异
  • 自动检测 (2010+): 使用 Terraform plan 或 AWS Config 自动检测
  • 自动修复 (2015+): 结合 CI/CD 定时执行 terraform apply
  • 预防 (2018+): 不可变基础设施 + GitOps + 零信任网络
"配置漂移是 IaC 的『天敌』。最好的解决方案是预防——使用不可变基础设施和 GitOps 确保实际状态永远与代码一致。当预防失效时,自动检测和修复提供了第二道防线。"
—— 漂移设计哲学

取舍 设计中的权衡

⚡ 自动修复 vs 安全风险
自动修复可以提高效率,但如果检测到错误的变更(如安全漏洞),自动修复可能会将漏洞重新引入。需要结合人工审批和安全评估。
🔧 检测频率 vs 性能
高频检测可以及时发现漂移,但会增加 API 调用和资源消耗。需要根据基础设施的变更频率合理设置检测周期。
📊 不可变 vs 可调
不可变基础设施完全杜绝漂移,但牺牲了运行时调整的灵活性。对于需要频繁调整配置的场景,需要结合自动化配置管理工具。