如何在重启AWS ECS服务时分配静态IP?Jenkins配置CI/CD更新ECS服务时IP变更的解决方法
刚好之前处理过类似的ECS网络配置问题,来给你梳理下可行的解决方案:
解决ECS服务更新时IP/网络接口变更的问题
首先得搞清楚为啥每次更新IP都会变:当你执行aws ecs update-service --force-new-deployment时,ECS会启动全新的任务实例、销毁旧任务,而默认情况下任务的IP是VPC动态分配的,所以每次更新自然会换IP。要解决这个问题,有两种核心思路,看你的场景选:
思路1:用负载均衡器做固定入口(生产环境首推)
这是最省心的方案,不用纠结任务本身的IP,而是通过ALB/NLB把流量入口固定住:
- 给你的ECS服务绑定一个Application Load Balancer(ALB)或者Network Load Balancer(NLB):
- ALB会给你一个固定的DNS名称,把业务流量指向这个DNS就行,不管后端任务怎么更新,ALB都会自动把流量路由到新启动的任务实例上。
- 如果必须要固定公网IP,就用NLB,给它分配弹性IP(EIP),这个EIP不会随任务更新而变动。
- 配置的时候记得在ECS服务的网络设置里关联负载均衡器,设置好目标组,确保新任务启动后自动注册到目标组,旧任务销毁时自动注销,这样流量切换就完全自动化了。
思路2:给ECS任务直接分配静态IP
如果你的业务场景必须让任务本身拥有固定IP,那可以根据你用的ECS启动类型(Fargate/EC2)来配置:
如果你用的是Fargate启动类型
Fargate支持绑定预创建的静态弹性网络接口(ENI),步骤是:
- 先在你的VPC里创建一个ENI,给它分配静态私有IP,要是需要公网访问,再给这个ENI关联一个弹性IP(EIP)。
- 在ECS任务定义里把
networkMode设为awsvpc,然后在networkConfiguration里指定你刚才创建的那个ENI。 - 注意:同一个ENI同一时间只能被一个任务用,所以你的ECS服务的
desiredCount得设为1,不然会出现ENI占用冲突。如果需要多实例,就得创建多个ENI,然后用任务集(Task Set)给每个任务分配不同的ENI。
如果你用的是EC2启动类型
有两种方式可选:
- Host网络模式:把任务的
networkMode设为host,这样任务的IP就是EC2容器实例的IP。你给EC2实例分配静态私有IP,再关联EIP(如果需要公网)就行。但这种方式要注意,同一实例上的任务不能用相同端口,容易出现端口冲突,适合单任务实例的场景。 - Awsvpc网络模式:和Fargate的逻辑一样,提前创建带静态IP的ENI,在任务定义里指定这个ENI。同样要注意每个ENI只能对应一个任务。
重启ECS服务时分配静态IP的方法
其实上面的思路2已经覆盖了重启时的静态IP需求,总结下关键要点:
- 任务必须用
awsvpc或者host网络模式(bridge模式没法分配静态IP)。 - 提前创建好带静态私有IP的ENI(EC2模式),或者在Fargate的任务定义里关联预创建的ENI。
- 当你执行
aws ecs update-service --force-new-deployment重启服务时,新任务会自动使用你配置的静态ENI/IP,不会再出现IP变更的情况。
最后补个小提醒:用静态ENI的话,一定要确保ENI处于可用状态,而且没有被其他资源占用,不然任务启动会失败哦。
内容的提问来源于stack exchange,提问作者zero86
相关产品推荐
相关产品推荐

