AWS: Glue — ошибка AWS S3 connect timed out, и cross-region connections

Автор: | 10/22/2020
 

Есть AWS Glue job, которая должна загрузить данные в AWS S3 в другом регионе.

Джоба падает с ошибкой:

ERROR [Executor task launch worker for task 39] executor.Executor (Logging.scala:logError(91)): Exception in task 6.1 in stage 2.0 (TID 39)
com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to projectname-dwh.s3.eu-west-1.amazonaws.com:443 [projectname-dwh.s3.eu-west-1.amazonaws.com/52.218.112.104] failed: connect timed out

Причину искал долго, потому что во-первых — изначально пошёл искать не в том направлении, во-вторых — не слишком обращал внимания на документацию, в третих — столкнулся с «забавными» багами AWS Console.

Но — всё-таки всё завелось.

Поехали.

«Решение» первое — неправильное (не верьте Google!)

Что мы делаем, когда встречаем какую-то ошибку? Гуглим.

Гуглим по запросу «aws glue s3 timeout«, находим обсуждение>>> на форуме тех. поддержки AWS, в котором автор размышляет о SecurityGroup, в которой не разрешён доступ кот AWS S3.

В принципе — выглядит достаточно логично.

«Виновата» SecurityGroup?

Проверяем используемый AWS Glue Connection:

Он настроен на VPC нашего AWS Aurora RDS-кластера, в подсети subnet-04bb24f7a349d36de которого AWS Glue создаёт свой Elastic Network Interface, к которому подключает SecurityGroup sg-08bed0e10707da5e6.

Проверяем исходящие правила этой SecurityGroup:

Outbound открыт по всем портам и на все адреса, окей.

А Inboud правила — нет, потому что SecurityGroup сервера баз данных, подключение к которой, разумеется, ограничено:

Значит, сейчас всё выглядит так, что когда AWS Glue пытается подключиться к AWS S3 — исходящий запрос уходит к корзине projectname-dwh.s3.eu-west-1.amazonaws.com/52.218.112.104, а обратно поступить не может.

Логично? Вроде бы да.

Варианты решения:

  1. разрешить входящий с IP 52.218.112.104, который есть в логе, и который вроде как принадлежит корзине projectname-dwh.s3.eu-west-1.amazonaws.com — но статичен ли он? Сильно сомневаюсь, что S3 оперирует статичными адресами, тем не менее — можно попробовать
  2. создать отдельную SecurityGroup в той же VPC, в этой SG разрешим весь входящий и исходящий трафик + доступ к самой себе (требования AWS Glue — немного документации всё-таки читать приходилось), и переключим коннекшен на эту SG — но насколько решение такое секьюрно? Попробуем, если сработает — потом подумаем над безопасностью.

Попробуем для начала открыть 52.218.112.104 (на скрине — привычка замазывать IP 🙂 ):

Перезапускаем джобу — и она снова падает:

ERROR [Executor task launch worker for task 25] executor.Executor (Logging.scala:logError(91)): Exception in task 14.1 in stage 2.0 (TID 25)
com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to projectname-dwh.s3.eu-west-1.amazonaws.com:443 [projectname-dwh.s3.eu-west-1.amazonaws.com/52.218.97.131] failed: connect timed out

Теперь адрес 52.218.97.131.

В общем-то — логично, что там не статичный IP.

Тогда — создаём отдельную SecurityGroup в той же VPC, в Inbound и Outbound рулах — разрешаем весь трафик.

Далее — редактируем сам Connection в AWS Glue, и меняем SecurityGroup на только что созданную:

Запукаем ещё раз, ждём.

Иииии…

ERROR [Executor task launch worker for task 16] executor.Executor (Logging.scala:logError(91)): Exception in task 14.0 in stage 2.0 (TID 16)
com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to projectname-dwh.s3.eu-west-1.amazonaws.com:443 [projectname-dwh.s3.eu-west-1.amazonaws.com/52.218.112.48] failed: connect timed out

WTF? А почему?

Возвращаемся к нашему Connection, проверяем — а там старая SecurityGroup… Но мы ведь только что её меняли?!?

Невозможно изменить SecurityGroup в AWS Glue Connection?

Пробуем ещё раз:

  1. редактируем Connection — ставим новую SecurityGroup
  2. жмём Next, потом Finish
  3. снова редактируем Connection — а там старая SecurityGroup

What?!?

Окей, пробуем отключить коннекшен от джобы — может, не хочет применяться, пока коннекшен активен?

Редактируем коннекшен ещё раз — и снова та же х*%?ня.

