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) 从「操作步骤」到「期望状态」

之前(步骤驱动)

  1. 先起一台机器
  2. 装 MySQL
  3. 配主从
  4. 挂了按步骤修

现在(期望状态)

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 国际许可协议进行许可。