Используйте один эластичный IP-адрес AWS для нескольких экземпляров

Мне нужно предоставить своим клиентам фиксированные URL-адреса, которые не меняются при остановке/запуске экземпляров EC2, потому что иногда нам нужно изменить размер EC2, и когда мы перезапускаем экземпляр, общедоступный IP-адрес изменился.

Я думал об использовании эластичных IP-адресов, чтобы сохранить тот же общедоступный IP-адрес при перезагрузке экземпляра, но я видел, что Amazon сообщает вам, что у вас есть только 5 эластичных IP-адресов. Если вы спросите их, они скажут, что могут дать вам больше, но я думаю, что они не дадут вам 10 000 штук.

Как я могу использовать один общедоступный эластичный IP-адрес, чтобы предоставить каждому пользователю разные URL-адреса для нашей службы?

Это будет что-то вроде этого, 11.22.33.44 эластичный IP-адрес и 192.168.0.X two EC2 instances:

11.22.33.44:**1000** --> 192.168.0.**1**:22
11.22.33.44:**1001** --> 192.168.0.**1**:80
11.22.33.44:**1002** --> 192.168.0.**1**:443

11.22.33.44:**1003** --> 192.168.0.**2**:22
11.22.33.44:**1004** --> 192.168.0.**2**:80
11.22.33.44:**1005** --> 192.168.0.**2**:443

Мне нужно заставить его работать программно, так как я создаю экземпляры EC2 из SDK по мере необходимости.

Еще один способ, который я придумал, — использовать поддомены из моего домена .com, которые указывают на текущий общедоступный IP-адрес каждого экземпляра EC2, но использование IP-адреса, как я описал ранее, звучит лучше.


person Luis Miguel García Mancebo    schedule 29.01.2020    source источник
comment
Они предоставят вам 10 000 эластичных IP-адресов, если они вам нужны, но на самом деле это не один из таких сценариев. Вам нужен балансировщик нагрузки (ELB) и некоторые записи DNS, такие как client1.example.com, client2.example.com и т. д., указывают на него.   -  person ceejayoz    schedule 29.01.2020
comment
Решение DNS — единственный способ, которым это сработает. Вы не сможете получить так много статических IP-адресов, и DNS также более перспективен, если вы хотите позже разместить балансировщики нагрузки, API-шлюз, CDN или что-то еще перед этими экземплярами.   -  person Mark B    schedule 29.01.2020
comment
@ceejayoz Для чего используется балансировщик нагрузки? Если я уже указываю каждой DNS-записи на общедоступный IP-адрес, мне больше не нужно, верно?   -  person Luis Miguel García Mancebo    schedule 29.01.2020
comment
@LuisMiguelGarcíaMancebo Один IP-адрес для нескольких экземпляров означает балансировщик нагрузки. Если вы хотите, чтобы с каждой записью DNS был связан только один экземпляр, вы можете отказаться от LB.   -  person ceejayoz    schedule 29.01.2020
comment
Дополнительный комментарий. Предоставление каждому клиенту отдельного экземпляра Amazon EC2 хорошо для разделения, но плохо для масштабирования и экономической эффективности. Возможно, стоит изучить, как можно реализовать мультитенантность, чтобы ресурсы EC2 можно было совместно использовать между несколькими клиентами. Это также значительно сократит ваши расходы.   -  person John Rotenstein    schedule 30.01.2020


Ответы (1)


Проблема в том, что экземпляры получают новые (временные) общедоступные IP-адреса после их остановки и запуска.

Простой способ решить эту проблему — добавить сценарий к каждому экземпляру, который запускается при каждой загрузке. Этот сценарий может обновить запись DNS, чтобы указать ее на экземпляр.

Скрипт должен находиться в каталоге /var/lib/cloud/scripts/per-boot, что заставит Cloud-Init автоматически запускать скрипт при каждом запуске экземпляра.

# Set these values based on your Route 53 Record Sets
ZONE_ID=Z3NAOAOAABC1XY
RECORD_SET=my-domain.com

# Extract information about the Instance
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id/)
AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone/)
MY_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4/)

# Extract Name tag associated with instance
NAME_TAG=$(aws ec2 describe-tags --region ${AZ::-1} --filters "Name=resource-id,Values=${INSTANCE_ID}" --query 'Tags[?Key==`Name`].Value' --output text)

# Update Route 53 Record Set based on the Name tag to the current Public IP address of the Instance
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch '{"Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"'$NAME_TAG.$RECORD_SET'","Type":"A","TTL":300,"ResourceRecords":[{"Value":"'$MY_IP'"}]}}]}'

Сценарий извлечет тег Name экземпляра и обновит соответствующий набор записей в маршруте 53. (Не стесняйтесь изменить это, чтобы использовать другой тег.) Экземпляру также потребуются разрешения IAM для ec2 describe-tags и route53 change-resource-record-sets.

Обновление: я превратил этот ответ в сообщение в блоге: Amazon Route 53: как автоматически обновлять IP-адреса без использования эластичных IP-адресов

person John Rotenstein    schedule 30.01.2020
comment
Спасибо, @John, похоже, это хороший способ сделать это. Поскольку я сам создаю экземпляры, я могу узнать IP-адрес и обновить его в Route 53, но я должен подумать, лучше ли, чтобы экземпляр делал это сам, как вы предложили. - person Luis Miguel García Mancebo; 31.01.2020
comment
Да, вы можете сделать это при создании экземпляра, но описанный выше метод также обновляет DNS-имя на новый общедоступный IP-адрес, если экземпляр останавливается и запускается. - person John Rotenstein; 01.02.2020