Пишем тикет в Tech Support, ждём.

Через несколько дней из дома зашёл проверить что и как — а там у нашего Connection уже новая SecurityGroup…

Хм… Ну, ОК, подумал я — может, саппорт что-то втихаря подфиксил.

Решение второе — правильное (RTFM!)

Но проблема осталась — джоба по-прежнему фейлится с ошибкой «connect timed out«, даже если к Connection подключена SecurityGroup, которая разрешает всё.

К решению подтолкнул всё тот же саппорт, который намекнул глянуть в сторону не SecurityGroup — а VPC и настроек сети.

Итак, наш Connection использует подсеть subnet-04bb24f7a349d36de, глянем её Route Table:

Вроде бы правильно?

У нас есть Internet Gateway, есть маршрут в сеть 0.0.0.0/0 через него, есть VPC endpoint для S3:

AWS VPC Endpoints

Читаем за VPC ендпоинты в документации>>>, и чешим репу — ну вроде ж всё правильно? Ендпоин для S3 создан, маршрут к нему в таблице маршрутизации есть — он создаётся автоматически при создании ендпоинта (вот тут-то и проблема: создавал бы руками — обратил бы внимание раньше):

Вот как должно работать:

Т.е. запросы от нашего AWS Glue Connection ENI должны идти через этот VPC S3 Endpoint, согласно маршруту, прописанному в таблице маршрутизации.

Но не работает.

И вот тут до меня дошло.

Смотрим внимательнее на маршрут:

А корзина где? projectname-dwh.s3.eu-west-1.amazonaws.com — Европа.

AWS Glue и cross-region AWS S3 Connections

Что можно сделать? Прочитать, б%;*ь, документацию по кросс-регион коннекшенам для AWS Glue — https://aws.amazon.com/ru/blogs/big-data/create-cross-account-and-cross-region-aws-glue-connections.

Которая говорит использовать NAT Gateway.

Только тогда надо создать отдельную подсеть, что бы роут в 0.0.0.0/0 слать через этот NAT Gateway, так как сейчас таблица маршрутизации этой подсети шлёт трафик через Internet Gateway, но её трогать нельзя, т.к. кластер баз данных.

Итак, что надо настроить:

  1. приватная подсеть в VPC нашей Aurora
    1. для подсети роут в 0.0.0.0/0 укажем через NAT GW
    2. AWS Glue Connection сделаем в этой приватной подсети, навешиваем SecurityGroup с self-allow
  2. и используем существующую публичную сеть в VPC Aurora, в которой создадим NAT Gateway
    1. для этой подсети роут в 0.0.0.0 через Internet Gateway
    2. NAT GW в этой публичной подсети будет ходить через IGW  в мир, к S3 в Европе

Вроде так?

Делаем.

С сетями у меня плохо — используем ipcalc, считаем 3 сети по 62 доступных хоста (2 уже есть, и существующие подсети уже разбиты так — не будем менять):

ipcalc 10.0.18.0/24 -s 62 62 62 | grep Network
Network:   10.0.18.0/24         00001010.00000000.00010010. 00000000
Network:   10.0.18.0/26         00001010.00000000.00010010.00 000000
Network:   10.0.18.64/26        00001010.00000000.00010010.01 000000
Network:   10.0.18.128/26       00001010.00000000.00010010.10 000000

10.0.18.0/26 и 10.0.18.64/26 у нас уже есть

Создаём новую подсеть:

Создаём NAT Gateway в существующей публичной подсети:

RouteTable для новой, приватной, подсети уже есть — создаётся сама при создании подсети:

Редактируем её — указываем маршрут в 0.0.0.0/0 через созданный ранее NAT GW:

Редактируем AWS Glue Connection — задаём использование новой, приватной, подсети:

Сохраняем изменения, и…

&^$&$*%!!!

Невозможно изменить Subnet в AWS Glue Connection?

Ничего не сохраняется — повторяется история с SecurityGroup, когда мы её обновляли — а она оставалась прежней.

Причину нашли позже, а пока я просто создал новый Connection:

Меняем Connection в настройках самой джобы:

Запускаем джобу.

Ждём.

И всё работает.

Твою ж мать…

Невозможно изменить […] в AWS Glue Connection — причина и «решение»

На самом деле — всё менялось. Т.е. изменения применяются — они просто не отображаются в AWS Console, пока не перезагрузишь страницу через F5, а просто переходы между пунктами меню не помогали.

Саппорт передал в команду разработки — пофиксят.

Собственно, на этом приключения завершились.