VPC 网络 — CodeRoadMapVPC 网络
这一课你将能做到
- 设计一个跨两个 AZ 的 VPC,包含公有子网和私有子网,并能画出架构图
- 配置路由表、Internet Gateway、NAT Gateway,让公有子网能上网、私有子网能通过 NAT 上网
- 用安全组和网络 ACL 实现分层防护,并说出两者的区别
为什么要学
VPC 是 AWS 网络的「地基」。不懂 VPC,就不知道 EC2 怎么连外网、RDS 怎么被保护、服务之间怎么隔离。本站如果迁到 AWS,数据库必须放私有子网,Web 层放公有子网,这是最基本的安全架构。面试必问「公有子网和私有子网的区别」「NAT Gateway 的作用」。
人话:VPC 就是你在 AWS 里划的一块「内网」,像公司内网一样,有网段、有路由、有防火墙。公有子网是「临街商铺」,能直接开门迎客;私有子网是「后院仓库」,外人进不来,但仓库管理员可以通过专用通道(NAT)出去进货。
先建立图像
经典三层架构 VPC 设计:
VPC: 10.0.0.0/16
├── 公有子网 A: 10.0.1.0/24 (AZ-1a) ←── Internet Gateway
│ └── 负载均衡器 (ALB)
├── 公有子网 B: 10.0.2.0/24 (AZ-1b)
│ └── 负载均衡器 (ALB)
├── 私有子网 A: 10.0.11.0/24 (AZ-1a)
│ └── EC2 应用服务器 ×2
├── 私有子网 B: 10.0.12.0/24 (AZ-1b)
│ └── EC2 应用服务器 ×2
├── 数据库子网 A: 10.0.21.0/24 (AZ-1a)
│ └── RDS 主实例
└── 数据库子网 B: 10.0.22.0/24 (AZ-1b)
└── RDS 备实例
关键组件对照:
| 组件 | 作用 | 本站场景 |
|---|
| VPC | 逻辑隔离的网络空间 | 整个站点的网络边界 |
| 公有子网 | 路由表指向 IGW,可直接上网 | 放 ALB、NAT Gateway |
| 私有子网 | 无 IGW 路由,通过 NAT 上网 | 放 EC2 应用服务器 |
| 数据库子网 | 更严格的私有子网 | 放 RDS,只许应用层访问 |
| IGW | VPC 通往互联网的门 | 公有子网必须配 |
| NAT Gateway | 私有子网出网的代理 | 让私有子网的 EC2 能 yum update |
| 安全组 | 实例级防火墙(有状态) | 控制 EC2/RDS 的端口 |
| 网络 ACL | 子网级防火墙(无状态) | 子网层面的额外防护 |
跟着做
步骤 1:创建 VPC
# 创建 VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=codenav-vpc}]"
# 记录返回的 VpcId,后续都用 vpc-xxxxxxxx 代替
步骤 2:创建子网(跨两个 AZ)
# 公有子网 A
aws ec2 create-subnet --vpc-id vpc-xxxxxxxx --cidr-block 10.0.1.0/24 --availability-zone ap-southeast-1a --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=public-1a}]"
# 公有子网 B
aws ec2 create-subnet --vpc-id vpc-xxxxxxxx --cidr-block 10.0.2.0/24 --availability-zone ap-southeast-1b --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=public-1b}]"
# 私有子网 A
aws ec2 create-subnet --vpc-id vpc-xxxxxxxx --cidr-block 10.0.11.0/24 --availability-zone ap-southeast-1a --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=private-1a}]"
# 私有子网 B
aws ec2 create-subnet --vpc-id vpc-xxxxxxxx --cidr-block 10.0.12.0/24 --availability-zone ap-southeast-1b --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=private-1b}]"
# 数据库子网 A/B(略,同上,用 10.0.21.0/24 和 10.0.22.0/24)
步骤 3:创建并附加 Internet Gateway
# 创建 IGW
aws ec2 create-internet-gateway --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Name,Value=codenav-igw}]"
# 附加到 VPC
aws ec2 attach-internet-gateway --internet-gateway-id igw-xxxxxxxx --vpc-id vpc-xxxxxxxx
步骤 4:配置公有子网路由表
# 创建路由表
aws ec2 create-route-table --vpc-id vpc-xxxxxxxx --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]"
# 添加默认路由指向 IGW
aws ec2 create-route --route-table-id rtb-xxxxxxxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxxxxxxx
# 关联公有子网
aws ec2 associate-route-table --route-table-id rtb-xxxxxxxx --subnet-id subnet-xxxxxxxx
步骤 5:创建 NAT Gateway
# 先申请 EIP(NAT Gateway 需要固定公网 IP)
aws ec2 allocate-address --domain vpc
# 在公有子网创建 NAT Gateway
aws ec2 create-nat-gateway --subnet-id subnet-xxxxxxxx --allocation-id eipalloc-xxxxxxxx --tag-specifications "ResourceType=natgateway,Tags=[{Key=Name,Value=codenav-nat}]"
步骤 6:配置私有子网路由表
# 创建私有路由表
aws ec2 create-route-table --vpc-id vpc-xxxxxxxx --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=private-rt}]"
# 默认路由指向 NAT Gateway
aws ec2 create-route --route-table-id rtb-yyyyyyyy --destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-xxxxxxxx
# 关联私有子网
aws ec2 associate-route-table --route-table-id rtb-yyyyyyyy --subnet-id subnet-yyyyyyyy
步骤 7:配置安全组
# ALB 安全组:允许 80/443 从任意 IP
aws ec2 create-security-group --group-name alb-sg --description "ALB Security Group" --vpc-id vpc-xxxxxxxx
aws ec2 authorize-security-group-ingress --group-id sg-albxxxx --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id sg-albxxxx --protocol tcp --port 443 --cidr 0.0.0.0/0
# 应用安全组:只允许来自 ALB 的 8080
aws ec2 create-security-group --group-name app-sg --description "App Security Group" --vpc-id vpc-xxxxxxxx
aws ec2 authorize-security-group-ingress --group-id sg-appxxxx --protocol tcp --port 8080 --source-group sg-albxxxx
# 数据库安全组:只允许来自应用层的 3306
aws ec2 create-security-group --group-name db-sg --description "DB Security Group" --vpc-id vpc-xxxxxxxx
aws ec2 authorize-security-group-ingress --group-id sg-dbxxxx --protocol tcp --port 3306 --source-group sg-appxxxx
讲清楚要点
- CIDR 规划:VPC 用 /16 有 65536 个 IP,子网用 /24 有 256 个 IP(AWS 保留 5 个)。规划时预留扩展空间,不要一上来把 /16 切满。
- 公有子网的本质:不是子网本身有公网 IP,而是它的路由表有
0.0.0.0/0 → IGW 这条路由。
- NAT Gateway 是单向的:只允许私有子网主动出网,不允许外网主动连进来。这是保护私有子网的关键。
- 安全组是有状态的:你允许 outbound 80 出去,回来的响应自动放行。网络 ACL 是无状态的,出和入都要显式允许。
- 跨 AZ 部署是底线:至少两个 AZ,RDS 多 AZ 部署,ALB 跨 AZ 分发。单 AZ 的架构在面试和现实中都不及格。
你可能会懵的地方
-
NAT Gateway 和 NAT Instance 有什么区别?
NAT Gateway 是托管服务,自动高可用、自动扩展,按小时+流量收费。NAT Instance 是自己开的 EC2 做 NAT,便宜但要自己维护高可用。生产环境一律用 NAT Gateway。
-
私有子网的 EC2 怎么 yum update?
通过 NAT Gateway 出网。或者配 VPC Endpoint(S3 Endpoint、ECR Endpoint 等),让流量走 AWS 内网,不经过 NAT。
-
网络 ACL 到底用不用?
默认的 NACL 允许所有流量,安全组已经够用。但在合规要求高的场景(如金融),会用自定义 NACL 做第二层防护。初学者先掌握安全组。
-
VPC Peering 和 Transit Gateway 是干什么的?
VPC Peering 连接两个 VPC(一对一)。Transit Gateway 是中心辐射型,连接多个 VPC 和本地机房(一对多)。本站初期用不上,但面试常问。
-
IPv6 在 VPC 里怎么用?
AWS 支持 IPv6,子网可以双栈(IPv4 + IPv6)。IPv6 地址默认全球可达,没有 NAT 概念,安全完全靠安全组和 NACL。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 把 RDS 放公有子网 | 数据库直接暴露公网,被扫风险 | RDS 必须放私有子网,安全组只许应用层访问 |
| 私有子网路由表指向 IGW | 私有子网变公有,安全失守 | 私有子网默认路由指向 NAT Gateway |
| 安全组入方向开 0.0.0.0/0 的 22 | 任何 IP 都能 SSH 爆破 | 限制公司 IP 或用 Session Manager |
| 一个 AZ 挂了就全挂 | 单点故障 | 至少跨两个 AZ,ALB 健康检查自动切换 |
| CIDR 和现有网络冲突 | VPN/专线打通后路由冲突 | 规划前确认现有网段,避开 192.168.x.x 和 10.x.x.x 常用段 |
卡点急救
- 私有子网的 EC2 连不上外网:检查私有路由表是否有
0.0.0.0/0 → NAT Gateway;检查 NAT Gateway 是否在公有子网;检查安全组 outbound 是否允许。
- ALB 健康检查失败:检查目标组端口是否正确;检查 EC2 安全组是否允许来自 ALB 安全组的流量;检查应用是否真的在监听。
- 两个子网的 EC2 互相 ping 不通:检查是否在同一 VPC;检查路由表是否有本地路由(
10.0.0.0/16 local 是自动的);检查安全组是否允许 ICMP。
面试常问
-
公有子网和私有子网的区别?
区别在于路由表:公有子网的路由表有指向 IGW 的默认路由,私有子网没有。私有子网的实例要上网,必须通过 NAT Gateway 或 NAT Instance。数据库、内部服务必须放私有子网。
-
NAT Gateway 的作用?为什么不能省?
NAT Gateway 让私有子网的实例能主动访问互联网(如下载补丁、调用第三方 API),同时阻止外网主动连入。不能省,否则私有子网的实例无法更新软件。但可以用 VPC Endpoint 替代部分 NAT 流量(如 S3、ECR)。
-
安全组和网络 ACL 的区别?
安全组是实例级、有状态(自动放行响应)、只支持允许规则。NACL 是子网级、无状态(出入都要显式允许)、支持允许和拒绝规则。安全组是主力,NACL 是补充。
自测三问
- 一个子网是公有还是私有,由什么决定?
- 私有子网的 EC2 需要访问 S3 下载文件,有哪两种方式?
- 安全组为什么说是「有状态」的?举例说明。
小结一句话
VPC 是云上的内网,公有子网临街、私有子网后院,路由表决定谁能上网,安全组决定谁能进门。
延伸