云架构设计的实战心得

举报
liujxu 发表于 2026/11/12 10:19:21 2026/11/12
【摘要】 IaC 不是「把手动操作写成代码」,是思维方式的转变很多人对 Terraform 的理解停留在「把控制台点击操作写成 .tf 文件」,这是最常见也最危险的误解。手动操作的思维:先建 VPC → 再建子网 → 再建 ECS → 出错了手动删掉重来。IaC 的思维:描述期望状态(desired state),让工具去算怎么从当前状态到达期望状态。这个区别看起来微妙,影响巨大: 1. 不可变基础...

IaC 不是「把手动操作写成代码」,是思维方式的转变

很多人对 Terraform 的理解停留在「把控制台点击操作写成 .tf 文件」,这是最常见也最危险的误解。

手动操作的思维:先建 VPC → 再建子网 → 再建 ECS → 出错了手动删掉重来。

IaC 的思维:描述期望状态(desired state),让工具去算怎么从当前状态到达期望状态。

这个区别看起来微妙,影响巨大:

1. 不可变基础设施

手动操作里,改一台 ECS 的配置是「登录上去改文件」。IaC 里,改配置是改 .tf 文件然后 apply——Terraform 会销毁旧实例、创建新实例。

这意味着:你的实例必须是可丢弃的。所有状态——数据、配置、会话——都不能存在 ECS 本地,必须外置到 RDS、OBS、DCS 等托管服务。

# 反模式:在 ECS 上存数据
# ECS 挂了 → 数据没了 → 重建后状态丢失

# 正确做法:状态外置
# ECS 挂了 → 重建即可 → 从 RDS/OBS 恢复状态

2. 声明式 vs 命令式

# 声明式:我说我要什么,不管你怎么实现
resource "huaweicloud_compute_instance" "web" {
  count       = 3  # 我要 3 台
  name        = "web-${count.index}"
  flavor_id   = "s6.large.2"
  # ...
}

把 count = 3 改成 count = 5,Terraform 知道只需新增 2 台,不会动已有的 3 台。改成 count = 2,它知道要销毁 1 台。

你不需要写「扩容脚本」和「缩容脚本」,你只需要改一个数字。

3. 状态文件是真相,不是缓存

Terraform 的 terraform.tfstate 记录了「当前基础设施的真实状态」。这个文件是 source of truth——plan 时的 diff 就是拿它和云上实际状态对比算出来的。

所以:

  • 不要手动改 state 文件(用 terraform import 和 terraform state 命令)
  • 不要把 state 提交到 Git(里面有敏感信息,且多人操作会冲突)
  • 用远程 backend(OBS + DynamoDB 锁,支持团队协作)

安全不是加一道墙,是每一层都留一道缝

传统安全思路是「外层防火墙搞定一切」——安全组开 0.0.0.0/0,靠 WAF 挡攻击。

云原生架构里,安全是纵深防御(defense in depth),每一层都有独立的防护:

Internet
  │
  ├── WAF(过滤 SQL 注入、XSS 等)
  │
  ├── ELB(只暴露 443,SSL 终止)
  │
  ├── 安全组(只允许 ELB 的网段访问 ECS 的 8080)
  │
  ├── ECS(非 root 用户运行,最小权限 IAM)
  │
  └── RDS(只允许 ECS 安全组访问,不开公网)

每一层假设上一层已经被突破。即使攻击者穿过了 WAF,安全组也只允许 ELB 访问 ECS;即使拿到了 ECS shell,RDS 也不开公网。

几个我每次 review 都会查的点:

  1. 数据库安全组:源地址是不是 0.0.0.0/0?是不是只允许应用安全组访问?
  2. EIP 绑定:数据库/内部服务有没有误绑 EIP?
  3. IAM 权限:ECS 用的 AK/SK 是不是 Admin 权限?应该最小权限。
  4. 密钥管理:密码是明文写在 .tf 里还是通过变量/密钥管理服务注入?

一个实用原则:如果你不需要从公网访问它,它就不应该有公网入口。听起来像废话,但你会在 review 中惊讶于多少数据库绑了 EIP「为了方便调试」。


成本不是最后才算的,是架构决策的一部分

很多团队的流程是:设计 → 开发 → 部署 → 收到账单 → 震惊 → 开始优化。

成本应该在设计阶段就纳入考量。几个实际决策点:

实例规格:够用就好,不是越大越好

# 反模式:一上来就 s6.2xlarge.4
# 「先给大点,以后再缩」——以后永远不会缩

# 正确做法:从 s6.large.2 开始
# 压测验证 → 不够再升 → 有数据支撑

存储类型:按访问模式选

数据类型 访问模式 推荐存储 成本对比
热数据 高频读写 EVS 高 IO $$$
温数据 低频读写 OBS 标准 $$
冷数据 归档 OBS 低频/归档 $
临时数据 可丢失 ECS 本地盘 免费

弹性伸缩:用最贵的资源时,确保它能缩

固定基线(2 台 s6.large.2)  ← 扛日常流量
     +
弹性层(0-10 台 s6.large.2)  ← 扛峰值流量

峰值时自动扩到 12 台,流量下去后自动缩回 2 台。如果你只有固定 12 台,成本是 6 倍。

一个反直觉的发现:很多团队的成本问题不是「用了太贵的东西」,而是「用了太多便宜的东西」。10 台 s6.small.1 的成本可能超过 2 台 s6.large.2,但后者的性能更好、运维更简单。规模化之前先想清楚单实例效率。


文档不是写给别人看的,是写给三个月后的自己看的

架构文档最容易陷入两个极端:

  1. 没有文档:「代码就是文档」——不,代码告诉你 what,不告诉你 why。
  2. 过度文档:50 页 Word 文档,写完就过时,没人维护。

我找到的平衡点是决策记录(ADR,Architecture Decision Record):

# ADR-007: 选择 RDS for PostgreSQL 而非自建 MySQL

## 背景
应用需要关系型数据库存储订单数据,团队有 PostgreSQL 经验。

## 决策
使用华为云 RDS for PostgreSQL 8.0。

## 理由
1. 托管服务,免运维(备份、补丁、HA 由云厂商负责)
2. 团队有 PG 经验,降低学习成本
3. 主备自动切换,满足可用性要求
4. 与应用同 VPC,内网访问延迟低

## 代价
1. 成本高于自建(但运维成本更低,总体 TCO 更优)
2. 某些 PG 扩展不支持(postgis 不在白名单内)
3. 无法直接访问操作系统层

## 替代方案
- 自建 MySQL on ECS:运维成本高,HA 需自建
- DCS for Redis:不适合关系型数据
- GaussDB:当时团队不熟悉,学习成本高
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。