EC2 实例无法获取公网 IP 通常是因为子网未开启自动分配公网 IPv4 地址,或者实例未绑定弹性 IP。路由表配置影响网络连通性而非 IP 地址分配本身。修复需修改子网属性或关联弹性 IP,生产环境建议优先使用弹性 IP 避免停机。
先说结论:这不是实例故障,通常是 VPC 网络配置未满足公网访问条件。修改子网设置需停止实例,绑定弹性 IP 可无停机修复。
- 先确认:子网是否启用“自动分配公网 IPv4 地址”及 IAM 权限
- 先处理:生产环境直接关联弹性 IP,测试环境可修改子网属性
- 再验证:通过实例元数据(注意 IMDSv2)或控制台确认公网 IP
核心概念:IP 分配与网络连通性
公网 IP 的分配依赖于子网设置或弹性 IP 绑定,而互联网网关(Internet Gateway)和路由表决定流量能否流出。即使实例拥有公网 IP,若路由表缺少指向互联网网关的规则,实例依然无法访问外网。反之,若仅需获取 IP 地址用于特定白名单场景,无需修改路由表。
方案一:控制台配置(适合测试环境)
步骤 1:检查子网自动分配设置
在 VPC 控制台找到实例所在的子网,点击“操作”>“编辑子网设置”。勾选“启用自动分配公网 IPv4 地址”。
步骤 2:应用变更(需停机)
修改子网属性后,已运行的实例不会自动获取新 IP。必须执行“停止实例”然后“启动实例”。注意:仅执行“重启实例”不会刷新网络接口配置。此操作会导致实例私有 IP 可能变更(若在非默认子网)及业务中断,生产环境慎用。
方案二:AWS CLI 自动化修复(推荐)
可以通过 AWS CLI 修改子网属性或绑定弹性 IP,便于集成到自动化脚本中。
1. 修改子网自动分配属性
aws ec2 modify-subnet-attribute `--subnet-id` subnet-xxx `--map-public-ip-on-launch-value`2. 分配并关联弹性 IP(无停机)
生产环境推荐此方式,无需停止实例。
# 分配新的弹性 IP
aws ec2 allocate-address `--domain` vpc `--query` AllocationId `--output` text
# 关联弹性 IP 到实例
aws ec2 associate-address `--allocation-id` eipalloc-xxx `--instance-id` i-xxx3. 权限检查
确保当前 IAM 用户或角色拥有 ec2:ModifySubnetAttribute、ec2:AllocateAddress 和 ec2:AssociateAddress 权限。
验证方法(适配 IMDSv2)
AWS 默认启用 IMDSv2,直接 curl 可能失败。建议使用以下命令获取 Token 后查询:
# 获取 Token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# 查询公网 IP
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4若返回 IP 地址,说明实例已获取公网 IP。也可在 AWS 控制台 EC2 实例列表中查看“公网 IPv4 地址”一列。
常见坑与风险排查
- 生产环境停机风险:修改子网自动分配设置必须停止实例,会导致业务中断。生产环境请直接绑定弹性 IP。
- 重启无效:修改子网设置后,仅“重启”实例不会生效,必须“停止”再“启动”。
- 安全组误解:安全组规则只控制流量通行,不决定 IP 有无。无需修改安全组来获取 IP。
- NAT 网关场景:若实例位于私有子网且通过 NAT 网关访问外网,本就不应配置公网 IP,否则可能暴露风险。
- 路由表混淆:不要试图通过修改路由表来解决 IP 未分配问题,路由表仅影响连通性。
参考来源
- AWS Official Documentation, "Assigning a public IPv4 address to your instance", https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html
- AWS Official Documentation, "Subnet settings", https://docs.aws.amazon.com/vpc/latest/userguide/vpc-subnets-settings.html