Подключение публичной подсети к Интернету

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

Введение

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

Сначала завершите «Создание VPC с подсетями для приложения». Эта новая среда предоставляет собственные VPC, подсети, приложение и правила доступа; предыдущая VM не используется повторно. CLI уже настроен. Сохраните не связанную с задачей эталонную сеть и все предоставленные ресурсы приложения.

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

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

Подключите интернет-шлюз

На этом шаге вы исследуете предоставленную сеть приложения и подключите интернет-шлюз к её VPC.

Выполняйте команды в Terminal и откройте AWS View рядом с ним. Представление читает то же состояние ресурсов, что и CLI. VPC application-network содержит public-subnet и private-subnet; предоставленное приложение использует приватный адрес 10.20.1.10 в public-subnet.

cd /home/labex/project

Выберите VPC приложения по тегу Name. --filters ограничивает результаты сервера, а --query выбирает ID. $(...) сохраняет этот ID в переменную оболочки для следующих шагов:

VPC_ID=$(aws ec2 describe-vpcs \
  --filters Name=tag:Name,Values=application-network \
  --query 'Vpcs[0].VpcId' \
  --output text)

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

aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'Subnets[].{CIDR:CidrBlock,ID:SubnetId}' \
  --output table

Их диапазоны — 10.20.1.0/24 и 10.20.2.0/24. Отдельная эталонная сеть 10.99.0.0/16 не относится к задаче; сохраните её.

HTTP — протокол запросов и ответов, используемый конечной точкой этого приложения. Порт определяет принимающий сервис; приложение слушает TCP-порт 80. В AWS View нажмите Request application · client A. Это отправит внешний запрос от предоставленного клиента 198.51.100.10. Результат — Connection failed с сообщением No public address. Приложение существует, но его публичный путь ещё не готов.

Интернет-шлюз (IGW) соединяет публичный путь маршрутизации VPC с Интернетом. Создание и подключение — отдельные операции. Добавьте теги к новому шлюзу, чтобы распознавать свой учебный ресурс; заключённая в кавычки спецификация тегов передаётся одним аргументом:

IGW_ID=$(aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=parcel-internet},{Key=Project,Value=parcel}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

Подключите только этот шлюз к выбранной VPC приложения:

aws ec2 attach-internet-gateway --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"

Успешное подключение не выводит текст. Вместо этого запросите связь ресурсов:

aws ec2 describe-internet-gateways \
  --internet-gateway-ids "$IGW_ID" \
  --query 'InternetGateways[].{ID:InternetGatewayId,Attachments:Attachments}' \
  --output json

Подключение указывает вашу VPC и имеет состояние available. AWS View теперь показывает интернет-шлюз под VPC. Само подключение не предоставляет маршрут подсети или публичный адрес приложения. Оставьте этот Terminal открытым, чтобы сохранить записанные ID.

Добавьте маршрут по умолчанию публичной подсети

На этом шаге вы направите интернет-трафик публичной подсети к подключённому шлюзу.

Таблица маршрутов сопоставляет диапазоны назначения с целями. Подсеть использует связанную с ней таблицу либо основную таблицу VPC, если явной связи нет. При подготовке предоставлены две отдельно связанные таблицы: public-routes и private-routes. Выберите public-routes внутри VPC приложения:

PUBLIC_ROUTE_TABLE_ID=$(aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=public-routes \
  --query 'RouteTables[0].RouteTableId' \
  --output text)

Прочитайте маршруты и связи таблицы:

aws ec2 describe-route-tables \
  --route-table-ids "$PUBLIC_ROUTE_TABLE_ID" \
  --query 'RouteTables[].{ID:RouteTableId,Routes:Routes,Associations:Associations}' \
  --output json

Связь указывает public-subnet; существующий маршрут 10.20.0.0/16 имеет цель local, которая оставляет трафик VPC внутри VPC. Не удаляйте этот локальный маршрут и не изменяйте private-routes.

Маршрут по умолчанию 0.0.0.0/0 охватывает назначения IPv4, для которых нет более конкретного маршрута. --gateway-id задаёт интернет-шлюз в качестве цели:

aws ec2 create-route \
  --route-table-id "$PUBLIC_ROUTE_TABLE_ID" \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id "$IGW_ID"

Ответ содержит Return: true. Снова запросите таблицу:

aws ec2 describe-route-tables \
  --route-table-ids "$PUBLIC_ROUTE_TABLE_ID" \
  --query 'RouteTables[].Routes[].{Destination:DestinationCidrBlock,Target:GatewayId,State:State}' \
  --output table

Маршрут по умолчанию указывает ваш igw-... и имеет состояние active; локальный маршрут остаётся. AWS View показывает 0.0.0.0/0 под public-routes с тем же шлюзом. Ещё раз нажмите Request application · client A. Запрос по-прежнему завершается ошибкой No public address. Публичный маршрут подсети готов, но приложению нужен собственный публичный адрес IPv4.

Свяжите публичный адрес и проверьте HTTP

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

Elastic IP — публичный адрес IPv4, выделенный вашему аккаунту, который можно связать с поддерживаемым ресурсом. ID выделения определяет зарезервированный адрес, а ID связи — соединение с ресурсом. При очистке вы удалите и связь, и выделение.

