Маршрутизация запросов через Application Load Balancer

AWSBeginner
Практиковаться сейчас

Введение

У вашей команды два сервера приложения, но клиентам нужен единый адрес сервиса. Вы создадите Application Load Balancer, подключите слушатель к целевой группе и зарегистрируете оба сервера. Реальные HTTP-ответы покажут, какой сервер обработал каждый запрос.

Нужно знать экземпляры EC2, подсети VPC и группы безопасности из предыдущих курсов. Среда предоставляет сеть, работающие серверы и настроенный AWS CLI. Вы создадите ресурсы балансировки и удалите их в конце.

Связь с сертификацией

Лабораторная работа дает начальную практику по следующим темам экзаменов.

Создайте Application Load Balancer

На этом шаге вы создадите единый вход для двух подготовленных серверов.

Application Load Balancer (ALB) распределяет HTTP- и HTTPS-запросы между серверами приложения. Network Load Balancer (NLB) работает с транспортными соединениями, например TCP и UDP; для этого HTTP-приложения подходит ALB. В работе вы будете использовать ALB.

Перейдите в подготовленный рабочий каталог:

cd /home/labex/project

Файл launch.env содержит идентификаторы предоставленной сети. Прочитайте его и используйте source, чтобы загрузить присваивания переменных в текущую оболочку:

cat launch.env
source launch.env

SUBNET_ID и SECOND_SUBNET_ID обозначают подсети в двух разных зонах доступности. ALB требует как минимум две такие подсети. ALB_SECURITY_GROUP_ID обозначает подготовленную группу, разрешающую HTTP-трафик слушателя на порту 80; серверы используют отдельную группу для порта приложения.

Создайте доступный из Интернета балансировщик приложения с именем application-alb. Internet-facing описывает схему адресации. --query выбирает только ARN, а --output text упрощает его повторное использование. Синтаксис оболочки $(...) сохраняет вывод в LB_ARN:

LB_ARN=$(aws elbv2 \
  create-load-balancer \
  --name application-alb \
  --type application \
  --scheme internet-facing \
  --subnets "$SUBNET_ID" "$SECOND_SUBNET_ID" \
  --security-groups "$ALB_SECURITY_GROUP_ID" \
  --query 'LoadBalancers[0].LoadBalancerArn' \
  --output text)

Amazon Resource Name (ARN) идентифицирует ресурс AWS. Проверьте балансировщик по сохраненному ARN:

aws elbv2 \
  describe-load-balancers \
  --load-balancer-arns "$LB_ARN" \
  --query 'LoadBalancers[].{Name:LoadBalancerName,Type:Type,Scheme:Scheme,DNS:DNSName}'

Найдите application-alb, тип application и схему internet-facing. DNS-имя станет адресом для клиентов и зависит от среды. Создание одного балансировщика пока не подключает серверы.

Нажмите AWS View рядом с Terminal. Страница читает то же состояние ресурсов, что и CLI, и должна показывать application-alb. Области целевой группы и целей пока пусты, потому что вы их еще не подключили.

ALB до подключения целевой группы

Изображение показывает этап создания. Имя ресурса соответствует работе, а DNS-имя приведено как пример.

Подключите слушатель к целевой группе

На этом шаге вы определите, куда идут входящие HTTP-запросы.

Целевая группа содержит серверы, способные обслуживать приложение. Ее порт используется для связи с серверами. Слушатель принимает клиентские соединения на балансировщике и выбирает назначение с помощью действия. Здесь клиенты используют порт 80, а приложение на серверах работает на 8081.

Создайте целевую группу типа instance в предоставленной VPC. --target-type instance означает регистрацию ID экземпляров EC2. Путь /health — это endpoint готовности приложения:

TG_ARN=$(aws elbv2 \
  create-target-group \
  --name application-targets \
  --protocol HTTP \
  --port 8081 \
  --vpc-id "$VPC_ID" \
  --target-type instance \
  --health-check-path /health \
  --query 'TargetGroups[0].TargetGroupArn' \
  --output text)

Создайте HTTP-слушатель. Действие по умолчанию направляет запросы в TG_ARN. Сокращенная запись CLI Type=forward,TargetGroupArn=... задает это действие:

LISTENER_ARN=$(aws elbv2 \
  create-listener \
  --load-balancer-arn "$LB_ARN" \
  --protocol HTTP \
  --port 80 \
  --default-actions "Type=forward,TargetGroupArn=$TG_ARN" \
  --query 'Listeners[0].ListenerArn' \
  --output text)

Проверьте созданный слушатель:

aws elbv2 \
  describe-listeners \
  --load-balancer-arn "$LB_ARN" \
  --query 'Listeners[].{Protocol:Protocol,Port:Port,Actions:DefaultActions}'

Вывод должен показывать HTTP на порту 80 и действие пересылки в вашу группу. В AWS View группа появится между ALB и серверами. Зарегистрированных целей пока нет; нужно подключить серверы.

Зарегистрируйте и протестируйте оба сервера

