为什么我们需要在 VPC 私有子网?

AWS VPC 配置中有 4种情况,但是让我们看看这两个:

  • 场景1:1公共子网。
  • 方案2:1个公用子网和1个私用子网。

由于在公共子网中启动的任何实例都没有 EIP (除非分配了它) ,因此它已经无法从 Internet 寻址。然后:

  • 为什么需要私有子网?
  • 私有子网和公有子网到底有什么不同?
43882 次浏览

更新: 在2015年12月底,AWS 宣布提供了一个新功能,面向 VPC 的托管 NAT 网关。这种可选服务为私有子网中的 VPC 实例访问因特网提供了一种替代机制,在此之前,通用的解决方案是 VPC 中公共子网上的 EC2实例,作为“ NAT 实例”,为其他私有子网中的实例提供网络地址转换(技术上,左舷地址转换) ,允许这些机器使用 NAT 实例的公共 IP 地址进行出站因特网访问。

新的托管 NAT 服务并没有从根本上改变以下信息的适用性,但是这个选项并没有在下面的内容中提到。一个 NAT 实例仍然可以像描述的那样使用,或者可以提供托管 NAT 网关服务。这个答案的扩展版本将集成更多关于 NAT 网关的信息,以及它与 NAT 实例的比较,因为这两者都与 VPC 中的私有/公共子网范例相关。

请注意,互联网门户NAT 网关是两个不同的特性。所有具有 Internet 访问的 VPC 配置都将有一个 Internet 网关虚拟对象。


为了理解 Amazon VPC 中“私有”和“公共”子网之间的区别,需要理解 IP 路由和网络地址转换(NAT)一般是如何工作的,以及它们是如何在 VPC 中具体实现的。

VPC 中公共子网和私有子网之间的核心区别是由 VPC 路由表中子网的默认路由定义的。

反过来,这种配置规定了在特定子网上的实例上使用或不使用公共 IP 地址的有效性。

每个子网只有一个默认路由,这只能是两种情况中的一种:

  • VPC 的“ Internet 网关”对象,在“公共”子网的情况下,或
  • 一个 NAT 设备——也就是说,一个 NAT 网关或 EC2实例,在“私有”子网的情况下,执行“ NAT 实例”角色。

因特网网关不会对没有公共 IP 地址的实例进行任何网络地址转换,所以没有公共 IP 地址的实例无法将 向外连接到因特网——如果其 VPC 子网上的默认路由是因特网网关对象,则无法进行下载软件更新或访问其他 AWS 资源(如 S31和 SQS)。因此,如果您是“公共”子网上的一个实例,那么您就需要 需要一个公共 IP 地址,以便完成服务器通常需要完成的大量工作。

对于只有私有 IP 地址的情况,有另一种出站访问 Internet 的方式。这就是网络地址转换和 NAT 实例的用武之地。

私有子网上的机器可以访问 Internet,因为私有子网上的默认路由是 没有,VPC“ Internet Gateway”对象——它是配置为 NAT 实例的 EC2实例。

NAT 实例是公共子网上具有公共 IP 和特定配置的实例。有一些 AMI 是预先构建的,或者您可以构建自己的 AMI。

当私有寻址机器向外发送流量时,流量通过 VPC 发送到 NAT 实例,NAT 实例用自己的公共 IP 地址替换数据包上的源 IP 地址(私有机器的私有 IP 地址) ,将流量发送到 Internet,接受响应数据包,然后将它们转发回原始机器的私有地址。(它还可以重写源端口,并且在任何情况下,它都会记住映射,以便知道哪个内部机器应该接收响应数据包)。一个 NAT 实例不允许任何“意外”的入站流量到达私有实例,除非它被特别配置为这样做。

因此,当从私有子网访问外部因特网资源时,流量会遍历 NAT 实例,并且在目的地显示为来自 NAT 实例的公共 IP 地址... ... 因此响应流量会返回到 NAT 实例。分配给 NAT 实例的安全组和分配给私有实例的安全组都不需要配置为“允许”这种响应通信,因为安全组是有状态的。他们意识到响应流量与内部发起的会话相关,因此自动允许响应流量。当然,除非安全组配置为允许意外通信,否则将拒绝意外通信。

不像传统的 IP 路由,你的默认网关是在同一个子网上,它在 VPC 的工作方式是不同的: 任何给定的私有子网的 NAT 实例总是在一个不同的子网上,其他子网总是一个公共的子网,因为 NAT 实例需要有一个公共的外部 IP,它的默认网关必须是 VPC 的“互联网网关”对象。

