Исключите нездоровые цели из трафика

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

Введение

У приложения два сервера за Application Load Balancer. Приложение может отказать, даже если экземпляр EC2 работает. Вы настроите проверки здоровья, вызовете реальный сбой и подтвердите, что здоровый сервер продолжает отвечать. Затем восстановите приложение и удалите ресурсы балансировки.

Нужно знать слушатели ALB, целевые группы и SSH к EC2. Новая среда предоставляет сеть, два работающих сервера, их регистрацию и слушатель ALB. Она независима от предыдущей работы; AWS CLI и файлы соединения подготовлены.

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

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

Настройте проверки здоровья

Вы проверите предоставленный сервис и настроите проверку готовности приложения в ALB.

Перейдите в подготовленный каталог и загрузите сетевые переменные:

cd /home/labex/project
source launch.env

Найдите предоставленные балансировщик и группу по имени. Сохраните ARN для следующих команд и DNS-имя для HTTP:

LB_ARN=$(aws elbv2 \
  describe-load-balancers \
  --names application-alb \
  --query 'LoadBalancers[0].LoadBalancerArn' \
  --output text)

TG_ARN=$(aws elbv2 \
  describe-target-groups \
  --names application-targets \
  --query 'TargetGroups[0].TargetGroupArn' \
  --output text)

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

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

aws elbv2 \
  describe-target-groups \
  --target-group-arns "$TG_ARN" \
  --query 'TargetGroups[].{Path:HealthCheckPath,Interval:HealthCheckIntervalSeconds,Timeout:HealthCheckTimeoutSeconds,Healthy:HealthyThresholdCount,Unhealthy:UnhealthyThresholdCount,Matcher:Matcher}'

Предоставленная группа проверяет /health каждые 30 секунд. Для небольшой работы задайте интервал пять секунд и тайм-аут две секунды. Два последовательных отказа исключают цель, два успеха возвращают нездоровую цель. Matcher принимает HTTP 200 как успех:

aws elbv2 \
  modify-target-group \
  --target-group-arn "$TG_ARN" \
  --health-check-protocol HTTP \
  --health-check-path /health \
  --health-check-interval-seconds 5 \
  --health-check-timeout-seconds 2 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 2 \
  --matcher HttpCode=200 \
  --query 'TargetGroups[].{Path:HealthCheckPath,Interval:HealthCheckIntervalSeconds,Healthy:HealthyThresholdCount,Unhealthy:UnhealthyThresholdCount}'

Интервал определяет частоту, тайм-аут ограничивает ожидание каждого запроса. Пороги предотвращают реакцию на краткий сбой. В рабочей системе учитывайте запуск и поведение приложения при отказах; короткие значения делают упражнение наглядным.

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

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

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

Откройте AWS View, подтвердите две цели healthy и нажмите Send request для реального HTTP 200. Состояния и ответ подтверждают исходные условия.

Наблюдайте реальный сбой приложения

Вы вызовете отказ endpoint здоровья app-a, сохранив его экземпляр EC2 работающим.

Получите ID по тегам имен и адрес для SSH:

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)

APP_A_IP=$(aws ec2 \
  describe-instances \
  --instance-ids "$APP_A" \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text)

Приложение читает /etc/report-app/config.json при каждом запросе. healthy определяет, вернет ли /health код 200 или 503. Используйте SSH с предоставленными ключом и настройками. jq меняет только это поле; временный файл предотвращает перезапись во время чтения, а install заменяет файл с правами чтения:

ssh -F ssh_config "ubuntu@$APP_A_IP" \
  'sudo jq ".healthy = false" /etc/report-app/config.json > /tmp/report-config.json && sudo install -m 644 /tmp/report-config.json /etc/report-app/config.json'

Проверьте приложение изнутри сервера. -o /dev/null отбрасывает тело, а -w выводит HTTP-статус:

ssh -F ssh_config "ubuntu@$APP_A_IP" \
  'curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8081/health'

Ожидайте 503. Это сбой приложения, а не остановка EC2. Дайте время на две проверки и найдите причину:

sleep 12

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

APP_A должен быть unhealthy с Target.ResponseCodeMismatch, потому что 503 не соответствует 200. APP_B остается healthy. Проверки асинхронны; при незавершенном переходе подождите и повторите запрос.

Убедитесь, что экземпляры EC2 продолжают работать:

aws ec2 \
  describe-instances \
  --instance-ids "$APP_A" "$APP_B" \
  --query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}' \
  --output table

Отправьте шесть отдельных запросов через ALB:

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

Каждый ответ должен указывать APP_B. В AWS View подтвердите одну нездоровую и одну здоровую цель. Несколько раз нажмите Send request; успешные ответы должны приходить от здорового сервера. ALB исключает отказавшую цель, пока доступна здоровая.

Нездоровая цель исключена, а здоровый сервер отвечает

Пример показывает реальный HTTP 200 от здоровой цели, пока другая сообщает Target.ResponseCodeMismatch. Ваши ID отличаются; сравните ответ со своей здоровой целью.

Если все цели нездоровы, ALB может использовать fail open и направлять к нездоровым целям. Сохранение app-b здоровым важно; полностью нездоровая группа не доказывает, что ALB прекращает все пересылки.

Восстановите и верните цель

Вы восстановите app-a и увидите его возврат к трафику после успешных проверок.

Восстановите только healthy тем же безопасным замещением файла:

ssh -F ssh_config "ubuntu@$APP_A_IP" \
  'sudo jq ".healthy = true" /etc/report-app/config.json > /tmp/report-config.json && sudo install -m 644 /tmp/report-config.json /etc/report-app/config.json'

Подтвердите, что прямой endpoint теперь возвращает 200:

ssh -F ssh_config "ubuntu@$APP_A_IP" \
  'curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8081/health'

Приложение восстановлено, но ALB должен увидеть настроенные последовательные успехи. Дождитесь здорового состояния и проверьте обе цели:

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

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

Обе должны быть healthy. Снова отправьте шесть запросов:

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

Найдите оба ID. В AWS View подтвердите две здоровые карточки и ответы обоих серверов через Send request. Вы исправили приложение и позволили проверкам пройти; экземпляр не заменялся и не удалялся из регистрации.

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

Вы удалите предоставленную конфигурацию балансировки, сохранив восстановленные серверы и сеть.

Получите ARN слушателя, удалите сначала слушатель, затем ALB и группу:

LISTENER_ARN=$(aws elbv2 \
  describe-listeners \
  --load-balancer-arn "$LB_ARN" \
  --query 'Listeners[0].ListenerArn' \
  --output text)

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 и сеть.

Итоги

Вы настроили проверки ALB, вызвали реальный сбой и отличили его от остановки EC2. Вы наблюдали трафик к здоровому серверу, восстановили приложение и подтвердили ответы обоих серверов. В конце удалили балансировку, сохранив серверы и сеть.

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