Отслеживание всплеска расходов на NAT-шлюз

Если вы проводите достаточно времени, занимаясь архитектурой и созданием решений для облака, вы, скорее всего, сталкивались или, по крайней мере, слышали рассказы о захватывающих историях биллинга в облаке (📈).

Это мой рассказ о расследовании неожиданного всплеска платы за NAT-шлюз в проекте миграции в облако.

Проект

Один из моих клиентов недавно перевел сложное локальное приложение на AWS — проект lift-and-shift, в котором использовались GitHub Actions, Terraform и Ansible для автоматизации создания специфических VPC окружений, содержащих несколько веб-приложений, несколько микросервисов и вспомогательную инфраструктуру.

После запуска новых сред команде проекта потребовалось некоторое время, чтобы сделать шаг назад и поискать проблемы. Мы нашли и задокументировали точки трения в автоматизации, усилили безопасность и посмотрели на ежемесячные счета от AWS.

Большая часть расходов AWS соответствовала ожиданиям, но была одна категория, для которой у нас не было объяснения: NAT.

Что такое NAT?

NAT расшифровывается как «трансляция сетевых адресов». Обычно NAT нужен, когда вы пытаетесь установить связь между ресурсом, не имеющим публичного IP-адреса, и каким-либо внешним ресурсом. Поскольку внутренняя машина не имеет публичного IP-адреса, нет возможности общаться напрямую, поэтому вы можете попросить другой ресурс (сервер или, в данном случае, управляемый AWS NAT-шлюз) перевести внешний адрес и порт на внутренний адрес и порт.

Необъяснимые затраты на NAT

VPC, созданные в ходе автоматизации проекта, имеют частные подсети, и эти подсети используют NAT-шлюзы для связи с внешним миром, когда это необходимо.

Однако расходы на NAT были высокими и постоянно росли:

Трафик NAT был удивительно высоким — мы приближались к 40 ТБ ежемесячного трафика NAT, что намного больше, чем команда ожидала. Откуда шел трафик, куда он направлялся и почему?

Для каждой среды существует свой VPC, и некоторые среды имеют общую учетную запись, поэтому давайте посмотрим, наблюдается ли в каждом VPC одинаковый объем NAT-трафика, используя CloudWatch Metrics для управляемых NAT-шлюзов.

Метрики CloudWatch

Давайте посмотрим на метрики для NAT шлюзов в CloudWatch. «NATGateway > NAT Gateway Metrics» имеет множество метрик, но поскольку мы рассматриваем объем данных, давайте включим все те, которые относятся к «Bytes»:

Итак, похоже, что только один NAT-шлюз отвечает за большую часть трафика, как BytesInFromDestination, так и BytesOutToSource. Оба эти параметра указывают на то, что трафик поступает из внешнего источника — ресурсы внутри VPC загружают большие объемы данных:

Журналы потоков VPC / CloudWatch Insights

Теперь, когда мы сузили круг поиска до одного VPC, как нам выяснить, откуда и куда идет трафик? Хорошим следующим шагом будут журналы VPC Flow Logs, которые регистрируют трафик в вашем VPC. Журналы потоков VPC уже были включены, и есть удобная статья в базе знаний, в которой даются советы по использованию CloudWatch Log Insights для анализа участников трафика через NAT-шлюз.

Если посмотреть на трафик, проходящий через NAT-шлюз и выходящий из него, похоже, что здесь задействовано множество различных внутренних IP-адресов:

Так что же является источником этих данных?

Быстрое сканирование позволяет предположить, что это адреса AWS, скорее всего, S3. Итак, множество внутренних IP-адресов в одном VPC загружают множество данных с экземпляров AWS S3. Почему?

Отслеживание IP-адресов

На этом этапе я сначала проверил пару вещей — в частности, я начал подозревать, что здесь может быть нездоровая служба ECS, за которой плохо следят, но я не обнаружил ее при очень быстром сканировании, поэтому я решил продолжить систематический поиск. С чем связаны эти IP-адреса?

Итак, теперь смотрим в EC2 > Сетевые интерфейсы (ENI):

Ничего. Я искал несколько ip-адресов, перечисленных в журналах потоков, и ни один из них в настоящее время не активен. Подозрительно. Что-то использует IP-адрес, выполняет трафик NAT, а затем … исчезает до того, как я начинаю его искать.

Можем ли мы найти IP-адрес в CloudTrail?

Да, можем:

❯ aws cloudtrail lookup-events --max-results 20 --lookup-attributes AttributeKey=EventName,AttributeValue=CreateNetworkInterface --end-time "2022-06-10" | jq '.Events[].CloudTrailEvent | fromjson' | jq .userAgent| sort | uniq -c
  20 "ecs.amazonaws.com"
Войти в полноэкранный режим Выйти из полноэкранного режима

Удобно, что группа безопасности, которая появляется в событии, также совпадает с именем службы ECS. Похоже, моя теория была верна, просто я еще не нашел нужную службу.

Из событий службы сразу становится ясно, что служба нездорова и перезапускается с какого-то события в марте, и никто этого не заметил:

