云架构设计的实战心得
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 都会查的点:
- 数据库安全组:源地址是不是
0.0.0.0/0?是不是只允许应用安全组访问? - EIP 绑定:数据库/内部服务有没有误绑 EIP?
- IAM 权限:ECS 用的 AK/SK 是不是 Admin 权限?应该最小权限。
- 密钥管理:密码是明文写在
.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,但后者的性能更好、运维更简单。规模化之前先想清楚单实例效率。
文档不是写给别人看的,是写给三个月后的自己看的
架构文档最容易陷入两个极端:
- 没有文档:「代码就是文档」——不,代码告诉你 what,不告诉你 why。
- 过度文档: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:当时团队不熟悉,学习成本高
- 点赞
- 收藏
- 关注作者
评论(0)