Operator + Terraform 对传统运维的改变
Posted on Fri 23 January 2026 in Journal
| Abstract | Journal on 2026-01-23 |
|---|---|
| Authors | Walter Fan |
| Category | learning note |
| Status | v1.0 |
| Updated | 2026-01-23 |
| License | CC-BY-NC-ND 4.0 |
还记得2025的一个冬天, 接近深夜零点, 我刚刚进入梦乡, 一阵警铃大作, 我以为发生了火灾, 赶紧爬起来查看, 原来是手机中安装的 Pageduty App 的呼叫, 原来是产线发生的严重事故, 需要我立即上线参加在线会议.
传统运维的痛点, 就是需要人肉运维.
而 Operator + Terraform 做的事,说白了就是把“处理故障的手艺”从人的脑袋里,搬进系统里,让系统自己干活。复杂度没减少,但复杂度从不可控的人,转移到了可控的代码。
一句话总览(给忙人/管理层的)
传统运维:人 + 文档 + 手工步骤
新运维(IaC + Operator):代码 + 期望状态 + 控制器自动对齐
如果你只能记住一句:
过去回答“怎么做”,现在只回答“我想要什么”。
先别打架:Terraform 和 Operator 分工不同
很多人把它俩混成“一坨自动化”,其实它们分别管两件事:
- Terraform(IaC):更像“施工图纸 + 验收单”,负责把基础设施建出来(VPC、IAM、K8s 集群、LB、数据库实例等)
- Operator(控制器):更像“自动驾驶 + 维修工”,负责运行时的全生命周期(创建、扩容、升级、故障恢复、下线)
一句话:
- Terraform 管“建房子”
- Operator 管“住进去之后还得一直好好活着”
传统运维被改造的 7 个关键点(按“之前 → 现在”讲)
1) 从「人治」到「法治」
之前:经验靠老员工、Wiki、口口相传;流程像武功秘籍,“只传内门弟子”。
现在:经验写进 Terraform(基础设施)和 Operator(运行时逻辑),系统自动执行扩容、修复、回滚。
一句话总结:经验 = 代码,代码 = 事实(而不是“我记得上次是这么干的”)
2) 从「点鼠标」到「写代码」
之前:云控制台一顿点,改完心里没底;问题是三连:不可回放、不可审计、不一致。
现在(Terraform):
infra = Git Repo
变更 = PR
审核 = Review
每一次改动都有 Diff、有审批、有回滚路径。
一句话总结:运维进入工程化时代(终于不靠“手感”)
3) 从「操作步骤」到「期望状态」
之前(步骤驱动):
- 先起一台机器
- 装 MySQL
- 配主从
- 挂了按步骤修
现在(期望状态):
replicas: 3
version: 8.0
highAvailability: true
你只说最终状态,系统自己决定怎么做到。
一句话总结:运维开始像写控制系统:你下“目标”,它跑“控制回路”。
4) 从「一次性部署」到「全生命周期管理」
之前:部署时很认真,部署后就靠人盯;出事再修。
现在(Operator):覆盖创建/扩容/升级/故障恢复/下线。
一句话总结:软件从“装好就不管”变成“养着”(而且是系统自动喂养)
5) 从「被动救火」到「主动自愈」
之前:报警 → 人醒 → 排障。
现在:Pod 挂了自动拉起、Leader 掉了自动选举、副本不够自动补齐。
一句话总结:人从 on-call 主体变成兜底(终于不是“人肉控制器”)
6) 从「环境不一致」到「环境可复制」
之前:Dev/Test/Prod “大概差不多”;问题只在 Prod 出,像玄学。
现在(Terraform):
dev.tfvars
staging.tfvars
prod.tfvars
同一套代码,不同参数。
一句话总结:环境差异从玄学变成 diff
7) 从「运维即职位」到「运维即能力」
之前:开发写代码,运维部署;出了事互相“礼貌甩锅”。
现在:运维能力进入开发团队;运维角色更像平台工程/SRE。
一句话总结:DevOps/Platform 的落地,不是换工具,是换责任边界。
再升一级:传统运维 / DevOps / Platform / SRE 到底啥关系?
先把结论摆在前面:不是替代关系,是演进关系 + 侧重点不同。
核心对照表(全景版)
| 维度 | 传统运维 | DevOps | Platform Engineering | SRE |
|---|---|---|---|---|
| 核心目标 | 系统活着 | 交付更快 | 让团队更高效 | 系统可靠 |
| 关注点 | 服务器 / 软件 | 流程协作 | 平台能力 | SLI / SLO |
| 驱动力 | 人 | 流程 | 产品 | 指标 |
| 工作对象 | 机器 | CI/CD | 内部平台 | 服务 |
| 自动化 | 脚本 | 流水线 | API / Self-Service | 自动化 +预算 |
| 典型工具 | Shell / Ansible | Jenkins / GitLab CI | Terraform / Operator | Prometheus / Alert |
| 知识载体 | 人 / 文档 | 规范 | 平台能力 | 数学 + 工程 |
| 失败应对 | 人工救火 | 快速回滚 | 平台兜底 | Error Budget |
| 对开发的态度 | 服务对象 | 合作对象 | 客户 | 合伙人 |
一句话画像(拿去对外讲很省事)
- 传统运维:「我来帮你把机器弄好」
- DevOps:「我们一起把交付流程打通」
- Platform Engineering:「我给你一套平台,你自己用」
- SRE:「我用工程和数学,保证系统不翻车」
一个关键误区(别再吵了)
DevOps 不是工具;SRE 不是运维升级版;Platform 也不是“运维中台”。
真正区别在于:他们解决的问题不同。
真实案例:MySQL 的四种时代(看完你就懂“演进”)
场景:一个核心业务 MySQL(高可用、可扩展、可升级)
① 传统运维时代:MySQL = 人肉系统
架构:1 主 1 从,裸机/虚机,手工部署
故障:人工判断、手动切主
问题也很“直给”:
- 老范离职 = 系统降级
- 故障恢复慢
- 不可复制
一句话总结:MySQL 的“可用性”在人的大脑里。
② DevOps 时代:MySQL 可部署,但不可自愈
改进点:自动化脚本、CI/CD、标准镜像(Ansible/Docker 这类)
变化:部署快了、环境一致了,但核心问题还在:
- 主挂了 → 人介入
- 扩容 → 人操作
- 升级 → 人盯着
一句话总结:部署自动化 ≠ 运维自动化。
③ Platform Engineering:MySQL 成为“产品”
关键变化:运维不再“接工单”,而是交付能力。
架构演进:Kubernetes + MySQL Operator + Terraform 管 infra
开发者视角:
kind: MySQLCluster
spec:
replicas: 3
version: 8.0
开发只关心:几个节点、版本、SLA。平台团队负责:Operator、备份策略、升级策略、安全默认值。
一句话总结:MySQL = 内部 PaaS 服务。
④ SRE 时代:MySQL 有“数学保证”
到这里,系统已经很自动化了,但还不够“理性”。
SRE 关注:
- SLI:可用性、P99 延迟、复制延迟
- SLO:
MySQL 可用性 ≥ 99.95%
Error Budget(让组织不再靠感觉拍脑袋):
- 允许一年 4.38 小时不可用
- 用完了:禁止功能发布,优先稳定性
一句话总结:SRE 管的是“可靠性债务”(和信用卡一样,刷得爽,还得还)。
一张时间轴理解演进(背下来就能讲)
传统运维
|
v
DevOps(流程)
|
v
Platform(能力)
|
v
SRE(指标与约束)
自动化程度越来越高,人的角色越来越靠近“系统设计者”。
给 CTO / VP 的终极对照(1 分钟讲完)
| 问题 | 谁来回答 |
|---|---|
| 机器怎么建 | Terraform |
| MySQL 怎么活 | Operator |
| 谁能自助用 | Platform |
| 稳不稳定 | SRE |
实战案例:用 Terraform + Operator 一键部署 WordPress
光讲理论容易"听君一席话,如听一席话"。咱们拿一个最经典的场景——部署一个生产级 WordPress 站点——来走一遍完整流程。
先看传统方式有多"酸爽"
假设你要在 AWS 上部署一个 WordPress,传统流程大概是这样:
1. 登录 AWS 控制台,创建 VPC、子网、安全组
2. 开一台 EC2,配置 SSH 密钥
3. SSH 进去,安装 Nginx/Apache + PHP + MySQL
4. 下载 WordPress,解压,配置 wp-config.php
5. 配置 HTTPS 证书(Let's Encrypt 或 ACM)
6. 配置域名解析
7. 测试、调优、祈祷
8. 三个月后:PHP 版本升级?MySQL 挂了?老范呢?
问题很明显:
- 步骤多,容易漏
- 环境不可复制("在我机器上是好的")
- 出了问题全靠人肉排查
- 扩容?再来一遍
新方式:Terraform 建房子,Operator 住进去
我们把整个流程拆成两层:
| 层级 | 负责人 | 工具 | 产出 |
|---|---|---|---|
| 基础设施层 | Terraform | HCL | VPC、EKS 集群、RDS MySQL、ALB、Route53 |
| 应用运行时层 | Kubernetes + WordPress Operator | YAML | WordPress 部署、扩容、升级、备份 |
一句话:Terraform 把"地基+水电"搞定,Operator 把"装修+入住+维护"搞定。
Step 1: Terraform 搞定基础设施
创建一个 main.tf,声明你想要的基础设施:
# main.tf - 基础设施即代码
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# 1. VPC 和网络
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "wordpress-vpc"
cidr = "10.0.0.0/16"
azs = ["${var.aws_region}a", "${var.aws_region}b"]
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
}
# 2. EKS 集群(Kubernetes)
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "19.0.0"
cluster_name = "wordpress-cluster"
cluster_version = "1.28"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
default = {
min_size = 2
max_size = 10
desired_size = 3
instance_types = ["t3.medium"]
}
}
}
# 3. RDS MySQL(WordPress 数据库)
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "6.0.0"
identifier = "wordpress-db"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.medium"
allocated_storage = 20
db_name = "wordpress"
username = "admin"
port = "3306"
vpc_security_group_ids = [module.vpc.default_security_group_id]
subnet_ids = module.vpc.private_subnets
# 生产环境必须开
multi_az = true
backup_retention_period = 7
}
# 4. 输出连接信息(给 Operator 用)
output "eks_cluster_endpoint" {
value = module.eks.cluster_endpoint
}
output "rds_endpoint" {
value = module.rds.db_instance_endpoint
}
变量文件 terraform.tfvars:
aws_region = "us-west-2"
执行三条命令,基础设施就绑了:
terraform init # 初始化
terraform plan # 看看要建啥
terraform apply # 开干(约 15-20 分钟)
这一步完成后,你有了:VPC + EKS 集群 + RDS MySQL + 网络配置。全部可审计、可回滚、可复制。
Step 2: Operator 搞定 WordPress 运行时
基础设施就绪,接下来让 WordPress Operator 接管应用层。这里用 Bitpoke WordPress Operator 作为例子(也可以用 Bitnami Helm Chart,原理类似)。
先安装 Operator(一次性):
# 安装 WordPress Operator(使用 Helm)
helm repo add bitpoke https://helm-charts.bitpoke.io
helm install wordpress-operator bitpoke/wordpress-operator
然后,声明你想要的 WordPress 站点:
# wordpress-site.yaml
apiVersion: wordpress.presslabs.org/v1alpha1
kind: Wordpress
metadata:
name: my-blog
namespace: default
spec:
# 副本数:3 个 Pod,自动负载均衡
replicas: 3
# 域名
domains:
- www.example.com
# TLS 证书(配合 cert-manager 自动签发)
tlsSecretRef: my-blog-tls
# 数据库连接(从 Terraform 输出拿)
dbHost: wordpress-db.xxx.us-west-2.rds.amazonaws.com
dbUser: admin
dbPassword:
secretKeyRef:
name: wordpress-db-secret
key: password
dbName: wordpress
# 媒体文件存储(S3)
mediaVolumeSpec:
s3:
bucket: my-blog-media
region: us-west-2
# 资源限制
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
# WordPress 镜像版本
image: wordpress:6.4-php8.2-apache
一条命令部署:
kubectl apply -f wordpress-site.yaml
Step 3: 见证奇迹的时刻
Operator 会自动完成以下事情:
| 传统方式(人干) | Operator 自动完成 |
|---|---|
| 下载 WordPress | 拉取镜像 |
| 配置 wp-config.php | 注入环境变量 |
| 配置 Nginx/Apache | 创建 Ingress |
| 申请 HTTPS 证书 | 配合 cert-manager 自动签发 |
| 启动 3 个实例 | 创建 3 个 Pod + Service |
| 配置负载均衡 | 创建 LoadBalancer |
| 监控健康状态 | 自动 Health Check |
更爽的是Day 2 运维:
# 流量大了?改一行,自动扩容
spec:
replicas: 10 # 从 3 改成 10
# 新版本?改一行,滚动升级
spec:
image: wordpress:6.5-php8.3-apache
# 数据库挂了?Operator 自动重连
# Pod 挂了?Operator 自动拉起
# 证书快过期?cert-manager 自动续期
完整流程图
┌──────────────────────────────────────────────────────────────┐
│ Git Repository │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ main.tf │ │ wordpress.yaml │ │
│ │ variables.tf │ │ ingress.yaml │ │
│ │ outputs.tf │ │ secrets.yaml │ │
│ └────────┬────────┘ └────────┬────────┘ │
└───────────┼───────────────────────────┼──────────────────────┘
│ │
v v
┌───────────────┐ ┌───────────────┐
│ Terraform │ │ kubectl │
│ apply │ │ apply │
└───────┬───────┘ └───────┬───────┘
│ │
v v
┌───────────────────────┐ ┌───────────────────────┐
│ AWS Infrastructure │ │ Kubernetes Cluster │
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ VPC + Subnets │ │ │ │ WordPress │ │
│ │ EKS Cluster │──┼───┼──│ Operator │ │
│ │ RDS MySQL │ │ │ │ ↓ │ │
│ │ ALB │ │ │ │ WordPress Pods │ │
│ │ Route53 │ │ │ │ (auto-managed) │ │
│ └─────────────────┘ │ │ └─────────────────┘ │
└───────────────────────┘ └───────────────────────┘
一键脚本(CI/CD 集成)
把上面的流程封装成一个脚本,接入 GitLab CI / GitHub Actions:
#!/bin/bash
# deploy-wordpress.sh
set -e
echo "Step 1: Deploying infrastructure with Terraform..."
cd terraform/
terraform init
terraform apply -auto-approve
echo "Step 2: Configuring kubectl..."
aws eks update-kubeconfig --name wordpress-cluster --region us-west-2
echo "Step 3: Installing WordPress Operator (if not exists)..."
helm repo add bitpoke https://helm-charts.bitpoke.io
helm upgrade --install wordpress-operator bitpoke/wordpress-operator
echo "Step 4: Deploying WordPress site..."
cd ../kubernetes/
kubectl apply -f secrets.yaml
kubectl apply -f wordpress-site.yaml
echo "Step 5: Waiting for deployment..."
kubectl rollout status deployment/my-blog-wordpress
echo "Done! Your WordPress site is ready."
kubectl get ingress my-blog -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
从此,部署一个生产级 WordPress 站点 = 一条命令 + 一杯咖啡的时间。
对照:传统 vs 新方式
| 维度 | 传统方式 | Terraform + Operator |
|---|---|---|
| 部署时间 | 2-4 小时(手工) | 20-30 分钟(自动) |
| 环境一致性 | 靠运气 | 100% 可复制 |
| 扩容 | 再来一遍流程 | 改一行 YAML |
| 升级 | 停机 + 祈祷 | 滚动升级,零停机 |
| 故障恢复 | 人肉排查 | 自动重启 + 告警 |
| 回滚 | "上次的配置在哪?" | git revert + terraform apply |
| 审计 | "谁改的?" | Git 提交记录 |
小结:这才是"一键搞定"的真正含义
不是说真的只按一个键,而是把"工程师的手艺"变成可版本控制、可审计、可复制、可自愈的代码。
从此:
- 新环境?
terraform apply一把梭 - 新站点?复制 YAML,改几个参数
- 出故障?Operator 先顶住,你可以慢慢查
- 老范休假?代码不休假
坏处也得说清楚(否则别人以为你在卖课)
- 学习成本陡增:云 + K8s + Terraform + Operator(最好再有点 Controller 思维)
- 复杂度前移:复杂性没有消失,只是从“人”搬到“代码”
- 出问题时更高级:不是重启就完事,可能是状态机/Reconcile bug/State 不一致
但这恰恰是价值所在:至少我们知道复杂度在哪里,并且能用工程方法管起来。
最终总结(两句话收口)
Operator + Terraform 并没有减少运维复杂度,但它把复杂度从“不可控的人”转移到了“可控的代码”。
人话版:把“运维工程师”写进系统里,让运维工程师能休假。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。