Сетевой интерфейс (ENI) обеспечивает сетевое подключение и приватный IP приложения. Интерфейс уже предоставлен в этой работе; создавать инстанс или настраивать его ОС не нужно. Выберите его по VPC и имени:

ENI_ID=$(aws ec2 describe-network-interfaces \
  --filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=application-interface \
  --query 'NetworkInterfaces[0].NetworkInterfaceId' \
  --output text)

Выделите адрес для использования в VPC и сохраните ID выделения:

ALLOCATION_ID=$(aws ec2 allocate-address \
  --domain vpc \
  --query 'AllocationId' \
  --output text)

Свяжите адрес с интерфейсом приложения и сохраните ID связи:

ASSOCIATION_ID=$(aws ec2 associate-address \
  --allocation-id "$ALLOCATION_ID" \
  --network-interface-id "$ENI_ID" \
  --query 'AssociationId' \
  --output text)

Прочитайте получившееся состояние интерфейса:

aws ec2 describe-network-interfaces \
  --network-interface-ids "$ENI_ID" \
  --query 'NetworkInterfaces[].{ID:NetworkInterfaceId,PrivateIP:PrivateIpAddress,PublicIP:Association.PublicIp}' \
  --output table

Приватный адрес остаётся 10.20.1.10; поле публичного адреса теперь заполнено. В AWS View карточка приложения показывает этот публичный адрес и маршрут к шлюзу. Нажмите Request application · client A.

Результат — Success, адрес источника 198.51.100.10, порт назначения 80 и тело Application online. Это HTTP-ответ предоставленного приложения. Один лишь список настроенных ресурсов не доказывает работоспособность запроса.

У приложения есть публичный адрес и маршрут к интернет-шлюзу; клиент A получает HTTP-ответ

Пример результата: публичная подсеть показывает маршрут к шлюзу и адрес приложения, а запрос возвращает Application online. ID и выделенные адреса могут отличаться.

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

Наблюдайте и восстановите нарушенный маршрут

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

Публичный адрес не заменяет маршрутизацию. Удалите только созданный вами маршрут по умолчанию; сохраните предоставленный локальный маршрут:

aws ec2 delete-route \
  --route-table-id "$PUBLIC_ROUTE_TABLE_ID" \
  --destination-cidr-block 0.0.0.0/0

Убедитесь, что публичный адрес всё ещё связан с интерфейсом:

aws ec2 describe-addresses \
  --allocation-ids "$ALLOCATION_ID" \
  --query 'Addresses[].{PublicIP:PublicIp,Interface:NetworkInterfaceId}' \
  --output table

В AWS View у public-routes теперь есть только локальный маршрут. Старый ответ может иметь пометку Previous request; он не описывает изменённую конфигурацию. Нажмите Request application · client A, чтобы отправить новый запрос. Результат изменится на Connection failed, хотя публичный адрес остаётся.

Публичный адрес остаётся, но отсутствие маршрута по умолчанию приводит к сбою нового запроса

Пример диагностики: у приложения всё ещё есть публичный адрес, в public-routes остался только локальный маршрут, а новый запрос завершается ошибкой.

Восстановите маршрут к тому же подключённому шлюзу:

aws ec2 create-route \
  --route-table-id "$PUBLIC_ROUTE_TABLE_ID" \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id "$IGW_ID"

Ответ содержит Return: true. Когда маршрут снова появится в AWS View, ещё раз нажмите Request application · client A. Вернутся Success и Application online. Вы изолировали маршрутизацию как изменённое условие, не меняя несколько настроек одновременно.

Удалите свой публичный путь

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

У ресурсов есть зависимости. Сначала разорвите связь адреса с интерфейсом:

aws ec2 disassociate-address --association-id "$ASSOCIATION_ID"

Затем освободите выделенный адрес; один лишь разрыв связи оставляет выделенный ресурс:

aws ec2 release-address --allocation-id "$ALLOCATION_ID"

Удалите свой маршрут по умолчанию перед отключением его шлюза:

aws ec2 delete-route \
  --route-table-id "$PUBLIC_ROUTE_TABLE_ID" \
  --destination-cidr-block 0.0.0.0/0
aws ec2 detach-internet-gateway --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"

Наконец, удалите отключённый шлюз:

aws ec2 delete-internet-gateway --internet-gateway-id "$IGW_ID"

Эти команды удаления при успехе не выводят текст. Запросите полные списки, чтобы установить отсутствие ресурсов, вместо проверки по тегам:

aws ec2 describe-addresses --query 'Addresses' --output json
aws ec2 describe-internet-gateways --query 'InternetGateways' --output json

В этой новой среде оба запроса возвращают []. Ещё раз проверьте маршруты предоставленной подсети:

aws ec2 describe-route-tables \
  --route-table-ids "$PUBLIC_ROUTE_TABLE_ID" \
  --query 'RouteTables[].Routes[].{Destination:DestinationCidrBlock,Target:GatewayId}' \
  --output table

Остаётся только локальный маршрут. Предоставленные VPC, подсети и интерфейс приложения всё ещё существуют. AWS View больше не показывает ваш шлюз и публичный адрес. Ещё раз нажмите Request application · client A; удалённый публичный путь не может обслужить запрос. Ошибка получения списка не доказывает очистку ресурсов.

Выполните проверку завершения этого шага.

Итоги

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

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