{
    "id": "715c6493-9a08-4de2-82d1-afcaf54c54ef",
    "createdAt": "2022-07-13T15:24:18.650000-04:00",
    "message": "(service qa-XXX-service) deregistered 1 targets in (target-group arn:aws:elasticloadbalancing:ca-central-1:004110273183:targetgroup/qa-XXX-service/a7f603824fb1e497)"
},
{
    "id": "0fea699a-3628-4f9d-abe0-dd89a930aa45",
    "createdAt": "2022-07-13T15:24:01.939000-04:00",
    "message": "(service qa-XXX-service) has begun draining connections on 1 tasks."
},
{
    "id": "68e666d1-f489-40a3-9dda-c5b739a7e6ad",
    "createdAt": "2022-07-13T15:24:01.926000-04:00",
    "message": "(service qa-XXX-service) deregistered 1 targets in (target-group arn:aws:elasticloadbalancing:ca-central-1:004110273183:targetgroup/qa-XXX-service/a7f603824fb1e497)"
},
{
    "id": "3cca6545-d38d-4b88-a8b9-1e936f737526",
    "createdAt": "2022-07-13T15:23:30.948000-04:00",
    "message": "(service qa-XXX-service) registered 1 targets in (target-group arn:aws:elasticloadbalancing:ca-central-1:004110273183:targetgroup/qa-XXX-service/a7f603824fb1e497)"
},
{
    "id": "36b50859-babe-47eb-8dcb-ca2c5c661491",
    "createdAt": "2022-07-13T15:23:21.103000-04:00",
    "message": "(service qa-XXX-service) has started 1 tasks: (task d1a70a3629d64febbc91695b4b848d71)."
},
{
    "id": "32f354a3-21ec-4a26-aac0-ceb02805dd16",
    "createdAt": "2022-07-13T15:23:16.401000-04:00",
    "message": "(service qa-XXX-service) has begun draining connections on 1 tasks."
},
Вход в полноэкранный режим Выход из полноэкранного режима

Каждый раз при перезапуске он тянет новый образ контейнера из ECS и тратит на это пропускную способность NAT.

Что теперь?

Во-первых, остановите кровотечение:

  • Установите количество желаемых задач на 0.
  • Это остановит попытки ECS создать новые задачи, которые никогда не будут здоровыми.
  • Это хороший способ остановить ECS от попыток исправить сломанную службу без необходимости существенно изменять определение задачи или определение службы, что позволяет провести диагностику позже.

На данном этапе мы можем отслеживать метрики NAT Gateway, чтобы убедиться, что использование снизилось, а также биллинг AWS в течение следующих нескольких дней, чтобы убедиться, что расходы на NAT Gateway снизились.

Далее?

Мы решили непосредственную проблему, но она выявила множество областей для дальнейшего исследования:

  • Технический долг
    • Это старая служба, которая была заменена новым окружением, но не была очищена.
    • Те задачи по очистке, которые были отложены, теперь имеют вполне реальную стоимость.
  • Улучшенный мониторинг служб ECS
    • Я уже видел, как служба ECS попадает в этот бесконечный нездоровый цикл.
    • Существует множество способов обнаружения и диагностики неработающих служб ECS, но большинство из них требуют некоторой настройки с вашей стороны.
    • Эти затраты на NAT ясно показывают, что команде проекта необходимо уделять больше времени обнаружению нездоровых служб ECS.
  • Мониторинг шлюзов NAT
    • Один NAT-шлюз пропускал значительно больше трафика, чем остальные.
    • Можно добавить сигнал тревоги, когда использование NAT-шлюза переходит разумный предел.
    • Можно также рассмотреть возможность обнаружения аномалий CloudWatch.
  • Мониторинг затрат
    • Затраты такого масштаба, вероятно, не должны были оставаться незамеченными в течение нескольких месяцев.
    • Хотя другие пункты все еще имеют ценность, это лишь один из бесконечного числа способов, которыми ваш счет за AWS может удивить. Если мы улучшим мониторинг служб ECS и шлюзов NAT, это не помешает чему-то другому сойти с рельсов через месяц или два.
    • Здесь есть множество вариантов:
      • Вручную просматривать счета AWS, когда они приходят
      • Пороговые сигналы тревоги при выставлении счетов
      • Обнаружение аномалий в расходах
      • Сторонние решения для управления и оптимизации расходов AWS.
  • PrivateLink
    • Без PrivateLink трафик между задачами ECS, выполняемыми на Fargate, и службами AWS, такими как ECS и S3, проходит через шлюз NAT.
    • Настроив PrivateLink для VPC, мы можем направлять этот трафик через внутреннюю инфраструктуру AWS, сокращая трафик NAT-шлюза и расходы.
  • Замена управляемых NAT-шлюзов
    • Можно настроить собственные NAT-шлюзы на экземплярах EC2 вместо использования управляемых AWS.
    • Это потребует больше работы по настройке и обслуживанию, и я не уверен, что оно того стоит, но аргументы есть.
    • Я признаю, что испытываю некоторую симпатию к слогану Кори Куинна «Неприятно и не рекомендуется».

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

Оцените статью
devanswers.ru
Добавить комментарий