BODY: 如果你接触AWS超过几周,多半已经创建过VPC。画子网、挂路由表、写安全组规则,甚至搭过VPC对等连接。一切正常,你继续往下走,没有人会多想。 但在控制台点击和Terraform资源之下,AWS真正做的是在网络层面编排真实的硬件能力:隔离边界、过滤数据包、做出路由决策,并把这些操作放到超大规模上去执行。大多数人都看不见这一层。它被封装、抽象成服务,而这正是托管服务的全部意义。 可我还是想亲眼看看那一层。于是我写了一个名叫vpcctl的Python命令行工具,用纯Linux原生的工具——网络命名空间(network namespaces)、veth对、Linux网桥和iptables——把AWS VPC的核心网络行为完整复刻了一遍:子网划分、路由策略、安全组、VPC对等连接,全部涵盖。这篇文章既带你了解AWS VPC内部到底发生了什么,也会告诉你:当你亲手用底层原语重建一遍等效行为后,你对真实AWS网络的设计与排障思路会发生怎样的改变。 动手之前,有必要把VPC的构成讲准确。因为下文的所有对照,都基于这些基础模块。 VPC本质上包含这些逻辑组件:一个隔离的虚拟网络边界;若干子网,各自关联一张路由表,决定流量去向;安全组,作为实例级别的有状态防火墙;网络访问控制列表(NACL),作为子网级别的无状态防火墙;互联网网关或NAT网关,处理公网进出;以及对等连接,打通两个VPC之间的私网通路。 每一个组件都是逻辑存在。AWS并没有在某个机房里放一个挂着“VPC设备”标签的实体盒子,它做的依然是最朴素的网络操作:转发数据包、过滤流量、做地址转换——跟任何一台Linux主机上做的事情没有本质区别。我真正想搞清楚的问题是:如果不用AWS API,自己造一遍这些东西,底层长什么样? vpcctl就是在这个问题驱动下诞生的。它复刻的AWS VPC组件和Linux底层工具一一对应: VPC的隔离边界,对应Linux的网络命名空间;子网间的二层互通,对应veth对和Linux网桥;路由决策,对应内核IP路由表和ip route命令;安全组的过滤行为,对应iptables的有状态规则;NAT网关的出网能力,对应iptables的MASQUERADE规则;VPC对等连接,则对应两个命名空间之间直接相连的veth链路。 vpcctl支持创建VPC、添加公有或私有子网、挂载安全组规则、建立两个VPC之间的对等连接,并且把全部状态持久化到磁盘,保证多次运行之间配置不丢失。这些操作和在AWS控制台里做的事情完全一样,只不过底层执行的是真实的Linux网络命令,而不是调用AWS API。 把两边放在一起对照之后,有几个原本只是被我死记硬背的AWS行为,突然变得清晰了。 第一个收获,是彻底理解了为什么VPC对等连接不支持传递。A与B对等,B与C对等,A却无法访问C。从控制台上看,这好像是个不合情理的AWS限制。但当你手动搭建时你会看见,对等连接实际上是在两个命名空间之间拉了一根直接的虚拟网线,它只存在于A和B之间。A的路由表里有一条去往B网段的直连路由,B的路由表里也有一条去往A网段的直连路由。而C根本不在A的路由表里,A也没有任何一条路由能把包送到C。所谓传递性,本质上要求路由器具备“得知”远端网段的能力——要么靠动态路由协议,要么靠手动添加路由。AWS的VPC对等连接设计上就砍掉了这两种能力,因为你只需要在对等关系里显式添加一条路由就能打通,搞传递性反而会让路由表变得不可控。这不是AWS做不到,而是网络设计上的一种有意收敛。 第二个收获,是理解了为什么安全组是有状态的。以前用AWS的时候,文档里写“安全组是有状态的,NACL是无状态的”,我背下来就完了。自己用iptables复刻安全组才发现,有状态意味着你只需定义入站规则,出站响应自动被允许。底层靠的是iptables的conntrack机制,它维护了一张连接跟踪表,记录每个TCP连接或UDP会话的状态。当出站数据包经过时,conntrack识别出这是一条已建立的连接,于是自动放行。这个机制极大简化了用户心智模型——你永远不需要为“响应包应该怎么回来”这件事额外写规则。而NACL作为无状态组件,每一条入站和出站规则必须分别写明,因为它根本不跟踪连接状态。自己实现一遍后你就会明白,这两个组件在AWS里之所以一个是实例级、一个是子网级,与其说是功能差异,不如说是有状态与无状态两种设计哲学在工程上的分界。 第三个收获,是理解了路由表在VPC里的绝对权威。过去排障时,最常见的现象就是“安全组全放通了,可流量还是不通”。一旦亲手搭过这套东西你就会发现,数据包要经过好几道关卡:先过NACL,再过路由表,最后过安全组。任何一道关卡拒绝,包就丢了。而路由表往往是最容易被忽略的那个角色——因为从控制台看,它只是一堆网段和目标的列表。但真正在网络命名空间里操作时,你会看到路由表查找发生在每一次数据包转发的最前端。如果VPC的路由表里没有匹配项,内核会直接丢弃或者走默认路由,其他所有安全配置根本来不及生效。更微妙的是,路由表是“最长前缀匹配”而不是“顺序匹配”,这意味着两条看似相近的路由,它们的掩码长度直接决定数据包到底走哪条路径。AWS默认VPC里那条“local”路由掩码是/16,而你手动加的对等连接路由可能是/24,当访问一个具体IP时,命中的永远是那条更精确的/24——这种机制在AWS控制台里是隐形的,但用ip route命令一眼就能看穿。 写完vpcctl之后,我开始用一种全新的视角看AWS控制台。以前它是一堆抽象概念拼成的界面,现在它是一张被精心封装过的分布式路由器的投影。每一次点击创建VPC,背后都对应着一次网络隔离边界的划分;每一条安全组规则,都对应着一条iptables规则链的操作;每一个对等连接,都对应着一条真实链路的建立。 用一句话说:AWS VPC并不是什么黑魔法,它是在庞大规模上,把一套我们早就有的网络原语,用工程手段组织到了极致。而亲手重造一遍,是理解这套系统最笨也最扎实的方法。
![]()
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.