AWS网络架构解析
在 AWS 上跑任何应用,都绕不开三个网络问题:服务怎么被用户访问、容器怎么访问外部 API、数据库怎么不暴露到公网。回答这三个问题需要理解一组组件:路由表、IGW、NAT Gateway、安全组、VPC Endpoint。本文按机制原理逐层拆开,不堆 API 字段、只回答 “ 为什么这样实现 “。
1. VPC 与 Region/AZ 关系
先把地基铺平:VPC 是 Region 内的一张虚拟网络,可以横跨同 Region 内多个 AZ,但不能跨 Region。AZ(Availability Zone)是同 Region 内物理隔离的机房,毫秒级延迟互通。生产环境跨 AZ 部署是高可用的最低门槛——任一 AZ 整体故障时,其它 AZ 还能扛住流量。
VPC 不是物理交换机,而是 AWS 基于 SDN 实现的一套虚拟地址系统:用户在控制台看到的 10.0.1.5 只是一条逻辑记录,真实包在 AWS 物理网络上转发时会被加一层封装,宿主机之间靠一张全局映射表寻址。这层抽象决定了一件事:VPC 主 CIDR 一旦创建就不能改——它是映射表的主索引,改主索引等于重建全表。要扩容只能挂辅助 CIDR。
因此规划阶段切 CIDR 一定要留足余地,详见 §12。
1.1 VPC 内部互通
同一 VPC 里两台 EC2 互相 ping,宿主机查映射表拿到对端物理位置后封装转发,对用户视角的 10.0.0.0/16 完全透明,不走二层广播。
1.2 关键边界
| 维度 | VPC 不是什么 | VPC 是什么 |
|---|---|---|
| 物理实体 | 不是一台虚拟交换机 | SDN 控制平面里的一条租户记录 |
| 跨 Region | 不能 | 仅在 Region 内可跨 AZ |
| 主 CIDR | 不能改 | 只能追加辅助 CIDR |
配额(us-west-2,2026-04 快照):每账户每 Region 默认 5 个 VPC、每 VPC 默认 200 个子网、每路由表默认 50 条手动路由、每 SG 默认 60 入 + 60 出且 SG×规则 ≤ 1,000。多数瓶颈出在子网数和路由条目上。
2. 路由表:流量导航的唯一裁判
“ 这个子网是公有还是私有?” 唯一可靠的判定是:子网关联的路由表里,0.0.0.0/0 指向哪里。指 IGW 即公有,指 NAT GW 即私有,不存在这条规则即隔离子网。子网的名字、Tag、CIDR 段都是给人看的;路由表才是给数据包看的。
2.1 最长前缀匹配
路由表匹配规则只有一条——最长前缀匹配,越具体优先级越高,与下发顺序、AZ 编号都无关。同时存在 10.0.1.0/24、10.0.0.0/16、0.0.0.0/0 三条规则时,去 10.0.1.5 走 /24,去 10.0.2.5 走 /16,去外网才落到 /0 默认路由。AWS 路由表没有 “ 自定义优先级 “ 字段,工程师能控制的只有 “ 前缀写多细 “。
每张路由表自带一条不可删除的 local 路由——目标是 VPC 主 CIDR、下一跳为 local,覆盖整个 VPC 内部互通。每个 VPC 有且只有一张主路由表(Main Route Table),未做显式关联的子网默认套用它。生产实践强烈建议每个子网都做显式关联,主表只留作 fallback;否则新建子网会沉默继承到主表的出口,是 AWS 网络事故里出现频次最高的几个根因之一。
2.2 三种子网形态
flowchart LR
PUB[公有子网]:::pub --> RT1[路由表A<br/>0.0.0.0/0 → IGW]:::rt --> IGW((IGW)):::gw
PRI[私有子网]:::pri --> RT2[路由表B<br/>0.0.0.0/0 → NAT GW]:::rt --> NAT((NAT GW)):::warn
ISO[隔离子网]:::iso --> RT3[路由表C<br/>仅 local]:::rt
classDef pub fill:#10B981,stroke:#10B981,color:#fff
classDef pri fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef iso fill:#EF4444,stroke:#EF4444,color:#fff
classDef rt fill:#fff,stroke:#3B82F6,color:#3B82F6
classDef gw fill:#10B981,stroke:#10B981,color:#fff
classDef warn fill:#F59E0B,stroke:#F59E0B,color:#fff| 看到这条规则 | 子网类型 | 典型用途 |
|---|---|---|
0.0.0.0/0 → igw-xxx | 公有子网 | ALB、NAT GW、堡垒机 |
0.0.0.0/0 → nat-xxx | 私有子网 | 应用层 EC2/ECS、Lambda VPC |
仅 local 一条 | 隔离子网 | RDS、ElastiCache、内网中间件 |
2.3 QA
Q:判断子网公有还是私有,最可靠的方式?
A:看其关联路由表中 0.0.0.0/0 的下一跳——指 IGW 即公有,指 NAT GW 即私有,都没有就是隔离子网。
3. IGW 与公有 IP 的真相
“ 挂了 IGW 怎么还连不上网?” 是 AWS 工单频率最高的一类提问。误区是把 IGW 当 “ 上网开关 “。事实:IGW 不会给任何资源分配公有 IP,只负责把已经持有公有 IP 的包转出去。
资源真正能上网需要两个必要条件:① 子网路由表的 0.0.0.0/0 指向 IGW;② 实例的 ENI 上已经绑了公有 IP(自动分配、启动时勾选、绑定弹性 IP 三选一)。两者缺一不可。
3.1 1:1 静态 NAT,无状态
IGW 的实现是 1:1 静态 NAT:每张持有公有 IPv4 的 ENI,在 IGW 内部都对应一条静态映射 私有 IP ↔ 公有 IP,出站时改源地址,入站时改目的地址。这条映射的关键属性是无状态——IGW 不维护连接表,因此无连接表上限,水平能力随 AWS 骨干带宽线性扩展。这是它和 §4 NAT Gateway 的本质区别。
公有 IPv4 来源只有三种:子网开启 “Auto-assign public IPv4”、启动 EC2 时手动勾选、显式绑定弹性 IP(EIP)。前两种 IP 随实例停止释放,只有 EIP 能跨生命周期保留。
flowchart LR
EC2[EC2 ENI<br/>私有 10.0.1.5<br/>公有 54.1.2.3]:::user --> RT[路由表<br/>0.0.0.0/0 → IGW]:::rt
RT --> IGW{IGW<br/>1:1 静态 NAT<br/>无状态}:::gw
IGW --> NET((Internet)):::net
classDef user fill:#10B981,stroke:#10B981,color:#fff
classDef rt fill:#fff,stroke:#3B82F6,color:#3B82F6
classDef gw fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef net fill:#F59E0B,stroke:#F59E0B,color:#fff3.2 必踩的 4 种组合
路由 0.0.0.0/0 → IGW | ENI 有公有 IP | 能否上网 |
|---|---|---|
| ✅ 有 | ✅ 有 | ✅ 通 |
| ✅ 有 | ❌ 无 | ❌ 出站包无公有源地址,IGW 直接丢 |
| ❌ 无 | ✅ 有 | ❌ 路由表没出口,包走不到 IGW |
| ❌ 无 | ❌ 无 | ❌ 隔离子网 |
3.3 公有 IPv4 收费(重要)
自 2024-02-01 起,AWS 对所有公有 IPv4 收费 $0.005/小时,在用与闲置同价(us-west-2,2026-04 快照,行为变更公告)。EIP 申请下来即使没绑任何 ENI,照样按小时计费。ALB / NAT GW / NLB 自带的公有 IP 同样计入这笔账,不因 “AWS 托管 “ 而豁免。
定期审计闲置 EIP:
1 | aws ec2 describe-addresses --query 'Addresses[?AssociationId==null]' |
4. NAT Gateway
私有子网 ECS 拉镜像偶发超时:SG 放行、路由 0.0.0.0/0 → nat-xxx、NAT GW available、带宽只 2 Gbps,docker pull 却间歇 timeout。问题大概率落在 NAT GW 的端口表上限——IGW 永远不会遇到的瓶颈。
4.1 多对一 PAT,有状态
IGW 是 1:1 静态 NAT,NAT GW 走多对一 NAT(PAT)。把 N 个实例的 (源 IP, 源端口) 重写成 (NAT EIP, 新源端口),回包按一张连接表反向还原。这本账叫 conntrack 表,每个并发连接占一条。NAT GW 自身必须放在公有子网:自身 ENI 走 0.0.0.0/0 → igw-xxx 出网,再把 EIP 替换到包源地址上。
flowchart LR
A[10.0.2.5:45001]:::pri --> NAT
B[10.0.2.6:51200]:::pri --> NAT
C[10.0.2.7:33880]:::pri --> NAT
NAT[NAT GW<br/>EIP 52.x.x.10]:::gw
NAT -->|52.x.x.10:30001| OUT((Internet)):::net
NAT -->|52.x.x.10:30002| OUT
NAT -->|52.x.x.10:30003| OUT
classDef pri fill:#10B981,stroke:#10B981,color:#fff
classDef gw fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef net fill:#F59E0B,stroke:#F59E0B,color:#fff4.2 端口耗尽
单 EIP 对同一 (dst IP, dst port, protocol) 组合最多 55,000 并发(us-west-2,2026-04 快照)。批量任务全打到同一镜像仓库 IP+443 极易触顶——超出后新连接静默丢,CloudWatch 指标 ErrorPortAllocation 立即非零,监控这一条即可:
1 | aws cloudwatch get-metric-statistics \ |
解法是给 NAT GW 关联多个 EIP(Secondary IPv4),按 EIP 数线性扩展并发。
4.3 跨 AZ 陷阱
NAT GW 按 AZ 部署。私有子网在 AZ-b、NAT GW 只起在 AZ-a,AZ-b 出向流量得先跨 AZ。同 Region 跨 AZ $0.01/GB 单方向,回包同价,双向合计 $0.02/GB(us-west-2,2026-04 快照,AWS Pricing API SKU VJSFUFWPB2TZ7RG3 验证)。
| 维度 | 同 AZ(每 AZ 各一 NAT GW) | 跨 AZ(仅 AZ-a 一台) |
|---|---|---|
| 小时费 | $0.045/h × N | $0.045/h × 1 |
| 数据处理费 | $0.045/GB | $0.045/GB |
| 跨 AZ 流量费 | $0/GB | $0.02/GB(双向合计) |
3 AZ 共用 1 台表面省小时费,跑量上来跨 AZ 反超——决策点是流量规模,详见 §14。
4.4 QA
Q:NAT Gateway 为什么必须放在公有子网?
A:自身也要出公网做 PAT,ENI 必须走 0.0.0.0/0 → IGW 才能把流量送出去。
Q:3 个 AZ 应该共用 1 个 NAT GW 吗?
A:流量小可共用省小时费;跑量上去后跨 AZ $0.02/GB 反超,应每 AZ 各起一台。
5. VPC Endpoint
-4 算过一笔账:私有子网经 NAT GW 拉一次 S3,要付 $0.045/GB 数据处理费(us-west-2,2026-04 快照)。把这条流量搬到 VPC Endpoint,对 S3/DynamoDB 的账单可以直接归零。但 Endpoint 分两种:Gateway Endpoint 完全免费,Interface Endpoint 按小时和流量收费。差价根因不在商业策略,而在两者实现机制不同。
简化为一句话:Gateway Endpoint 只动路由表,是路由层的把戏;Interface Endpoint 要在子网起 ENI 并劫持 DNS,按 AZ 起、按资源算钱。后者就是 AWS 所说的 PrivateLink。
5.1 两种实现机制
Gateway Endpoint:在子网关联的路由表里塞一条新规则,目标是 AWS 维护的前缀列表(prefix list 是 “ 某服务当前全部公网 IP 段 “ 的动态名单,形如 pl-xxx,对应 com.amazonaws.us-west-2.s3),下一跳指向 endpoint。包到达后由 SDN 控制面直接送进服务后端,不创建任何 ENI、不消耗子网 IP、不跨 AZ、不需私有 DNS。整条路径在 SDN 平面完成,数据面零新增资源——这才是免费的真正原因。代价是产品口径只支持 S3 与 DynamoDB。
Interface Endpoint:在每个目标 AZ 的子网里创建一张 ENI,分配一个 VPC 内部私有 IP;同时启用私有 DNS,由 Route 53 Resolver 把服务公网域名(如 s3.us-west-2.amazonaws.com)的解析结果改写成 ENI 私有 IP。应用代码无需改动、SDK 不必更新,DNS 一查就走私网。覆盖 100+ 服务(ECR、SQS、CloudWatch、KMS、STS、Secrets Manager 等)。每张 ENI 都是真实占用子网 IP 的资源,AWS 因此按小时和流量计费。
flowchart LR
subgraph G[Gateway 路径 · 免费]
ECS1[ECS]:::user --> RT1[路由表<br/>pl-xxx → vpce]:::rt --> S3A[(S3)]:::svc
end
subgraph I[Interface 路径 · 收费]
ECS2[ECS]:::user --> DNS[私有 DNS<br/>解析到 ENI]:::dns --> ENI[Endpoint ENI<br/>每 AZ 一张]:::eni --> S3B[(ECR / SQS / KMS)]:::svc
end
classDef user fill:#10B981,stroke:#10B981,color:#fff
classDef rt fill:#fff,stroke:#3B82F6,color:#3B82F6
classDef dns fill:#F59E0B,stroke:#F59E0B,color:#fff
classDef eni fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef svc fill:#EF4444,stroke:#EF4444,color:#fff5.2 对比与计费
| 维度 | Gateway Endpoint | Interface Endpoint |
|---|---|---|
| 实现 | 路由表 + 前缀列表 | 子网 ENI + 私有 DNS |
| 支持服务 | 仅 S3 / DynamoDB | 100+(ECR、SQS、CloudWatch …) |
| 每 AZ 部署 | 不需要,VPC 级 | 需要,每 AZ 一张 ENI |
| 费用 | 免费 | $0.01/h/AZ + ~$0.01/GB |
3 AZ 部署一个 Interface Endpoint 静态成本约 $0.03/h ≈ $21.6/月,对换 NAT GW 的 $0.045/GB 数据处理费,每月跑量超 ~480 GB 即回本(us-west-2,2026-04 快照)。
5.3 PrivateLink Service:把自家服务发布给别人
Interface Endpoint 的反面是 PrivateLink Service。把自家的 NLB 暴露给别人的 VPC 私网访问——服务方发布服务(如 SaaS API、跨账号 RDS Proxy),消费者在自己 VPC 内用 Interface Endpoint 接入,流量全程走 AWS 骨干、不出公网。典型场景:
- 企业内部跨账号共享中台 API
- SaaS 厂商把控制面提供给客户 VPC 接入(Snowflake、Datadog 等)
- B2B 数据集成省去 VPN/公网打通
5.4 QA
Q:为什么 Gateway Endpoint 免费而 Interface Endpoint 要付费?
A:Gateway 只在路由表注入前缀列表,无新增数据面资源;Interface 要在每个 AZ 起 ENI,AWS 按 ENI 小时数与流量计费。
Q:S3 同时配 Gateway 和 Interface Endpoint,流量走哪个?
A:Interface 启用私有 DNS 时走 Interface(DNS 先命中 ENI);想走免费 Gateway 需关掉 Interface 的私有 DNS。
6. 安全组与 NACL
安全组只放行入站 80,服务返回的响应包为什么不需要再写一条出站规则?只配一条规则,包却双向都通——这背后是 ENI 在替每条流偷偷记账。
6.1 Conntrack 让 SG “ 有状态 “
每张 ENI 都挂一份连接跟踪表(conntrack table),按 5 元组 (src IP, src port, dst IP, dst port, protocol) 索引每条活跃流。SG 的 “ 有状态 “ 就落在这里:出去的包一旦匹配出站规则,conntrack 立即为反向流量加一条临时表项;回包到达时直接命中表项放行,根本不会再去查入站规则。
高并发反代型实例(API 网关、爬虫汇聚节点)偶发出现 SG 没改却丢包/RST,多半是 conntrack 表项耗尽。CloudWatch 指标 ConntrackAllowanceExceeded 非零就是实锤,解法是升级实例规格或缩短长连接。
6.2 SG Vs NACL
| 维度 | 安全组 SG | 网络 ACL NACL |
|---|---|---|
| 实现机制 | conntrack(有状态) | 无状态,每个包独立判断 |
| 作用层级 | ENI | 子网 |
| 默认行为 | 入站全拒、出站全放 | 入站全放、出站全放 |
| 规则类型 | 仅 allow | allow + deny |
| 评估顺序 | 全部规则取并集 | 按 rule number 从小到大首匹配 |
| 典型用途 | 应用级精细放行 | 子网边界粗粒度黑名单 |
NACL 何时仍要保留:粗粒度 IP 黑名单、多账号共享 VPC 由网络管理员强制边界、合规审计要求子网层留独立策略。日常应用层精细放行仍交给 SG,NACL 只做兜底。
6.3 QA
Q:安全组的 “ 有状态 “ 到底是什么意思?
A:每张 ENI 维护一份 conntrack 表,按 5 元组记录出站流;回包命中表项直接放行,无需在入站再写规则。
7. VPC 内的 DNS
排错经验:” 网络配置看起来都对、Reachability Analyzer 也判可达,但应用就是连不上 “,相当一部分根因不在三四层,而在 DNS。VPC 里的 DNS 由两个开关 + 两类区域决定,先把它们摸清楚。
7.1 两个 VPC 级开关
enableDnsSupport:默认 ON,关掉后 VPC 内部完全没有 DNS 解析。基本不要动。enableDnsHostnames:默认 OFF(旧 VPC)/ ON(控制台新建),决定 EC2 是否自动获得ip-10-0-1-5.us-west-2.compute.internal这种 AWS 默认主机名。Interface Endpoint 私有 DNS、RDS 私有 DNS 端点都依赖这个开关——很多 “ 域名解析不到 ENI 私有 IP” 的问题,根因就是这一开关默认关。
7.2 默认解析器:.2 地址
每个 VPC 主 CIDR 的 +2 地址(如 10.0.0.2)是 AWS 内置的 Route 53 Resolver。EC2 默认 DNS 指向它,由它解析三类东西:
- AWS 公网域名(含 endpoint 私有 DNS 改写)
*.compute.internal默认主机名- 关联到 VPC 的 Route 53 Private Hosted Zone
7.3 Private Hosted Zone
自定义内部域名(如 db.internal.acme.com → rds-prod.xxxxx.us-west-2.rds.amazonaws.com)就靠 Private Hosted Zone。新建 Hosted Zone 时勾 “Private”、关联到目标 VPC、添加 A/CNAME 记录即可。VPC 内的实例自动能解析这些域名,VPC 外(或没关联的 VPC)解析不到。
跨 VPC / 混合云解析:用 Route 53 Resolver Endpoint 在 VPC 边界开通 DNS 转发——Inbound 让本地数据中心解析 VPC 内私有域名,Outbound 让 VPC 解析本地 AD 域名。
7.4 QA
Q:Interface Endpoint 创建好了,应用却仍解析到 S3 公网 IP?
A:99% 是 VPC 的 enableDnsHostnames 关着,私有 DNS 改写未生效。
8. ALB / NLB 与目标组
选 LB 看两件事:协议层、源 IP 处理。
8.1 ALB Vs NLB
ALB(Application LB) 工作在 L7,处理 HTTP/HTTPS。每个 AZ 创建一张 ENI 作为入口,反向代理时会修改源 IP——后端 ENI 看到的 src 是 ALB 自己的内网 IP,应用必须从 X-Forwarded-For 头解析真实客户端 IP(链式追加,最右一跳离 ALB 最近)。2023 年起 cross-zone 默认启用且免费。
NLB(Network LB) 工作在 L4(TCP/UDP),保留源 IP——后端直接看到真实客户端 IP,性能也比 ALB 高一档。代价是 cross-zone 默认禁用:流量只在同 AZ 的目标组成员间分发,启用 cross-zone 后跨 AZ 部分按 $0.01/GB 单方向计费(us-west-2,2026-04 快照)。
| 维度 | ALB | NLB |
|---|---|---|
| 协议层 | L7(HTTP/HTTPS) | L4(TCP/UDP) |
| 源 IP 处理 | 改写为 LB 内网 IP | 保留源 IP |
| Cross-zone 默认 | ON(2023 起) | OFF |
| Cross-zone 计费 | 免费 | 启用后 $0.01/GB/方向 |
| 典型用途 | 网站 / API 网关 | 高性能 TCP / 低延迟 |
8.2 健康检查:实战 80% 的 “ 不通 “ 根因
“ 应用启起来了,ALB 却返回 502/504”,绝大多数死在健康检查。目标组(Target Group)的 Health Check 配置决定了哪些 task 会被纳入流量分发:
- 路径:默认
/,业务侧务必提供轻量/health端点,避免误命中重业务接口 - 协议/端口:要与目标实际监听端口一致;ECS task 端口动态时用
traffic-port - 阈值:
HealthyThresholdCount默认 5、Interval默认 30s——意味着新 task 上线后最长要 2.5 分钟才进入分发,蓝绿发布时容易误判 “ 切流量后 502”
容易踩的两个坑:
- SG 没放行健康检查端口:ALB 的 SG 必须能访问目标组成员端口,且后端实例 SG 必须允许 ALB SG 入站。
- 健康端点返回 4xx 也算失败:默认期望
200,自定义Matcher接受200-399。
8.3 ALB HTTPS 与 ACM
公网 ALB 暴露 HTTPS 必绑证书。AWS Certificate Manager(ACM)签发的证书完全免费,且自动续期。流程:在 ACM 申请域名证书 → DNS 验证(在 Route 53 一键创建 CNAME)→ ALB Listener 选 443 + ACM 证书 ARN。注意证书必须签发在 ALB 所在 Region。
8.4 QA
Q:ALB 后面的应用怎么拿到真实客户端 IP?
A:从 X-Forwarded-For 头取最右一跳 IP——ALB 反代会把源 IP 改成自己的内网地址。
Q:ALB 健康检查 502,应用日志却没收到请求?
A:先查目标组成员的 SG 入站是否放行 ALB SG + 健康检查端口。
9. ECS Fargate 的 Awsvpc 网络模式
Fargate(以及 ECS EC2 模式开启 awsvpc)的网络模型与 EC2 直觉不同:每个 task 独占一张 ENI,不是和宿主机共享。这条事实带出三个常见踩坑点。
9.1 每 Task 一张 ENI 的含义
- 每 task 占一个子网 IP:批量任务(数据处理、scheduled task)一启就吃 IP,子网 /24(256 IP)跑 200 个并发就会撞 IP 不足。CIDR 切片要给私有子网留足空间,详见 §12。
- task 自己的 SG:SG 直接挂在 task 的 ENI 上,不再像 EC2 模式那样 “ 实例 SG 包一切 task”,颗粒度更细。
- ENI 配额:账号有每 Region ENI 总数配额(默认 5,000),大批量 Fargate 时可能撞顶,可提工单上调。
9.2 公网拉镜像的两条路
Fargate task 默认无公网,需要拉 ECR 镜像 / 访问外部 API 时,路径有二选一:
- 走 NAT GW:私有子网路由
0.0.0.0/0 → nat-xxx,最简单但流量都过 NAT 数据处理费 - 挂 ECR Interface Endpoint:ECR 是 Interface Endpoint 大头流量,单服务跑量稍大就值得挂 endpoint,详见 §5
实际生产推荐 NAT GW + ECR endpoint 组合:常规出网走 NAT,镜像拉取走 endpoint 省钱。
9.3 QA
Q:Fargate task 启动失败,日志写 “ 子网 IP 不足 “?
A:每 task 占一个 IP,把私有子网换到 /20 或更大,避免 /24 容量上限。
10. 跨 VPC 互通:Peering Vs TGW Vs PrivateLink
业务长大就会撞到跨 VPC 互通——不同环境(dev/prod)、不同账号(business unit)、不同 Region(多活)。AWS 给了三套工具,选错要么贵要么慢。
10.1 三者对比
VPC Peering:两 VPC 间的点对点直连,无中间设备、无额外计费(仅跨 AZ/Region 流量费)。最便宜、延迟最低,但拓扑是网状——N 个 VPC 全互通要 N(N-1)/2 条 peering,路由表要在每个 VPC 手动维护。CIDR 不能重叠是硬约束。
Transit Gateway(TGW):星型 hub,所有 VPC 接到同一个 TGW、路由集中决策。把网状复杂度从 N² 降到 N,并能同时接 VPN、Direct Connect 把混合云收口。代价是付费组件——按附件小时费 + 数据处理费收。
PrivateLink:通过 NLB + Interface Endpoint 暴露具体服务,不打通整个网段。安全性最高(消费方只能访问发布的服务、看不到对端 VPC 其它资源),但只能做单向服务消费,不适合双向互通。
10.2 选型决策
| 场景 | 推荐 | 理由 |
|---|---|---|
| 2-3 个 VPC 简单互通 | Peering | 便宜,复杂度可控 |
| ≥4 VPC 或跨账号 | TGW | 网状管理成本压不住 |
| 接 VPN / Direct Connect | TGW | 自带混合云接入 |
| 只让对方访问某个 API | PrivateLink | 最小权限、不打通网段 |
| 跨 Region 互联 | TGW Inter-Region Peering | 经 AWS 骨干,更稳 |
10.3 QA
Q:VPC Peering 能传递吗(A↔B、B↔C,A 能访问 C 吗)?
A:不能。Peering 不传递路由,A→C 必须额外建 A↔C peering,这正是 N² 复杂度的来源,也是 TGW 的卖点。
11. SSM Session Manager 替代 Bastion
Bastion Host 是公有子网最常见的角色,但 2026 年还在配它就落伍了。一台带公网 IP、22 端口对外的跳板机,多一个被扫的入口,多一份 SSH key 分发与轮换负担,还要自己拼 syslog 做命令审计;EIP 和常驻 EC2 也在月底账单上一直走表。SSM Session Manager 把这些问题一次抹平。
11.1 反向连接机制
EC2 上的 SSM Agent(Amazon Linux 2/2023、Ubuntu 官方 AMI 默认预装)启动后主动建立到 SSM 服务的 outbound HTTPS 长连接,挂在那里等指令。控制台或 CLI 发起 session 时,指令顺着这条已建立的反向通道下发,全程不走 SSH 协议,22 端口可以彻底关掉。
正因为是反向连接,EC2 既不需要公网 IP、也不需要在 SG 里开任何入站端口。前提只有两条:
- EC2 绑定的 IAM Role 含
AmazonSSMManagedInstanceCorepolicy - 实例所在子网能访问 SSM endpoint:要么走 NAT GW 出公网,要么挂
ssm/ssmmessages/ec2messages三个 Interface VPC Endpoint(私有子网纯内网方案)
任缺一条,session 都连不上。
11.2 Bastion Vs SSM 对比
| 维度 | Bastion Host | SSM Session Manager |
|---|---|---|
| 暴露面 | 公网 IP + 22 端口对外 | 无公网 IP、零入站端口 |
| SG 入站要求 | 允许办公网/VPN 段 22 入站 | 完全不需要入站规则 |
| 操作便利 | 维护 SSH key、跳板登录两跳 | 一条 CLI 直达,无需 key |
| 审计能力 | 自建 syslog/auditd | 原生接 CloudWatch Logs / S3 |
| 费用 | 一台常驻 EC2 + EIP | session 本身免费 |
实战命令一条够用:
1 | aws ssm start-session --target i-0a1b2c3d4e |
11.3 QA
Q:SSM Session Manager 为什么不需要给 EC2 分公有 IP?
A:反向连接——SSM Agent 主动 outbound 到 SSM 服务,指令走这条已建立的通道下发。
12. 三层架构 + CIDR 模板 + Terraform 骨架
12.1 CIDR 切分模板
主 CIDR 取 10.0.0.0/16(65,536 IP),按 /20 切片每段 4,096 IP。前 9 段填满 “3 AZ × (公有 + 私有 + 数据库)” 三层结构,后 7 段保留扩展。
1 | 10.0.0.0/16 (65,536 IPs) |
每段 4,096 个 IP 扣掉 AWS 保留的 5 个还剩 4,091 个,足够单 AZ 跑千级容器编排。预留段后续可整段挪给 EKS Pod 子网、TGW 附加。
12.2 三层架构
flowchart TB
NET((Internet)):::net --> IGW{IGW}:::gw
IGW --> ALB[ALB / 公有]:::pub
ALB --> ECSa[ECS / AZ-a 私有]:::pri
ALB --> ECSb[ECS / AZ-b 私有]:::pri
ALB --> ECSc[ECS / AZ-c 私有]:::pri
ECSa --> RDS[(RDS Multi-AZ<br/>主 AZ-a / 备 AZ-b)]:::db
ECSb --> RDS
ECSc --> RDS
classDef net fill:#F59E0B,stroke:#F59E0B,color:#fff
classDef gw fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef pub fill:#10B981,stroke:#10B981,color:#fff
classDef pri fill:#3B82F6,stroke:#3B82F6,color:#fff
classDef db fill:#EF4444,stroke:#EF4444,color:#fff| 组件 | 部署子网 | 理由 |
|---|---|---|
| ALB | 公有 | 需要被 IGW 直达 |
| NAT GW | 公有 | 自身 ENI 需 0.0.0.0/0 → IGW |
| ECS / Fargate | 私有 | 默认无公网;走 NAT GW 拉镜像 |
| RDS / ElastiCache | 数据库 | 隔离子网,无 0.0.0.0/0 |
| VPC Endpoint (S3/ECR) | 私有 | Interface 型放私有,Gateway 型挂路由 |
生产环境每 AZ 各起一台 NAT GW 是高可用底线——AZ-a 整个挂掉时只部署在 AZ-a 的那台直接消失,依赖它的 AZ-b/c 私有子网会跟着断网。预算紧的非生产环境(dev/staging)才考虑 3 AZ 共用一台省小时费。
12.3 Terraform 最小骨架
社区维护的 terraform-aws-modules/vpc 是事实标准,最小可投产配置:
1 | module "vpc" { |
12.4 QA
Q:3 个 AZ 应该部署几个 NAT GW?
A:生产环境 3 个,每 AZ 一台;任一 AZ 故障不波及其他 AZ 的出网。
13. 排错:Flow Logs + Reachability Analyzer
网络不通时不要靠猜。AWS 提供两个互补工具:Flow Logs 看实际流量,Reachability Analyzer 看路径推断。前者是事后诸葛,记录包真正走没走通;后者是事前分析,纯读配置就能告诉你包会被谁挡。
13.1 两者分工
Flow Logs:粒度可选 ENI / 子网 / VPC 三级,输出去向 S3 / CloudWatch Logs / Kinesis。action 字段只有两个值——ACCEPT 或 REJECT,但不告诉你被哪一层挡(这正是 RA 出场的时机)。
Reachability Analyzer:静态分析路径,读取路由表 + SG + NACL + ENI + TGW / Endpoint 配置,模拟包从源 ENI 到目的 ENI 是否可达,命中阻塞时直接指出 “ 被 SG sg-abc 出站规则拒绝 “ 或 “ 路由表 rtb-xxx 缺 0.0.0.0/0“。注意 RA 仅覆盖 L3/L4,不验证 DNS、TLS、应用握手。
13.2 排错决策树
flowchart TD
S[症状: 应用连不上]:::sym --> Q1{Flow Logs<br/>有包吗?}:::dec
Q1 -->|无包| F1[查 DNS/应用层<br/>包没出 ENI]:::fix
Q1 -->|有包| Q2{action 字段}:::dec
Q2 -->|REJECT| F2[查 SG/NACL<br/>跑 RA 定位规则]:::fix
Q2 -->|ACCEPT| F3[查路由表/对端 SG<br/>包出去回不来]:::fix
classDef sym fill:#EF4444,color:#fff,stroke:#B91C1C
classDef dec fill:#F59E0B,color:#fff,stroke:#B45309
classDef fix fill:#10B981,color:#fff,stroke:#047857Reachability Analyzer 三步走:
1 | aws ec2 create-network-insights-path --source eni-aaa --destination eni-bbb --protocol tcp --destination-port 443 |
| 症状 | Flow Logs 表现 | 第一步 |
|---|---|---|
connection timed out | 出向 ACCEPT、入向无包 | 查对端 SG / 跨 VPC 路由是否回得来 |
connection refused | 双向 ACCEPT | 不是网络问题——查目标端口监听与应用 |
| 完全没日志 | 无记录 | 包没出 ENI——查客户端 DNS、本机路由 |
实战节奏:先开 ENI 级 Flow Logs 抓 5 分钟样本,落到决策树哪个分支后再用 RA 跑 A→B 验证。两步加起来通常 10 分钟内能出结论。
13.3 QA
Q:Reachability Analyzer 和 Flow Logs 的本质区别?
A:RA 是静态分析配置推断路径,Flow Logs 记录实际流量;前者预演、后者取证。
14. 费用全景与省钱手段
VPC 这层抽象本身不收钱:子网、路由表、IGW、SG、NACL 都是免费控制平面。但 VPC 一旦跑起来,每月账单必然冒出几个 “ 账单刺客 “:第一名 NAT GW(小时费 + 数据处理双重计费),第二名跨 AZ 流量(双向各计一次),第三名公有 IPv4(2024-02 起在用与闲置同价)。
14.1 组件费用总表
| 组件 | 费用 | 备注 |
|---|---|---|
| VPC / 子网 / 路由表 / IGW / SG | 免费 | 控制面 |
| NAT GW 小时费 | $0.045/h | 每 AZ 一份独立计费 |
| NAT GW 数据处理 | $0.045/GB | 流量经 NAT 必收 |
| Data Transfer Out to Internet | $0.09/GB(前 10 TB/月) | 任何 EC2 出 Internet 的流量都按此计 |
| 公有 IPv4 | $0.005/h | 在用 / 闲置同价,2024-02 起生效 |
| Gateway Endpoint(S3/DynamoDB) | 免费 | 必配项 |
| Interface Endpoint | $0.01/h/AZ + ~$0.01/GB | 每 AZ 一张 ENI |
| 跨 AZ 流量 | $0.01/GB / 方向(双向 $0.02/GB) | 同 Region 内 |
费率均为 us-west-2,2026-04 快照。来源:VPC Pricing、EC2 On-Demand、Public IPv4 公告、AWS Pricing API SKU VJSFUFWPB2TZ7RG3。
14.2 典型场景算账(三 AZ 中等流量)
- NAT GW 小时费:3 × $0.045/h × 720h = $97.20
- NAT GW 数据处理:100 GB/天 × 30 × $0.045 = $135.00
- Internet 出口流量:3 TB × $0.09 = $276.48 (NAT GW 处理后还要叠 Internet 出口费)
- 公有 IPv4:5 个 ALB × $0.005/h × 720h = $18.00
- 月成本合计 ≈ $526.68
NAT GW 两项 + Internet 出口三项就吃掉 $508.68、占比 96%——刺客名副其实,省钱第一刀必须切在它身上。
14.3 省钱手段
| 手段 | 节省点 | 适用判断标准 |
|---|---|---|
| Gateway Endpoint(S3/DynamoDB) | NAT GW 数据处理 $0.045/GB → 0 | 必配项,无量级门槛 |
| Interface Endpoint(ECR / CW / KMS 等) | NAT GW 流量改走 PrivateLink | 单服务月跑量 > ~480 GB 即回本 |
| 开发环境单 AZ NAT GW | 节省 2/3 NAT 小时费 | 跨 AZ 流量 < 数十 GB / 月时合算 |
| CloudFront 兜底静态资源 | Internet 出口费降到 CDN 价 | 大量公网下行流量 |
排账拆 USAGE_TYPE 维度:
1 | aws ce get-cost-and-usage \ |
grep nat 找 NAT 费用、grep DataTransfer 找跨 AZ 与出口流量。
14.4 QA
Q:NAT GW 单月账单由哪几部分构成?
A:每 AZ 实例 $0.045/h 小时费 + $0.045/GB 数据处理费;出 Internet 的部分还要叠 EC2 Data Transfer Out($0.09/GB 前 10TB)。
15. 避坑清单
| # | 误区 ❌ | 正解 ✅ | 严重度 |
|---|---|---|---|
| 1 | 公有子网里的资源自动有公有 IP | 公有 IP 必须显式分配,子网 “ 自动分配公有 IP” 开关默认关 | 🔴 |
| 2 | 子网名字叫 “public” 就是公有子网 | 唯一标准是路由表是否有 0.0.0.0/0 → IGW,名字纯属注释 | 🔴 |
| 3 | 有了 IGW 就能上网 | IGW 只是门,还需路由表指向它 + 资源持公有 IP/EIP | 🔴 |
| 4 | NAT Gateway 放在私有子网 | NAT GW 自身必须放公有子网(要 IGW 出口) | 🔴 |
| 5 | NAT Gateway 一个就够了 | NAT GW 单 AZ 故障会拖垮其他 AZ 出网,生产应每 AZ 各一台 | 🟡 |
| 6 | 所有出站都走 NAT Gateway | S3/DynamoDB 走 Gateway Endpoint 免费,其它服务走 Interface Endpoint | 🟡 |
| 7 | IGW 和 NAT Gateway 可以互相替代 | IGW 是无状态 1:1 NAT,NAT GW 是有状态 PAT,定位完全相反 | 🟡 |
| 8 | 安全组默认拒绝出站 | 安全组默认全放出站,只默认拒入站;与 NACL 双向默认放行不一样 | 🟡 |
| 9 | 跨 AZ 流量费可忽略 | 双向 $0.02/GB,量大时比 NAT 处理费还贵 | 🟡 |
| 10 | NAT Gateway 端口取之不尽 | 单 EIP 对同一目标 IP:Port 仅约 55K 端口,监控 ErrorPortAllocation | 🟡 |
| 11 | Interface Endpoint 建好就能用 | 关闭 “ 启用私有 DNS” 时原服务域名仍解析到公网 IP,流量绕开 Endpoint | 🟢 |
| 12 | 不用的 EIP 放着没事 | 未关联实例的 EIP 仍按 $0.005/h 计费,约 $3.6/月一个 | 🟢 |
| 13 | VPC 内 DNS 默认就好 | enableDnsHostnames 默认关时 Interface Endpoint 私有 DNS 不生效 | 🟡 |
| 14 | ALB 502 一定是应用挂了 | 多半是健康检查端口未在 SG 放行或 /health 返回非 2xx | 🟡 |