AWS VPC如何识别私有子网和公共子网?

64

我在AWS账户中有一个VPC,与该VPC相关联的有5个子网。子网分为两种类型:公网子网和私网子网。如何确定哪个子网是公网子网,哪个是私网子网?每个子网都有CIDR 10.249.?.?范围。

基本上,当我在具有ec2SubnetIds列表的子网中启动EMR时,它会说:“子网配置无效:提供的子网列表包含公网子网和私网子网。只允许使用一种子网类型。”


如何纠正此错误。


1
您可以检查NAT和IGW的子网。IGW表示公共子网,而NAT表示私有子网。 - Varun Chandak
@VarunChandak 我觉得你的意思是“检查子网的默认路由”,而不是“检查子网”。 - jarmod
@jarmod 抱歉错过了语义。 - Varun Chandak
4个回答

103
问题是如何区分公共子网和私有子网,在AWS中,一个VPC子网被认为是“公共的”还是“私有的”,这个答案就在其中。
公共子网具有指向Internet Gateway的默认路由;而私有子网则没有。
因此,要确定给定子网是公共的还是私有的,您需要描述与该子网关联的路由表。那将告诉您路由,并且您可以测试带有igw-xxxxxxxxxxxxxxxxx(而不是local)的0.0.0.0/0路由。
您可以通过查看子网的路由表来确定子网是否在AWS VPC控制台中公开,例如: enter image description here 您也可以按照以下方式为给定的子网ID执行此操作,使用awscli:
aws ec2 describe-route-tables \
    --filter Name=association.subnet-id,Values=subnet-0a123fc414ad5b999 \
    --query "RouteTables[].Routes[]"

输出结果将会是这样的:

[
    {
        "DestinationCidrBlock": "10.0.0.0/16",
        "GatewayId": "local",
        "Origin": "CreateRouteTable",
        "State": "active"
    },
    {
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": "igw-0fca21fadaa22a1b2",
        "Origin": "CreateRoute",
        "State": "active"
    }
]

这里,您可以看到一个目的地路由 0.0.0.0/0,其目标是互联网网关(其GatewayId为igw-xxxxxxxxxxxxxxxxx)。这证实您正在查看公共子网。


你如何实际执行这个部分:“测试具有 igw-xxxxxxxx 网关 ID(而不是“本地”)的“0.0.0.0/0”路由?” - themiDdlest
2
@themiDdlest已经添加了一个使用awscli的示例。 - jarmod

5
最好的解决方案是指定一个子网,这样你就不会产生跨 AZ 数据费用。
没有确定的方法来识别公共和私有子网,除非查看它们的路由表:公共子网将路由到互联网网关,而私有子网则不会。如果您通过某个程序创建集群,那么也许这是一个合理的检查方式,但我不会去那里。
最佳替代方案是在创建子网时为其命名:例如,在可用区 B(us-east-1b、us-west-1b 等)中为私有子网命名为“Private B”。如果您通过控制台启动集群,该名称应显示在可用子网列表中(我多年没有手动启动 EMR 集群,所以不能确定)。
或者,您可以给子网分配任意标签。如果您以编程方式访问它们,这可能是最有用的。

在确定了私有子网之后,由于EMR不允许混合使用私有和公共子网,我从列表中删除了公共子网,只保留了私有子网,然后它显示一个警告:在子网-***中找不到Amazon S3端点。建议使用S3端点来访问S3中的数据。这个问题的解决方案是什么?NatGateway与子网相关联。 - user1846749

3

我发现这很具有挑战性。希望其他人也会觉得这有用。这种方法使用aws cli和jq。截至2021年中期,我正在使用两者的当前版本。需要注意的是,这仅适用于IPv4,并且仅适用于具有1个Internet网关的VPC。

从bash shell开始,首先要确定您正在考虑子网的VPC。在我的用例中,我想要托管EKS集群的VPC。

VPC_ID=`aws eks describe-cluster \
  --name ${CLUSTER_NAME} \
  --query "cluster.resourcesVpcConfig.vpcId" \
  --output text`

查找该VPC的Internet网关

IGW_ID=`aws ec2 describe-internet-gateways \
  --filters Name=attachment.vpc-id,Values=${VPC_ID} \
  --query "InternetGateways[].InternetGatewayId" \
  | jq -r '.[0]'`

识别公共子网

PUBLIC_SUBNETS=`aws ec2 describe-route-tables \
  --query  'RouteTables[*].Associations[].SubnetId' \
  --filters "Name=vpc-id,Values=${VPC_ID}" \
    "Name=route.gateway-id,Values=${IGW_ID}" \
  | jq . -c`

显示公共子网。
echo $PUBLIC_SUBNETS

列出私有子网,排除公共子网。
aws ec2 describe-subnets \
  --filter Name=vpc-id,Values=${VPC_ID} \
  --query 'Subnets[].SubnetId' \
  | jq -c '[ .[] | select( . as $i | '${PUBLIC_SUBNETS}' | index($i) | not) ]'

1
我正在阅读这份用户指南使用单个子网的VPC,并发现这句话很有帮助。
“与路由表关联且具有通往Internet网关的路由的子网称为公共子网”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接