类似地... 您不能在私有子网上部署具有公共 IP 的实例。它不起作用,因为私有子网上的默认路由(根据定义)是一个 NAT 实例(在流量上执行 NAT) ,而不是 Internet Gateway 对象(不执行)。来自互联网的入站流量会碰到实例的公共 IP 地址,但是回复会尝试通过 NAT 实例向外路由,这样要么会丢失流量(因为它将由对它不知道的连接的回复组成,所以它们会被认为是无效的) ,要么会重写回复流量,使用它自己的公共 IP 地址,这不会起作用,因为外部来源不会接受来自 IP 地址的回复,而不是它们试图启动通信的 IP 地址。

因此,从本质上讲,“私人”和“公共”的标识并不真正关乎互联网的可访问性或不可访问性。它们是关于将被分配给该子网上的实例的地址类型,这是相关的,因为需要翻译——或避免翻译——这些 IP 地址以进行 Internet 交互。

由于 VPC 具有从所有 VPC 子网到所有其他 VPC 子网的隐式路由,因此默认路由在内部 VPC 通信中不起作用。具有私有 IP 地址的实例将“从”他们的私有 IP 地址连接到 VPC 中的其他私有 IP 地址,而不是“从”他们的公共 IP 地址(如果他们有的话) ... ... 只要目标地址是 VPC 中的另一个私有地址。

如果您的实例与私有 IP 地址从来没有,在任何情况下,需要发起出站互联网流量,那么他们在技术上可以部署在一个“公共”子网,仍然无法从互联网访问... 但在这样的配置,它们不可能发起出站流量向互联网,其中包括与其他 AWS 基础设施服务,如 S31或 SQS 连接。


1.关于 S3,特别是说互联网接入是 一直都是所需要的是一个过于简单的说法,随着 VPC 功能的不断增长和发展,随着时间的推移,范围可能会扩大,并扩展到其他 AWS 服务。有一个相对较新的概念称为 VPC 端点,它允许您的实例,包括那些只有私有 IP 地址的实例,直接从 VPC 内部选定的子网访问 S3,而不需要接触“互联网”,也不需要使用 NAT 实例或 NAT 网关,但是这确实需要额外的配置,并且只能用于访问与您的 VPC 相同的 AWS 区域内的存储桶。默认情况下,S3——在撰写本文时,它是唯一公开了创建 VPC 端点功能的服务——只能通过 Internet 从 VPC 内部访问。当您创建 VPC 端点时,这将创建一个前缀列表(pl-xxxxxxxx) ,您可以在 VPC 路由表中使用该列表,通过虚拟“ VPC 端点”对象将特定 AWS 服务的绑定流量直接发送到服务。它还解决了对特定实例限制对 S3的出站访问的问题,因为前缀列表可以在出站安全组中使用,而不是目标 IP 地址或块——并且 S3 VPC 端点可以受制于额外的策略语句,根据需要从内部限制 bucket 访问。

2.正如文档中指出的,这里实际讨论的是端口和网络地址转换。虽然在技术上有点不精确,但将组合操作称为“ NAT”是很常见的这有点类似于我们中的许多人在实际表示“ TLS”时倾向于说“ SSL”的方式我们知道我们在谈论什么,但我们不用最正确的词来描述它。注意: 虽然 NAT 设备的实际作用是地址转换和端口地址转换(PAT) ,但我们在本文档中使用 NAT 这个术语是为了遵循常见的 IT 实践。”

我没有声誉添加一个评论迈克尔的回答以上,因此添加我的评论作为答案。

值得注意的是,与运行您自己的实例相比,AWS 托管网关的开销是当前的3倍。当然,这是假设您只需要一个 NAT 实例(即您没有为故障转移配置多个 NAT 实例,等等) ,这对于大多数中小型用例场景通常是正确的。假设每月通过 NAT 网关传输100GB 的数据,

管理 NAT 实例每月成本 = $33.48/月($0.045/小时 * 每月744小时) + $4.50($0.045/GB 数据处理 * 100GB) + $10($.10/GB 标准 AWS 数据传输费用通过 NAT 网关传输的所有数据) = $47.98

将 t2.nano 实例配置为 NAT 实例 = $4.84/月($0.0065 * 744小时/月) + $10(通过 NAT 实例传输的所有数据的标准 AWS 数据传输费用为 $.10/GB) = $14.84

