传统运维使用命令式脚本(Shell、Python 脚本)执行一系列步骤来配置服务器。这种方式存在几个问题:不可重现(同一脚本在不同时间执行可能结果不同)、不可审计(难以追踪谁修改了什么)、容易产生配置漂移(手动修改后与脚本不一致)。
| 特性 | 命令式 | 声明式 |
|---|---|---|
| 描述方式 | 步骤序列(怎么做) | 目标状态(做什么) |
| 幂等性 | 依赖脚本实现 | 天然幂等 |
| 可重现性 | 低(依赖执行环境) | 高(配置即状态) |
| 代码复用 | 低(函数/模块) | 高(模块/资源抽象) |
| 审计追溯 | 困难(执行日志) | 简单(Git 历史) |
# 命令式 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
}
Terraform 是 HashiCorp 开发的声明式基础设施即代码工具,专为管理云资源(AWS、Azure、GCP 等)而设计。它的核心能力包括:资源依赖解析、状态管理、执行计划、模块化。
核心工作流程:
# 使用 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
Puppet 和 Chef 需要在目标服务器上安装 Agent,管理成本高且存在兼容性问题。Ansible 的设计目标之一是无 Agent——通过 SSH 协议直接管理远程服务器。这种架构降低了维护成本,也使得 Ansible 可以管理更广泛的设备(包括网络设备和云实例)。
Ansible 核心组件:
# 安装并启动 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
传统运维模式是可变基础设施:通过 SSH 连接到服务器,执行命令修改配置、安装更新、调试问题。这种方式的问题在于:配置漂移(不同服务器之间状态不一致)、难以回滚(修改后无法回退到之前状态)、不可重现(手动修改的操作难以追溯)。
不可变基础设施最佳实践:
# 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
}
即使采用了 IaC,运维人员仍然可能通过 SSH 临时修改服务器,或者某些自动化工具意外更改了配置。这种实际状态与期望状态之间的差异就是配置漂移。漂移可能导致安全漏洞、应用故障、难以调试等问题。
检测方法:
修复策略:
# 定时执行 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