我的团队正在开发一个由 20 个微服务组成的应用程序,该应用程序将部署在 aws ecs ec2 实例中。我计划在集群中启动 3 个 aws ec2 实例。每个微服务都有其任务定义和服务。
docker 容器已构建,推送到 aws ecr,然后使用 Jenkinsfile 通过 jenkins 部署到 ecs。在任务定义 json 文件中,我将主机端口设置为 0,以便每个 docker 容器主机端口都是随机的,并且如果我们将服务的所需计数增加到 2 个或更多,则不会出现任何端口冲突。
我猜想相同任务定义上的容器可以使用链接进行通信,但在我的例子中,我们无法预测 docker 容器在哪个实例上。
如果我们在不同的服务器上使用rabbitmq,它如何与不同的微服务通信?我在任务定义中使用网络模式作为“默认网络”,我应该将其更改为 awsvpc 吗?
“awsvpc”网络模式不适用于服务发现
网络模式 awsvpc 并不是为此目的而设计的。这 模式只是为每个正在运行的设备分配一个弹性网络接口 任务,提供动态私有 IP 地址和内部 DNS 名称。这有助于获得与网络相关的主要优势,例如每个任务定义的控制、流日志、流量监控。等等,我 我不确定是否有任何方法可以跟踪这些动态私有 IP 并明智地使用它们。
参考 - https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
解决方案 -
您可以寻找服务发现机制。 AWS 最近推出了 ECS 服务发现,您可以将其与您的服务集成,这大量使用 Route 53 并即时进行更改。
参考-
https://aws.amazon.com/blogs/aws/amazon-ecs-service-discovery/
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html
更轻松地说,人们也建议了“ecs-task-kite”,但似乎还没有像现在一样准备好生产 - https://github.com/awslabs/ecs-task-kite
似乎使用 AWS ECS 服务发现机制是您目前最好的选择。虽然,我还没有机会测试一下。
另一种方法是为 RabbitMQ 本身使用不同的集群,根据您想要支持的协议通过 NLB 或 ALB 公开它。并让服务集群使用其 ALB/NLB 端点与 RabbitMQ 集群进行通信。设置 ASG [min,max,desire=1],以防 RabbitMQ 不可扩展。
我现在正在运行类似的部署。 RabbitMq 服务器是与集群位于同一 vpc 中的单独实例。安全组配置为允许来自该网络的所有流量。我的部署的“薄弱”部分是我没有进行任何服务发现。由于机器没有重新启动,本地 IP 地址(10.0....)永远不会改变,因此我在任务定义中定义了一个指向该 IP 地址的额外主机。
当服务想要读取/发布消息时,y 使用定义的主机。如果由于某种原因我重新启动rabbitmq实例和IP地址,我将不得不使用更新的IP地址重新部署所有容器。
这可以使用实例元数据来修复
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/local-ipv4
根据官方文档Ec2实例元数据将其注册到某个地方(redis,zookeeper,etcd ...),然后您的服务可以检查它,因此如果rabbitMq实例重新启动,则不需要重新部署。