AWS VPC 配置中有4 个场景。但是让我们看看这两个:
- 场景 1:1 个公共子网。
- 场景 2:1 个公有子网和 1 个私有子网。
由于在公有子网中启动的任何实例都没有 EIP(除非已分配),因此它已经无法从 Internet 寻址。然后:
- 为什么需要私有子网?
- 私有子网和公共子网之间到底有什么区别?
AWS VPC 配置中有4 个场景。但是让我们看看这两个:
由于在公有子网中启动的任何实例都没有 EIP(除非已分配),因此它已经无法从 Internet 寻址。然后:
更新: 2015 年 12 月下旬,AWS宣布了一项新功能,即VPC 托管 NAT 网关。此可选服务为私有子网中的 VPC 实例访问 Internet 提供了一种替代机制,以前,常见的解决方案是 VPC 中公共子网上的 EC2 实例,充当“NAT 实例”,提供网络地址转换 (从技术上讲,端口地址转换)用于其他私有子网中的实例,允许这些机器使用 NAT 实例的公共 IP 地址进行出站 Internet 访问。
新的托管 NAT 服务不会从根本上改变以下信息的适用性,但该选项在后面的内容中并未涉及。NAT 实例仍可按所述使用,或者可以提供托管 NAT 网关服务。此答案的扩展版本将集成有关 NAT 网关及其与 NAT 实例的更多信息的更多信息,因为这些都与 VPC 中的私有/公共子网范式相关。
请注意,Internet 网关和NAT 网关是两个不同的功能。所有具有 Internet 访问权限的 VPC 配置都将具有 Internet Gateway 虚拟对象。
要了解 Amazon VPC 中“私有”和“公有”子网之间的区别,需要了解 IP 路由和网络地址转换 (NAT) 的一般工作原理,以及它们是如何在 VPC 中具体实施的。
VPC 中公有子网和私有子网之间的核心区别由 VPC 路由表中该子网的默认路由定义。
反过来,此配置决定了在该特定子网上的实例上使用或不使用公共 IP 地址的有效性。
每个子网只有一个默认路由,它只能是以下两种情况之一:
Internet 网关不会对没有公有 IP 地址的实例进行任何网络地址转换,因此没有公有 IP 地址的实例无法向外连接到 Internet — 执行诸如下载软件更新或访问其他 AWS 资源(如 S3 1和 SQS )之类的操作-- 如果其 VPC 子网上的默认路由是 Internet 网关对象。因此,如果您是“公共”子网上的一个实例,那么您需要一个公共 IP 地址来执行服务器通常需要做的大量事情。
对于只有私有 IP 地址的实例,还有另一种出站访问 Internet 的方式。这就是网络地址转换²和 NAT 实例的用武之地。
私有子网上的机器可以访问 Internet,因为私有子网上的默认路由不是VPC“Internet 网关”对象——它是配置为 NAT 实例的 EC2 实例。
NAT 实例是具有公共 IP 和特定配置的公共子网上的实例。有预先构建的 AMI 来执行此操作,或者您可以构建自己的。
当私网机器向外发送流量时,流量通过VPC发送到NAT实例,NAT实例将数据包上的源IP地址(私机的私网IP地址)替换为自己的公网IP地址,发送流量到 Internet,接受响应数据包,并将它们转发回原始机器的私有地址。(它也可能重写源端口,并且在任何情况下,它都会记住映射,因此它知道哪台内部机器应该接收响应数据包)。NAT 实例不允许任何“意外”的入站流量到达私有实例,除非它被专门配置为这样做。
因此,当从私有子网访问外部 Internet 资源时,流量会穿过 NAT 实例,并且在目的地看来是源自 NAT 实例的公共 IP 地址......因此响应流量会返回到 NAT 实例。分配给 NAT 实例的安全组和分配给私有实例的安全组都不需要配置为“允许”此响应流量,因为安全组是有状态的。他们意识到响应流量与内部发起的会话相关,因此它是自动允许的。当然,除非安全组配置为允许,否则会拒绝意外流量。
与默认网关位于同一子网的传统 IP 路由不同,它在 VPC 中的工作方式不同:任何给定私有子网的 NAT 实例始终位于不同的子网中,而其他子网始终是公共子网,因为NAT 实例需要有一个公共的外部 IP,其默认网关必须是 VPC“互联网网关”对象。
同样...您不能在私有子网上部署具有公共 IP 的实例。它不起作用,因为私有子网上的默认路由(根据定义)是 NAT 实例(对流量执行 NAT),而不是 Internet 网关对象(不执行)。来自 Internet 的入站流量会到达实例的公共 IP,但回复会尝试通过 NAT 实例向外路由,这会丢弃流量(因为它由对它不知道的连接的回复组成,所以他们'将被视为无效)或将重写回复流量以使用其自己的公共 IP 地址,这将无法正常工作,因为外部来源不会接受来自他们试图与之发起通信的 IP 地址以外的 IP 地址的回复.
那么,从本质上讲,“私人”和“公共”的名称并不是真正关于互联网的可访问性或不可访问性。它们是关于将分配给该子网上的实例的地址类型,这是相关的,因为需要翻译(或避免翻译)那些用于 Internet 交互的 IP 地址。
由于 VPC 具有从所有 VPC 子网到所有其他 VPC 子网的隐式路由,因此默认路由不会在内部 VPC 流量中发挥作用。具有私有 IP 地址的实例将连接到 VPC 中的其他私有 IP 地址“从”他们的私有 IP 地址,而不是“从”他们的公共 IP 地址(如果他们有的话)......只要目标地址是另一个私有地址在 VPC 内。
如果您的具有私有 IP 地址的实例在任何情况下都不需要发起出站 Internet 流量,那么从技术上讲,它们可以部署在“公共”子网上,并且仍然无法从 Internet 访问……但是在这样的配置下,他们不可能向 Internet 发起出站流量,其中包括与其他 AWS 基础设施服务的连接,例如 S3 1或 SQS。
1. 关于 S3,具体来说,说始终需要 Internet 访问是一种过于简单化的说法,随着 VPC 的功能不断发展和演变,它的范围可能会随着时间的推移而扩大并传播到其他 AWS 服务。有一个相对较新的概念,称为VPC Endpoint这允许您的实例(包括仅具有私有 IP 地址的实例)直接从 VPC 中的选定子网访问 S3,无需接触“互联网”,也无需使用 NAT 实例或 NAT 网关,但这确实需要额外配置,并且是仅可用于访问与您的 VPC 相同的 AWS 区域内的存储桶。默认情况下,S3(在撰写本文时是唯一公开了创建 VPC 端点的能力的服务)只能通过 Internet 从 VPC 内部访问。当您创建 VPC 终端节点时,这会创建一个前缀列表 (pl-xxxxxxxx
),您可以在您的 VPC 路由表中使用,通过虚拟“VPC 端点”对象将发往该特定 AWS 服务的流量直接发送到该服务。它还解决了限制特定实例对 S3 的出站访问的问题,因为前缀列表可以在出站安全组中使用,而不是目标 IP 地址或块——并且 S3 VPC 端点可以受制于其他策略声明,根据需要限制从内部访问存储桶。
2. 如文档中所述,这里实际讨论的是端口和网络地址转换。将组合操作称为“NAT”是很常见的,尽管在技术上有点不精确。这有点类似于我们许多人在实际指的是“TLS”时倾向于说“SSL”的方式。我们知道我们在说什么,但我们没有使用最正确的词来描述它。“注意我们在本文档中使用术语 NAT 来遵循常见的 IT 实践,尽管 NAT 设备的实际作用是地址转换和端口地址转换 (PAT)。”
我建议采用不同的策略——抛弃“私有”子网和 NAT 实例/网关。它们不是必需的。如果您不希望机器可以从 Internet 访问,请不要将其放在允许此类访问的安全组中。
通过放弃 NAT 实例/网关,您消除了实例/网关的运行成本,并且消除了速度限制(无论是 250mbit 还是 10gbit)。
如果您的机器也不需要直接访问互联网,(我会问您如何修补它*),那么请务必不要分配公共 IP 地址。
*如果这里的答案是某种代理,那么您会产生开销,但每个人都有自己的开销。
我没有在上面对迈克尔的答案添加评论的声誉,因此将我的评论添加为答案。
值得注意的是,与运行您自己的实例相比,AWS 托管网关的成本大约是当前的 3 倍。这当然是假设您只需要一个 NAT 实例(即您没有为故障转移配置多个 NAT 实例等),这对于大多数中小型用例场景通常是正确的。假设每月通过 NAT 网关传输 100GB 的数据,
托管 NAT 实例每月费用 = 33.48 美元/月(0.045 美元/小时 * 一个月 744 小时)+ 4.50 美元(每 GB 处理数据 0.045 美元 * 100GB)+ 10 美元(通过NAT 网关)= 47.98 美元
配置为 NAT 实例的 t2.nano 实例 = 4.84 美元/月(0.0065 美元 * 一个月 744 小时)+ 10 美元(通过 NAT 实例传输的所有数据的标准 AWS 数据传输费用为 0.10 美元/GB)= 14.84 美元
当您使用冗余 NAT 实例时,这当然会发生变化,因为 AWS 托管 NAT 网关具有内置冗余以实现高可用性。如果您不关心额外的 33 美元/月,那么托管 NAT 实例绝对值得减少不必维护另一个实例的头痛。如果您正在运行 VPN(例如 OpenVPN)实例来访问 VPC 中的实例,您可以简单地将该实例配置为也充当您的 NAT 网关,然后您不必仅为 NAT 维护额外的实例(虽然有些人可能不赞成结合 VPN 和 NAT 的想法)。
Michael - sqlbot的回答隐含了需要私有 IP 地址的假设。我认为值得质疑这个假设——我们是否首先需要使用私有 IP 地址?至少有一位评论者提出了同样的问题。
具有 NAT 实例的私有子网中的服务器 [vs.] 具有严格安全策略的公有子网中的服务器有什么优势?– abhillman 2014 年6 月 24 日 23:45
想象一个场景,您使用 VPC 并将公共 IP 地址分配给您的所有 EC2 实例。不用担心,这并不意味着它们一定可以通过 Internet 访问,因为您使用安全组来限制访问的方式与使用 EC2 经典的方式完全相同。通过使用公共 IP 地址,您可以轻松地将某些服务公开给有限的受众,而无需使用 ELB 之类的东西。这使您无需设置 NAT 实例或 NAT 网关。由于您需要一半的子网,您可以选择为您的 VPC 使用较小的 CIDR 分配,或者您可以使用相同大小的 VPC 创建更大的子网。更少的子网意味着您为可用区间的流量支付的费用也更少。
那么,我们为什么不这样做呢?为什么 AWS 说最佳实践是使用私有 IP?
Amazon Web Services 的公共 IPv4 地址供应有限,因为整个互联网的公共 IPv4 地址供应有限。使用实际上不受限制的私有 IP 地址而不是过度消耗稀缺的公共 IPv4 地址符合他们的最大利益。您可以从 AWS 如何定价弹性 IP 中看到一些证据;附加到实例的 EIP 是免费的,但未使用的 EIP 需要付费。
但是为了争论,让我们假设我们不关心互联网上公共 IPv4 地址的短缺。毕竟,我的申请很特别。接下来发生什么?
只有两种方法可以将公共 IP 地址附加到 VPC 中的 EC2 实例。
1.关联公共IP地址
您可以在启动新的 EC2 实例时请求公共 IP 地址。此选项在控制台中显示为复选框,在使用 aws-cli 时显示为--associate-public-ip-address标志,在使用 CloudFormation 时显示为嵌入式网络接口对象上的AssociatePublicIpAddress标志。在任何情况下,公共 IP 地址都分配给eth0
(DeviceIndex=0)。您只能在启动新实例时使用此方法。但是,这有一些缺点。
一个缺点是更改使用嵌入式网络接口对象的实例的安全组将强制立即替换该实例,至少在您使用 CloudFormation 时是这样。
另一个缺点是这样分配的公网 IP 地址会在实例停止时丢失。
2.弹性IP
一般来说,弹性 IP 是首选方法,因为它们更安全。您可以保证继续使用相同的 IP 地址,不会冒意外删除任何 EC2 实例的风险,您可以随时自由附加/分离弹性 IP,并且您可以自由更改应用于您的 EC2 实例的安全组。
...但是 AWS 将您限制为每个区域 5 个 EIP。您可以请求更多,并且您的请求可能会被批准。但基于我上面提到的推理,AWS 可能会拒绝该请求。因此,如果您计划将基础架构扩展到每个区域超过 5 个 EC2 实例,您可能不想依赖 EIP。
总之,使用公共 IP 地址确实有一些不错的好处,但是如果您尝试专门使用公共 IP 地址,则会遇到管理或扩展问题。希望这有助于说明和解释最佳实践为何如此。