На этом шаге вы зарегистрируете два работающих сервера и увидите реальные запросы к обоим.

Выведите список подготовленных серверов. Фильтр имен выбирает их теги, а запрос показывает полезные поля соединения:

aws ec2 \
  describe-instances \
  --filters 'Name=tag:Name,Values=app-a,app-b' \
  --query 'Reservations[].Instances[].{Instance:InstanceId,Name:Tags[?Key==`Name`].Value|[0],State:State.Name,PrivateIP:PrivateIpAddress}' \
  --output table

Оба экземпляра должны быть running. Получите ID отдельно по каждому имени, чтобы не зависеть от порядка списка:

APP_A=$(aws ec2 \
  describe-instances \
  --filters 'Name=tag:Name,Values=app-a' \
  --query 'Reservations[0].Instances[0].InstanceId' \
  --output text)
APP_B=$(aws ec2 \
  describe-instances \
  --filters 'Name=tag:Name,Values=app-b' \
  --query 'Reservations[0].Instances[0].InstanceId' \
  --output text)

Регистрация целей подключает эти ID к группе. Без явного переопределения Port каждая цель использует порт приложения 8081 из группы:

aws elbv2 \
  register-targets \
  --target-group-arn "$TG_ARN" \
  --targets "Id=$APP_A" "Id=$APP_B"

ALB проверяет /health, чтобы определить доступность. Дождитесь здорового состояния целей. CLI waiter повторяет запросы состояния только для чтения, пока условие не выполнится или не истечет время:

aws elbv2 \
  wait target-in-service \
  --target-group-arn "$TG_ARN"

Проверьте зарегистрированные ID, порты и состояния здоровья:

aws elbv2 \
  describe-target-health \
  --target-group-arn "$TG_ARN" \
  --query 'TargetHealthDescriptions[].{Instance:Target.Id,Port:Target.Port,Health:TargetHealth.State}' \
  --output table

Обе цели должны показывать порт 8081 и состояние healthy. Сохраните DNS-имя балансировщика:

LB_DNS=$(aws elbv2 \
  describe-load-balancers \
  --load-balancer-arns "$LB_ARN" \
  --query 'LoadBalancers[0].DNSName' \
  --output text)

Используйте HTTP-клиент curl для запроса endpoint здоровья. --config client.conf читает предоставленные настройки, а -sS скрывает прогресс, сохраняя сообщения об ошибках:

curl --config client.conf -sS "http://$LB_DNS/health"

Успешный ответ похож на этот пример; ID экземпляра приведен для иллюстрации:

{"service":"Report server","message":"Application ready","instance_id":"i-..."}

Отправьте шесть отдельных запросов. Цикл for повторяет запрос, а echo помещает каждый ответ в отдельную строку:

for request in 1 2 3 4 5 6; do
  curl --config client.conf -sS "http://$LB_DNS/health"
  echo
done

Найдите значения APP_A и APP_B в ответах. Это доказывает распределение между двумя серверами; число запросов не измеряет производительность или емкость. По умолчанию используется round robin. В рабочей системе распределение также зависит от соединений и других настроек.

Откройте AWS View и убедитесь, что обе цели здоровы. Несколько раз нажмите Send request и прочитайте instance_id. Запрос проходит через слушатель к приложению; карточки показывают состояние ресурсов, а ответ идентифицирует сервер, реально обработавший запрос.

Две здоровые цели и реальный ответ приложения

Пример показывает две здоровые цели и успешный запрос. Ваши ID будут другими; сравните ответ с собственными целями.

Удалите ресурсы балансировки

На этом шаге вы удалите созданные ресурсы, сохранив предоставленные серверы и сеть.

Сначала удалите слушатель, чтобы убрать зависимость пересылки в целевую группу:

aws elbv2 \
  delete-listener \
  --listener-arn "$LISTENER_ARN"

Удалите балансировщик, затем его целевую группу:

aws elbv2 \
  delete-load-balancer \
  --load-balancer-arn "$LB_ARN"
aws elbv2 \
  delete-target-group \
  --target-group-arn "$TG_ARN"

Убедитесь, что оба списка ресурсов балансировки пусты:

aws elbv2 \
  describe-load-balancers \
  --query 'LoadBalancers[].LoadBalancerName'
aws elbv2 \
  describe-target-groups \
  --query 'TargetGroups[].TargetGroupName'

Каждый запрос должен вернуть []. AWS View должен показывать отсутствие балансировщика и группы. Предоставленные серверы EC2 продолжают работать; это ресурсы подготовки, которые вы не должны удалять.

Итоги

Вы создали Application Load Balancer, подключили HTTP-слушатель к целевой группе и зарегистрировали два сервера EC2. Вы проверили их здоровье и определили оба сервера по реальным ответам. В конце вы удалили ресурсы балансировки, сохранив подготовленные серверы и сеть.

Следующая работа рассматривает, как проверки здоровья обнаруживают сбой приложения, сохраняют обслуживание здоровыми целями и возвращают восстановленную цель.