当你使用冗余的 NAT 实例时,这种情况当然会改变,因为 AWS 管理的 NAT 网关有内置的冗余高可用性。如果您不关心额外的 $33/月,那么托管 NAT 实例绝对值得减少不必维护另一个实例的头痛。如果你正在运行一个 VPN (例如 OpenVPN)实例来访问 VPC 中的实例,你可以简单地将该实例配置为也作为你的 NAT 网关,然后你就不必为了 NAT 而维护一个额外的实例(尽管有些人可能会反对将 VPN 和 NAT 结合起来的想法)。

我建议使用一种不同的方法——抛弃“私有”子网和 NAT 实例/网关。没必要。如果你不希望机器可以从互联网访问,不要把它放在一个安全组,允许这样的访问。

通过放弃 NAT 实例/网关,您可以消除实例/网关的运行成本,并消除速度限制(250mbit 或10gbit)。

如果你有一台机器,也不需要直接访问互联网,(我会问你如何修补它 *) ,那么无论如何,不要分配公共 IP 地址。

如果这个问题的答案是某种代理人,那么,你就要承担一笔开销,但每个人都有自己的代理人。

Michael-sqlbot给出的答案是一个隐式的假设,即需要私有 IP 地址。我认为有必要质疑这个假设——我们是否需要首先使用私有 IP 地址?至少有一位评论者问了同样的问题。

使用 NAT 实例的私有子网上的服务器相对于使用严格安全策略的公共子网上的服务器有什么优势?Abillman 14年6月24日23:45

设想一个场景,您正在使用 VPC,并为所有 EC2实例分配公共 IP 地址。别担心,这并不意味着它们一定可以通过互联网访问,因为您使用安全组来限制访问,其方式与 EC2经典版完全相同。通过使用公共 IP 地址,您可以轻松地向有限的受众公开某些服务,而无需使用 ELB 之类的东西。这使您无需设置 NAT 实例或 NAT 网关。由于您需要一半的子网,您可以选择使用较小的 CIDR 分配您的 VPC 或您可以使用相同大小的 VPC 更大的子网。更少的子网意味着您将支付更少的跨 AZ 流量以及。

那么,为什么我们不这样做呢? 为什么 AWS 说最佳实践是使用私有 IP?

亚马逊网络服务有一个有限的公共 IPv4地址供应,因为互联网作为一个整体有一个有限的公共 IPv4地址供应。您最好使用实际上是无限制的私有 IP 地址,而不是过度消耗稀缺的公共 IPv4地址。您可以从 AWS 对 Elastic IP 的定价中看到这方面的一些证据; 附加到实例的 EIP 是免费的,但是未使用的 EIP 需要花钱。

但是为了便于讨论,让我们假设我们并不关心互联网上公共 IPv4地址的短缺。毕竟,天啊应用程序是特殊的。接下来会发生什么?

只有两种方法可以将公共 IP 地址附加到 VPC 中的 EC2实例。

1. 联合公共 IP 地址

可以在启动新的 EC2实例时请求公共 IP 地址。该选项在控制台中显示为复选框,在使用 aws-cli 时显示为 联合公共 IP 地址标志,在使用 CloudForm 时显示为嵌入式网络接口对象上的 副公众地址标志。在任何情况下,公共 IP 地址都被分配给 eth0(DeviceIndex = 0)。只能在启动新实例时使用此方法。然而,这也有一些缺点。

缺点是更改使用嵌入式网络接口对象的实例的安全组将强制立即替换该实例,至少在使用 CloudForm 时是如此。

另一个缺点是,当实例停止时,以这种方式分配的公共 IP 地址将丢失。

2. 弹性 IP

一般来说,弹性 IP 是首选的方法,因为它们更安全。您可以保证继续使用相同的 IP 地址,您不会冒险意外删除任何 EC2实例,您可以随时自由地附加/分离一个 Elastic IP,并且您可以自由地更改应用于您的 EC2实例的安全组。

但是 AWS 限制你每个区域只能使用5个 EIP。您可以请求更多,并且您的请求 也许吧被授予。但是,基于我上面提到的推理,AWS 也可能拒绝该请求。因此,如果您计划将基础设施的规模扩展到每个区域5个 EC2实例以上,那么您可能不想依赖 EIP。

总之,使用公共 IP 地址确实带来了一些好处,但是如果试图仅使用公共 IP 地址,则会遇到管理或伸缩问题。希望这有助于说明和解释为什么最佳实践是这样的。