Связь между докерными контейнерами в aws ecs через rabbitmq
Моя команда разрабатывает приложение, состоящее из 20 микросервисов, которое будет развернуто в экземпляре aws ecs ec2. Я планирую запустить 3 aws ec2 экземпляр в кластере. У каждого микросервиса будет свое определение задач и сервис.
Контейнер Docker собирается, передается в aws ecr, а затем развертывается в ecs через jenkins с помощью Jenkinsfile. В json-файлах определения задачи я установил порт хоста равным 0, чтобы каждый порт хоста док-контейнера был случайным и не возникало никаких конфликтов портов, если мы увеличим желаемое количество услуг до 2 или более.
Я предполагаю, что контейнеры в одном и том же определении задачи могут взаимодействовать с использованием ссылок, но в моем случае мы не можем предсказать, на каком экземпляре находятся контейнеры Docker.
Если мы используем rabbitmq на другом сервере, как он может общаться с другим микросервисом? Я использую сетевой режим в качестве "сети по умолчанию" в определении задачи. Должен ли я изменить это на awsvpc?
2 ответа
У меня есть подобное развертывание, запущенное прямо сейчас. Сервер RabbitMq - это отдельный экземпляр в том же виртуальном частном процессоре, что и кластер. Группа безопасности настроена на пропуск всего трафика из этой сети. "Слабой" частью моего развертывания является то, что я не делаю никакого обнаружения службы. Поскольку машина не перезапускается, локальный IP-адрес (10.0....) никогда не меняется, поэтому в определении задачи я определил дополнительный узел, указывающий на этот IP-адрес.
Когда служба хочет прочитать / опубликовать сообщение, y использует определенный хост. Если по какой-то причине я перезагружу экземпляр rabbitmq и IP-адрес, мне придется заново развернуть все контейнеры с обновленным IP-адресом.
Это можно исправить с помощью метаданных экземпляра
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/local-ipv4
в соответствии с официальными документами метаданных Ec2 Instance, где-то его регистрируют (redis, zookeeper, etcd ...), а затем ваши службы могут его проверить, поэтому повторное развертывание не требуется, если экземпляр rabbitMq перезагружается.
Режим сети "awsvpc" не предназначен для обнаружения служб
Сетевой режим awsvpc не предназначен для этого из коробки. Этот режим просто назначает гибкий сетевой интерфейс для каждой выполняемой задачи, предоставляя динамический частный IP-адрес и внутреннее DNS-имя. Это помогает получить основные преимущества, связанные с сетью, такие как управление, журналы потоков, мониторинг трафика для каждой задачи. и т.д., я не уверен, есть ли способ отслеживать эти динамические частные IP-адреса и использовать их с умом.
Ссылка - https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
Решения -
Вы можете посмотреть на механизм обнаружения сервисов. AWS недавно запустил сервис обнаружения ECS, который вы можете интегрировать со своими сервисами, он интенсивно использует Route 53 и вносит изменения на лету.
Ref -
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 в зависимости от протокола, для которого вы хотите поддерживать. И пусть кластер сервисов взаимодействует с кластером RabbitMQ, используя его конечную точку ALB/NLB. Сделайте ASG [min,max,desire=1], если RabbitMQ не масштабируется.