目录:
AWS概述
EMR Serverless
AWS VPC及其网络
关于AWS网络架构的思考
网络作为云服务的交付手段,同时也是云内部体系的支撑骨架,是一项不可或缺的基础设施,所以这个系列先从 AWS 上的网络环境开始讲起。
VPC 是 AWS 上的一项重要且常用服务,它提供逻辑上隔离的私有网络环境。
所谓隔离,即为该 VPC 与 Internet 以及其它 VPC 相隔绝,限制其间的网络通信。这种隔离是是逻辑上的,通过使用软件层面的技术手段来达到隔离目的,并非物理设备的连通性隔离。
VPC 几乎可对等于自己本地机房的内网环境,你可以像使用自己的内网一样使用它,不同点在于这个内网环境被托管给了 AWS 来维护。在 AWS 上,你创建的几乎所有的服务实例(机器)都需要置于 VPC 内。它提供的私有网络环境可保障最基本的网络隔离安全。
VPC 作为私有网络,自然具备自己的私有地址范围,在 AWS 中地址范围通常用 CIDR 块表示,形式如 172.31.0.0/16,表示 IP 的二进制的前 16 位固定不变,后 32-16=16 位可使用,即为 172.31.0.0 至 172.31.255.255 这个 IP 范围,VPC 中实例的私有地址只能在这个范围内分配,如下所示:
VPC ID | State | IPv4 CIDR |
---|---|---|
vpc-0xxxxx | Available | 172.31.0.0/16 |
VPC 可进一步划分成多个子网,子网即是 AWS 中网络的最小组成单元。
子网作为 VPC 的细分,自然也拥有自己的私有地址范围。其地址范围是 VPC 地址范围的子集,如 173.31.0.0/20(表示 IP 的二进制的前 20 位固定,后 32-20=12 位可用),即 173.31.0.0 至 173.31.15.255 这个 IP 范围。子网范围是 VPC 范围的子集,且一个 VPC 下的各个子网的地址范围不会重叠,如下所示:
Subnet ID | State | VPC | IPv4 CIDR |
---|---|---|---|
subnet-a16e9b8a | Available | vpc-0xxxxx | 172.31.16.0/20 |
subnet-a742a0ef | Available | vpc-0xxxxx | 172.31.32.0/20 |
subnet-e5db87be | Available | vpc-0xxxxx | 172.31.0.0/20 |
子网根据其与能否与 Internet 直接连通,归类为公有子网和私有子网两种。对 Internet 开放进站/出站流量的子网即为公有子网,相对的,不暴露于 Internet 的子网即为私有子网。公有子网中的实例可直接与 Internet 相连,可将子网内产生的网络请求送入 Internet,也可将接收来自 Internet 的网络请求。私有子网则不能与 Internet 直接通信。
VPC 下的所有子网之间默认是互通的,无论是公有子网还是私有子网。
为何区分公有/私有子网
公有子网和私有子网的区分有何意义?
让我们先来看一个典型场景。通常的一个稍具规模的 Web 服务会被设计成多层架构,以 Web 站点层,应用层,数据库层这样的三层架构为例,每一层都对应若干个虚拟机实例:
在上面这个场景中,Web 站点层需要处理来自 Internet 的通信,所以需要放入公有子网中,以便暴露给外界访问。而应用层并不需要直接与 Internet 通信,将其放入私有子网中,可避免与 Internet 直接交互,防止被外界入侵或攻击。数据库层与应用层类似,可置于私有子网中。公有子网和私有子网间默认的互通性,可保证 Web 站点层与应用层能正常通信。
组合使用公有子网和私有子网,这样的网络环境设计,能在保证灵活性的同时提升网络安全性。
一个 AWS 账号在初始时,每个区域中都会内置一个默认 VPC,该 VPC 默认包含三个子网。
你也可以在 VPC 控制面板中通过创建向导,便捷地创建出满足不同需求的 VPC 和其中的子网:
CIDR 之前有介绍过,根据需要填写,也可直接使用默认值。「VPC 名称」和「子网名称」,命名通常是为了方便辨别,这里也不例外。
有些参数你可能不太了解,简要介绍一下:
需要说明的是,该章节只演示了使用 VPC 向导创建「带单个公有子网的VPC」。VPC 向导中还有其他三种 VPC 配置,这三种配置涉及私有子网,创建时需要去配置 NAT 网关或 VPN。当然,我们也可以不用VPC 向导,而是分别去创建 VPC 和子网。
生产环境中为了方便管理,通常使用terraform来创建云资源。
上文介绍了公有子网和私有子网,公有子网中的实例可直接与 Internet 通信,而私有子网不能。公有子网和私有子网是如何划分的呢?
AWS 中并没有一个属性来直接标识一个子网是公有子网还是私有子网,那么公有子网和私有子网由何而来?
对此需要先了解三个概念:路由表,路由规则和 Internet 网关。
一个网络中的网络请求被发起后,需要通过路由器来分发(路由)向目标。VPC 中就有这样一个路由器,这个路由器在 VPC 创建时便自动内置在 VPC 中,它对于用户不可见,由 AWS 来管理维护,用户不能对它进行操作。这个路由器负责路由 VPC 内的所有网络请求,包括 VPC 内部实例(机器)之间的网络请求,以及进出 Internet 的网络请求。
VPC 路由器在路由网络请求时,依据什么来选择网络中的目标呢?答案是路由表。VPC 通过查找路由表中的配置,从匹配到的配置项中确定目标,然后将网络请求路由给这个目标。
每个子网都需要关联一张路由表,也就是绑定一张路由表。每个新创建的 VPC 在初始情况下,默认自带一张路由表,这张路由表被称为主路由表。VPC 中的每个子网在初始情况下,会自动关联到主路由表,这种自动关联是隐式关联。你也可以自己创建路由表,然后将该路由表和子网关联,这种关联便是显式关联。
路由表中记录着路由器的一系列网络请求路由分发规则,而这个规则也就是路由表的路由规则。路由规则的格式是怎样的,又是如何来定义呢?
下图是一个典型的路由表:
Destination | Target | Status |
---|---|---|
172.31.0.0/16 | local | active |
0.0.0.0/16 | igw-88bc90ec | active |
这张路由表中有两条路由规则,每条路由规则有两个主要的属性: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 网关的意图又是什么?
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 通信。那私有子网中的实例(机器)想要做一些软件更新,或者想 SSH 登陆这些实例该怎么办?有没有与 Internet 通信的途径?这个当然也是就有的。
私有子网与 Internet 的通信有两个方向:从 Internet 连接私有子网和从私有子网连接 Internet。这两个方向的通信都离不开公有子网的辅助。
想要从 Internet 连接到私有子网中的机器,我们需要在同一 VPC 下的公有子网中安放一台机器,这台机器作为堡垒机向私有子网中的机器转发网络请求。
如果是从私有子网中的机器连接到 Internet,可以使用 NAT(Network Address Translation)网关,NAT 网关是 AWS 的一项服务,其需要被放置在公有子网中。创建出 NAT 网关后,我们需要把 NAT 网关配置到这个私有子网所关联的路由表中:
Destination | Target | Status |
---|---|---|
172.31.0.0/16 | local | active |
0.0.0.0/16 | nat-0224ad0e435da2157 | active |
也就是上表中的第二条路由规则,这里将所有 Internet 的网络请求路由给了 NAT 网关,之后 NAT 网关会紧接着转发这个请求。NAT 网关转发的网络请求又根据公有子网的路由表规则路由给 Internet 网关,由 Internet 网关转发向网络目标。由此便实现了私有子网向 Internet 的通信。
和 NAT 网关类似的还有 NAT 实例,它们不同的地方在于,NAT 实例创建后其背后的机器在 EC2(AWS 虚拟机服务)列表中是可见的,你甚至可以同时将它作为堡垒机来用,缺点在于该实例是单点的,无法保证高可用。NAT 网关作为 AWS 服务,其背后实例不可见,但 AWS 会为此保证可用性。
公有子网直接暴露在 Internet 中,势必会面临网络安全威胁。AWS 在子网这个层面设计了一层保护机制,称之为网络 ACL。网络 ACL 中可以自定义一些网络控制规则,这些规则用于控制流入或流出子网的网络请求,可以允许或拒绝某类数据包。
对于网络 ACL 的细节这里不再赘述,除网络 ACL 外也其它的网络安全机制,其中使用最多的是机器层面的安全组。