前文中我们讲到了 AWS 的网络环境 VPC,以及组成 VPC 的公有子网和私有子网。公有子网中的实例可直接与 Internet 通信,而私有子网不能。公有子网和私有子网是如何划分的呢?
公有子网和私有子网由何而来
AWS 中并没有一个属性来直接标识一个子网是公有子网还是私有子网,那公有子网和私有子网由何而来?
对此需要先了解三个概念:路由表,路由规则和 Internet 网关。
路由表(Route Table)
网络中的网络请求在被发起后,需要经过路由器来层层递进地向目标转发(路由)。VPC 中就有这样一个路由器,这个路由器在 VPC 创建时便自动内置其中,它对用户透明,由 AWS 来管理维护。这个 VPC 路由器负责路由 VPC 内的所有网络流量,包括 VPC 内部实例(机器)之间的网络流量,以及进出 Internet 的网络流量。
VPC 路由器在路由网络流量时,依据什么机制来向目标路由呢?答案是路由表。VPC 通过查找路由表中的配置,从匹配到的配置项中确定目标,然后将网络流量路由给这个目标。
每个子网都需要关联一张路由表,也就是绑定一张路由表。每个新创建的 VPC 在初始情况下,默认内置一张路由表,这张路由表被称为主路由表。VPC 中的每个子网在初始情况下,会自动关联到主路由表上,这种自动关联是隐式关联。你也可以自己创建路由表,然后将其和子网关联,这种关联便是显式关联。
路由规则(Route)
路由表中记录着路由器的一系列网络流量路由分发规则,而这个规则也就是路由表的路由规则。路由规则的格式是怎样的,又是如何来定义呢?
下图是一个典型的路由表:
路由表
这张路由表中有两条路由规则,每条路由规则有两个主要的属性:Destination 和 Target。Destination 表示一组目标 IP 范围,它的值是 CIDR 块;Target 表示路由的目标对象,它的值是一个 AWS 资源 ID。当路由器路由网络流量时,会根据目标的 IP 来路由表中查找匹配的 IP 范围(Destination),之后便将网络流量路由给其所对应的目标对象(Target)。
以图中的两条路由规则为例。
假设现在有一个发往 IP 172.31.1.1 的网络请求,该 IP 正好处于第一条路由规则的目标范围 172.31.0.0/16 之间,所以请求会被路由至 local(local 是一个特殊的标识,表示当前这个 VPC 自己,请求将会转发给这个 VPC 内部的 172.31.1.1)。
(眼尖的你可能已经发现上面的例子中有点问题,其实 172.31.1.1 这个 IP 既能匹配 CIDR 172.31.0.0/16,也能匹配 0.0.0.0/0。是的,这里其实有一个最长前缀匹配的原则,也就是说如果有多个目标范围被匹配到,那么只取其中范围最小的那个。)
假设又有一个发往 IP 220.181.57.216 的网络请求,可知目标 IP 与第二条路由规则中的目标范围 0.0.0.0/0 匹配,这个网络请求将被路由至 igw-88bc90ec,「igw-」开头的这串字符是 AWS Internet 网关的 ID。
那么 Internet 网关是什么?网络流量路由给 Internet 网关有什么用?
Internet 网关
VPC 中的网络流量想要流出 VPC 到 Internet 中去,或者 Internet 中的网络流量想要进入 VPC,这些都需要经过 Internet 网关处理和转发。也就是说 Internet 网关是 VPC 和 Internet 之间通信的入口。
在前面的例子中,发往 220.181.57.216 的网络流量匹配了目标范围 0.0.0.0/0,所以被路由至 igw-88bc90ec 这个 Internet 网关。所以这其实是个与互联网的通信,数据包由 VPC 路由器路由给 Internet 网关,Internet 网关继续转发向 Internet 上的目标。
回到我们最初的问题,公有子网和私有子网是如何划分的?
公有子网和私有子网的区别在于,公有子网所关联的路由表中配置有一条目标为 Internet 网关的路由规则,而私有子网关联的路由表中没有。这条指向 Internet 网关的路由规则就是公有子网和私有子网间的最大差别,也是它们之所以被这样分类的依据。
私有子网所关联的路由表中没有目标为 Internet 网关的路由规则,那么是否意味着一个发往 Internet 的流量没法被路由,也就无法跟互联网通信?是的,私有子网不能直接与 Internet 通信。那私有子网中的实例(机器)想要做一些软件更新,或者我想 SSH 登陆这些实例该怎么办?有没有与 Internet 通信的途径?这个当然也是就有的。
私有子网如何 Internet 通信
私有子网与 Internet 的通信有两个方向:从 Internet 连接私有子网和从私有子网连接 Internet。这两个方向的通信都离不开公有子网的辅助。
想要从 Internet 连接到私有子网中的机器,我们需要在同一 VPC 下的公有子网中放置一台机器,将这台机器作为堡垒机向私有子网中的机器转发网络流量。
如果是从私有子网中的机器连接到 Internet,可以使用 NAT(Network Address Translation)网关。NAT 网关是 AWS 的一项服务,其需要被放置在公有子网中。在创建出 NAT 网关后,我们需要把 NAT 网关配置到这个私有子网所关联的路由表中,也就是图片中的第二条路由规则:
含 NAT 网关的路由表这里将所有 Internet 的网络流量路由给了 NAT 网关。NAT 网关会紧接着转发这些网络流量,其转发的规则便是其所在公有子网的路由表规则,在这里也就是转发给 Internet 网关。而 Internet 网关也会再转发向网络目标,由此便实现了私有子网向 Internet 的通信。
和 NAT 网关类似的还有 NAT 实例,它们不同的地方在于,NAT 实例创建后其背后的虚拟机实例是可见的(甚至可以同时将它作为堡垒机来用),但是该实例是单点的,无法保证高可用;而 NAT 网关作为 AWS 服务,其背后实例不可见,但 AWS 会为此保证可用性。
网络安全
公有子网直接暴露在 Internet 中,势必会面临网络安全威胁。AWS 在子网这个层面设计了一层保护机制网络 ACL,其中可以自定义一些网络流量控制规则,以控制流入或流出子网的网络流量,包括允许或拒绝某类数据包。
对于网络 ACL 的细节这里不再赘述,除网络 ACL 外 AWS 也其它的网络安全机制,其中使用较多的是机器层面的安全组,这个我们将在之后的文章中介绍。
查看该系列文章
公众号「代码之外的自我修养」,增删改查之外来点有用且有趣的东西!
公众号「代码之外的自我修养」
网友评论