1. Обзор
Динамическое распределение портов (DPA) — это новая функция Cloud NAT. При включенном DPA Cloud NAT динамически масштабирует выделение портов для экземпляров в зависимости от их потребностей. DPA настроен с минимальными и максимальными ограничениями портов, поэтому он никогда не уменьшает количество портов ниже минимального и не увеличивает масштаб за пределы максимального. Это позволяет некоторым экземплярам за шлюзами NAT динамически увеличивать количество подключений без необходимости выделять дополнительные порты всем экземплярам за Cloud NAT.
Без DPA всем экземплярам за Cloud NAT выделяется одинаковое количество портов независимо от использования, как определено параметром minPortsPerVm
.
Для получения дополнительной информации просмотрите раздел документации о NAT DPA .
Что вы узнаете
- Как настроить шлюз Cloud NAT при подготовке к DPA.
- Как проверить распределение портов без DPA.
- Как включить и настроить DPA для шлюза NAT.
- Как наблюдать за эффектами DPA, запуская параллельные выходные соединения.
- Как добавить правила NAT к шлюзу NAT с включенным DPA.
- Как просмотреть поведение DPA с помощью правил, запустив исходящие подключения к нескольким местам назначения.
Что вам понадобится
- Базовые знания Google Compute Engine.
- Базовые знания сетевых технологий и TCP/IP.
- Базовые знания командной строки Unix/Linux.
- Полезно пройти экскурсию по сетям в Google Cloud, например, по лаборатории «Сеть в Google Cloud» .
- Проект Google Cloud с включенным альфа-доступом.
- Понимание основ Cloud NAT.
2. Использование Google Cloud Console и Cloud Shell.
Для взаимодействия с GCP на протяжении всей лабораторной работы мы будем использовать как Google Cloud Console, так и Cloud Shell.
Облачная консоль Google
Доступ к облачной консоли можно получить по адресу https://console.cloud.google.com .
Самостоятельная настройка среды
- Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .
- Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google, и вы можете обновить ее в любое время.
- Идентификатор проекта должен быть уникальным для всех проектов Google Cloud и неизменяемым (нельзя изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID
), поэтому, если он вам не нравится, создайте другой случайный идентификатор или попробуйте свой собственный и посмотрите, доступен ли он. Затем он «замораживается» после создания проекта. - Существует третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
- Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и не платить за выставление счетов за пределами этого руководства, следуйте инструкциям по «очистке», которые можно найти в конце лаборатории кода. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .
Запустить Cloud Shell
Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.
В консоли GCP щелкните значок Cloud Shell на верхней правой панели инструментов:
Подготовка и подключение к среде займет всего несколько минут. Когда все будет готово, вы должны увидеть что-то вроде этого:
Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лабораторной работе можно выполнять с помощью простого браузера.
3. Настройка лаборатории
В ходе этой лабораторной работы вы будете использовать проект и создадите два облака VPC с подсетью в каждом. Вы зарезервируете внешние IP-адреса, а затем создадите и настроите шлюз Cloud NAT (с облачным маршрутизатором), два экземпляра производителя, а также два экземпляра потребителя. После проверки поведения Cloud NAT по умолчанию вы включите динамическое распределение портов и проверите его поведение. Наконец, вы также настроите правила NAT и понаблюдаете за взаимодействием между DPA и правилами NAT.
Обзор сетевой архитектуры:
4. Зарезервируйте внешние IP-адреса.
Давайте зарезервируем все внешние IP-адреса для использования в этой лабораторной работе. Это поможет вам написать все соответствующие правила NAT и брандмауэра как в потребительском, так и в продюсерском VPC.
Из Cloud Shell:
gcloud compute addresses create nat-address-1 nat-address-2 \ producer-address-1 producer-address-2 --region us-east4
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1]. Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].
Заполните IP-адреса, которые были зарезервированы как переменные среды.
export natip1=`gcloud compute addresses list --filter name:nat-address-1 --format="get(address)"` export natip2=`gcloud compute addresses list --filter name:nat-address-2 --format="get(address)"` export producerip1=`gcloud compute addresses list --filter name:producer-address-1 --format="get(address)"` export producerip2=`gcloud compute addresses list --filter name:producer-address-2 --format="get(address)"`
Никаких выходных данных не ожидается, кроме подтверждения того, что адреса были заполнены правильно. Выведем значения всех переменных среды.
env | egrep '^(nat|producer)ip[1-3]'
Выход:
producerip1=<Actual Producer IP 1> producerip2=<Actual Producer IP 2> natip1=<NAT IP 1> natip2=<NAT IP 2>
5. Производитель VPC и настройка экземпляров.
Теперь мы создадим ресурсы для ресурсов производителя. Экземпляры, работающие в VPC-производителе, будут предлагать службу выхода в Интернет с использованием двух общедоступных IP-адресов «адрес производителя-1» и «адрес производителя-2».
Сначала давайте создадим VPC. Из Cloud Shell:
gcloud compute networks create producer-vpc --subnet-mode custom
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/networks/producer-vpc]. NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 producer-vpc CUSTOM REGIONAL Instances on this network will not be reachable until firewall rules are created. As an example, you can allow all internal traffic between instances as well as SSH, RDP, and ICMP by running: $ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE> $ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp:22,tcp:3389,icmp
Далее создадим подсеть us-east4. Из Cloud Shell:
gcloud compute networks subnets create prod-net-e4 \ --network producer-vpc --range 10.0.0.0/24 --region us-east4
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4]. NAME REGION NETWORK RANGE STACK_TYPE IPV6_ACCESS_TYPE IPV6_CIDR_RANGE EXTERNAL_IPV6_CIDR_RANGE prod-net-e4 us-east4 producer-vpc 10.0.0.0/24 IPV4_ONLY
Далее давайте создадим правила брандмауэра VPC, чтобы IP-адреса NAT могли достигать экземпляров производителя через порт 8080.
Первое правило из Cloud Shell:
gcloud compute firewall-rules create producer-allow-80 \ --network producer-vpc --allow tcp:80 \ --source-ranges $natip1,$natip2
Выход:
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80]. Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED producer-allow-80 producer-vpc INGRESS 1000 tcp:80 False
Следующим шагом является создание двух экземпляров производителя.
Экземпляры-производители будут запускать простое развертывание прокси-сервера nginx.
Чтобы быстро предоставить инстансам все необходимое программное обеспечение, мы создадим инстансы со сценарием запуска, который устанавливает nginx с помощью менеджера пакетов Debian APT.
Чтобы иметь возможность писать правила NAT, мы предоставим каждому экземпляру отдельный зарезервированный IP-адрес.
Создайте первый экземпляр. Из Cloud Shell:
gcloud compute instances create producer-instance-1 \ --zone=us-east4-a --machine-type=e2-medium \ --network-interface=address=producer-address-1,network-tier=PREMIUM,subnet=prod-net-e4 \ --metadata startup-script="#! /bin/bash sudo apt update sudo apt install -y nginx mkdir /var/www/html/nginx/ cat <<EOF > /var/www/html/nginx/index.html <html><body><h1>This is producer instance 1</h1> </body></html> EOF"
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-1]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS producer-instance-1 us-east4-a e2-medium 10.0.0.2 <Producer IP1> RUNNING
Затем создайте второй экземпляр. Из Cloud Shell:
gcloud compute instances create producer-instance-2 \ --zone=us-east4-a --machine-type=e2-medium \ --network-interface=address=producer-address-2,network-tier=PREMIUM,subnet=prod-net-e4 \ --metadata startup-script="#! /bin/bash sudo apt update sudo apt install -y nginx mkdir /var/www/html/nginx/ cat <<EOF > /var/www/html/nginx/index.html <html><body><h1>This is producer instance 2</h1> </body></html> EOF"
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/producer-instance-2]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS producer-instance-2 us-east4-a e2-medium 10.0.0.3 <Producer IP2> RUNNING
6. Настройка потребительского VPC, облачного NAT и экземпляров.
Теперь, когда вы создали службу-производитель, пришло время создать потребительский VPC и его шлюз Cloud NAT.
После создания VPC и подсети мы добавим простое правило входящего брандмауэра, чтобы разрешить IAP для диапазонов исходных IP-адресов TCP. Это позволит нам подключаться по SSH к потребительским экземплярам напрямую с помощью gcloud.
Затем мы создадим простой шлюз Cloud NAT в режиме ручного выделения и связанный с ним зарезервированный адрес «nat-address-1». В последующих частях лабораторной работы мы обновим конфигурацию шлюза, чтобы включить динамическое распределение портов, а позже добавим собственные правила.
Сначала давайте создадим VPC. Из Cloud Shell:
gcloud compute networks create consumer-vpc --subnet-mode custom
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc]. NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 consumer-vpc CUSTOM REGIONAL Instances on this network will not be reachable until firewall rules are created. As an example, you can allow all internal traffic between instances as well as SSH, RDP, and ICMP by running: $ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE> $ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp:22,tcp:3389,icmp
Далее создадим подсеть us-east4. Из Cloud Shell:
gcloud compute networks subnets create cons-net-e4 \ --network consumer-vpc --range 10.0.0.0/24 --region us-east4
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4]. NAME REGION NETWORK RANGE STACK_TYPE IPV6_ACCESS_TYPE IPV6_CIDR_RANGE EXTERNAL_IPV6_CIDR_RANGE cons-net-e4 us-east4 consumer-vpc 10.0.0.0/24 IPV4_ONLY
Далее давайте создадим правила брандмауэра VPC, чтобы адреса диапазонов IAP могли достигать экземпляров потребителей на порту 22.
Для первого правила брандмауэра выполните следующую команду из Cloud Shell:
gcloud compute firewall-rules create consumer-allow-iap \ --network consumer-vpc --allow tcp:22 \ --source-ranges 35.235.240.0/20
Выход:
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/consumer-allow-iap]. Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED consumer-allow-iap consumer-vpc INGRESS 1000 tcp:22 False
Прежде чем создавать шлюз NAT, нам необходимо сначала создать экземпляр облачного маршрутизатора (мы используем частный номер ASN, но он не имеет значения для деятельности этой лабораторной работы). Из Cloud Shell:
gcloud compute routers create consumer-cr \ --region=us-east4 --network=consumer-vpc \ --asn=65501
Выход:
Creating router [consumer-cr]...done. NAME REGION NETWORK consumer-cr us-east4 consumer-vpc
Затем создайте экземпляр шлюза NAT. Из Cloud Shell:
gcloud compute routers nats create consumer-nat-gw \ --router=consumer-cr \ --router-region=us-east4 \ --nat-all-subnet-ip-ranges \ --nat-external-ip-pool=nat-address-1
Выход:
Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.
Обратите внимание, что по умолчанию шлюз Cloud NAT создается с minPortsPerVm
равным 64.
Создайте экземпляры потребительского теста. Здесь мы заполняем зарезервированные IP-адреса производителей, чтобы иметь возможность позже ссылаться на них внутри экземпляра. Из Cloud Shell:
gcloud compute instances create consumer-instance-1 --zone=us-east4-a \ --machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \ --metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2 gcloud compute instances create consumer-instance-2 --zone=us-east4-a \ --machine-type=e2-medium --network-interface=subnet=cons-net-e4,no-address \ --metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2
Выход:
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-1]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS consumer-instance-1 us-east4-a e2-medium 10.0.0.2 RUNNING Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/zones/us-east4-a/instances/consumer-instance-2]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS consumer-instance-2 us-east4-a e2-medium 10.0.0.3 RUNNING
7. Проверьте поведение Cloud NAT по умолчанию.
На этом этапе экземпляры-потребители используют поведение Cloud NAT по умолчанию, которое использует один и тот же зарезервированный IP-адрес «nat-address-1» для связи со всеми внешними адресами. В Cloud NAT также пока не включен DPA.
Давайте проверим, какие порты Cloud NAT выделил нашим потребительским экземплярам, выполнив следующую команду:
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Пример вывода
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Consumer IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Consumer IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3
Как видно из приведенного выше вывода, Cloud NAT выделил 64 порта для каждого экземпляра с одного и того же внешнего IP nat-address-1
Давайте проверим, сколько соединений мы можем открыть параллельно, прежде чем включать DPA.
SSH к первому экземпляру потребителя. Из Cloud Shell:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Теперь вы должны находиться в оболочке экземпляра.
Пример вывода (полный вывод сокращен для краткости)
External IP address was not found; defaulting to using IAP tunneling. ... ... <username>@consumer-instance-1:~$
Из экземпляра потребителя давайте сначала получим IP-адреса обоих производителей и заполним их как переменные среды.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
Затем попробуйте подключиться к обоим экземплярам производителя, чтобы убедиться, что мы можем успешно связаться с ними.
<username>@consumer-instance-1:~$ curl http://$producerip1/nginx/ <html><body><h1>This is producer instance 1</h1> </body></html> <username>@consumer-instance-1:~$ curl http://$producerip2/nginx/ <html><body><h1>This is producer instance 2</h1> </body></html>
Теперь давайте попробуем создать множество параллельных подключений к одному из экземпляров производителя, запустив Curl в цикле. Напомним, Cloud NAT не позволяет повторно использовать закрытые сокеты в течение 2 минут. Следовательно, пока мы можем просмотреть все попытки подключения в течение 2 минут, мы можем таким образом моделировать параллельные соединения.
Запустите следующую команду в сеансе SSH экземпляра
while true; do for i in {1..64}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Вы ожидаете, что сможете успешно открыть 64 параллельных соединения, и сценарий должен распечатать следующее
Connection # 64 successful Loop Done, Sleeping for 150s Connection # 64 successful Loop Done, Sleeping for 150s
Чтобы увидеть, что мы не можем выйти за пределы 64 параллельных соединений, сначала подождите 2 минуты, чтобы все старые сокеты очистились. Затем настройте ту же строку на следующую и перезапустите ее.
while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Теперь вы ожидаете следующий вывод
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 67 failed Connection # 68 failed Connection # 69 failed Connection # 70 failed Loop Done, Sleeping for 150s
Это указывает на то, что первые 64 подключения были успешными, а остальные 6 соединений завершились неудачно из-за недоступности портов.
Давайте что-нибудь с этим сделаем: выйдем из оболочки SSH и включим DPA в следующем разделе.
8. Включите DPA и проверьте его поведение.
Запустите следующую команду gcloud, которая включает DPA и устанавливает минимальное выделение портов для каждой виртуальной машины равным 64, а максимальное выделение портов — 1024.
gcloud alpha compute routers nats update consumer-nat-gw --router=consumer-cr \ --region=us-east4 --min-ports-per-vm=64 --max-ports-per-vm=1024 \ --enable-dynamic-port-allocation
Что выводит следующее
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Теперь давайте повторно запустим get-nat-mapping-info
чтобы убедиться, что для обоих экземпляров по-прежнему выделено только 64 порта.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
Пример вывода (обрезан для краткости)
--- instanceName: consumer-instance-1 ... - <NAT Consumer IP1>:1024-1055 numTotalNatPorts: 32 ... - natIpPortRanges: - <NAT Consumer IP1>:32768-32799 numTotalNatPorts: 32 ... --- instanceName: consumer-instance-2 ... - <NAT Address IP1>:1056-1087 numTotalNatPorts: 32 ... - <NAT Address IP1>:32800-32831 numTotalNatPorts: 32 ...
С точки зрения распределения портов мало что изменилось, поскольку экземпляр еще не использует активные порты.
Давайте вернемся по SSH к экземпляру:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Повторно экспортируйте переменные среды IP-адреса производителя.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
И повторно запустите предыдущий цикл, чтобы смоделировать параллельные соединения:
while true; do for i in {1..70}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Теперь мы должны увидеть следующий вывод
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 70 successful Loop Done, Sleeping for 150s
Так что же здесь произошло? Cloud NAT увеличивает распределение портов при увеличении использования портов, но для программирования этого процесса на сетевом уровне требуется некоторое время. Следовательно, мы видим 1-3 таймаута соединения, прежде чем успешно завершим остальные попытки подключения.
Мы указали агрессивный тайм-аут для Curl (5 секунд), но приложения с более длинными тайм-аутами должны иметь возможность успешно завершать соединения, пока DPA увеличивает выделение портов.
Это поведение нарастания можно увидеть более четко, когда мы запускаем цикл для 1024 попыток подключения, например:
while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Теперь мы ожидаем увидеть следующий результат
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 129 successful Connection # 130 failed Connection # 131 failed Connection # 258 successful Connection # 259 failed Connection # 260 failed Connection # 515 successful Connection # 516 failed Connection # 1024 successful Loop Done, Sleeping for 150s
Поскольку Cloud NAT распределяет порты по степеням 2, фактически удваивая выделение на каждом этапе, мы видим таймауты соединения, выделенные вокруг степеней 2 между 64 и 1024.
Поскольку мы установили для maxPortsPerVM
значение 1024, мы не ожидаем, что сможем поддерживать более 1024 подключений. Мы можем проверить это, повторно запустив цикл скручивания со счетчиком, превышающим 1024 (после ожидания 2 минут для сброса устаревших портов).
while true; do for i in {1..1035}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip1/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
И, как и ожидалось, выходные данные показывают, что соединения после 1024 начинают давать сбой.
<truncated output> ... Connection # 1028 successful Connection # 1029 failed Connection # 1030 failed Connection # 1031 failed Connection # 1032 failed Connection # 1033 failed Connection # 1034 failed Connection # 1035 failed ... Loop Done, Sleeping for 150s
Установив для параметра maxPortsPerVM
значение 1024, мы дали указание Cloud NAT никогда не масштабировать выделение портов сверх 1024 на виртуальную машину.
Если мы выйдем из сеанса SSH и достаточно быстро повторно запустим get-nat-mapping-info
, мы увидим выделенные дополнительные порты.
gcloud compute routers get-nat-mapping-info consumer-cr --region=us-east4
И обратите внимание на следующий вывод
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1024-1055 - <NAT Address IP1>1088-1119 -<NAT Address IP1>:1152-1215 - <NAT Address IP1>:1280-1407 - <NAT Address IP1>:1536-1791 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Address IP1>:32768-32799 - <NAT Address IP1>:32832-32863 - <NAT Address IP1>:32896-32959 - <NAT Address IP1>:33024-33151 - <NAT Address IP1>:33536-33791 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3
Обратите внимание, что для consumer-instance-1
выделено 1024 порта, а consumer-instance-2
выделено только 64 порта. До появления DPA это было нелегко, и это подчеркивает возможности DPA для Cloud NAT.
Если вы подождите 2 минуты, прежде чем повторно запустить команду get-nat-mapping-info
, вы заметите, что consumer-instance-1
вернулся к минимальному значению, составляющему всего 64 выделенных порта. Иллюстрирует способность DPA не только увеличивать выделение портов, но и освобождать их, когда они не используются, для потенциального использования другими экземплярами за тем же шлюзом NAT.
9. Проверьте правила Cloud NAT с помощью DPA
Недавно мы также выпустили функцию правил NAT для Cloud NAT, позволяющую клиентам писать правила, использующие определенные IP-адреса NAT для определенных внешних мест назначения. Для получения дополнительной информации обратитесь к странице документации по правилам NAT.
В этом упражнении мы наблюдаем взаимодействие между правилами DPA и NAT. Давайте сначала определим правило NAT для использования nat-address-2
при доступе к producer-address-2
.
Запустите следующую команду gcloud, которая создаст правило NAT, используя
gcloud alpha compute routers nats rules create 100 \ --match='destination.ip == "'$producerip2'"' \ --source-nat-active-ips=nat-address-2 --nat=consumer-nat-gw \ --router=consumer-cr --router-region=us-east4
Вы должны ожидать следующий вывод
Updating nat [consumer-nat-gw] in router [consumer-cr]...done.
Теперь давайте повторно запустим get-nat-mapping-info
чтобы увидеть эффект нового правила NAT.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
Что должно вывести следующее
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Address IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2
Обратите внимание, что теперь у нас есть дополнительные порты, выделенные (также 64, указанный минимум) специально для nat-address-2
в иерархии ruleMappings
.
Что же произойдет, если экземпляр откроет множество подключений к месту назначения, указанному правилом NAT? Давайте выясним.
Давайте вернемся по SSH к экземпляру:
gcloud compute ssh consumer-instance-1 --zone=us-east4-a
Повторно экспортируйте переменные среды IP-адреса производителя.
export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"` export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`
А теперь давайте на этот раз повторим цикл скручивания для producerip2
while true; do for i in {1..1024}; do curl -s -o /dev/null --connect-timeout 5 http://$producerip2/nginx/; if [ $? -ne 0 ] ; then echo -e "\nConnection # $i failed" ; else echo -en "\rConnection # $i successful"; fi; done; echo -e "\nLoop Done, Sleeping for 150s"; sleep 150; done
Вы должны ожидать вывода, подобного следующему
Connection # 64 successful Connection # 65 failed Connection # 66 failed Connection # 129 successful Connection # 130 failed Connection # 131 failed Connection # 258 successful Connection # 259 failed Connection # 260 failed Connection # 515 successful Connection # 516 failed Connection # 1024 successful Loop Done, Sleeping for 150s
По сути, это отражение предыдущего теста. Давайте выйдем из сеанса SSH экземпляра и снова посмотрим на сопоставления nat.
gcloud alpha compute routers get-nat-mapping-info consumer-cr --region=us-east4
Что должно вывести следующее
--- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:1024-1055 - <NAT Address IP2>:1088-1119 - <NAT Address IP2>:1152-1215 - <NAT Address IP2>:1280-1407 - <NAT Address IP2>:1536-1791 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Address IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:32768-32799 - <NAT Address IP2>:32832-32863 - <NAT Address IP2>:32896-32959 - <NAT Address IP2>:33024-33151 - <NAT Address IP2>:33280-33535 numTotalDrainNatPorts: 0 numTotalNatPorts: 512 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 --- instanceName: consumer-instance-2 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:1056-1087 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 - natIpPortRanges: - <NAT Address IP1>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:32800-32831 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.3 --- instanceName: consumer-instance-1 interfaceNatMappings: - natIpPortRanges: - <NAT Address IP1>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:1024-1055 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2 - natIpPortRanges: - <NAT Address IP1>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleMappings: - natIpPortRanges: - <NAT Address IP2>:32768-32799 numTotalDrainNatPorts: 0 numTotalNatPorts: 32 ruleNumber: 100 sourceAliasIpRange: '' sourceVirtualIp: 10.0.0.2
Как вы можете видеть выше, IP-адрес NAT по умолчанию для consumer-instance-1
(IP для nat-address-1
) по-прежнему имеет только 64 выделенных порта, но IP-адрес правила NAT (IP для nat-address-2
) имеет 1024 порта. выделено. При этом consumer-instance-2
сохранял выделение по умолчанию 64 портов для всех IP-адресов NAT.
В качестве упражнения вы можете проверить обратный случай. Позвольте Cloud NAT освободить все дополнительные порты, затем запустите цикл скручивания для producerip1
и посмотрите, как это повлияет на выходные данные get-nat-mapping-info
10. Этапы очистки
Чтобы избежать повторяющихся платежей, вам следует удалить все ресурсы, связанные с этой кодовой лабораторией.
Сначала удалите все экземпляры.
Из Cloud Shell:
gcloud compute instances delete consumer-instance-1 consumer-instance-2 \ producer-instance-1 producer-instance-2 \ --zone us-east4-a --quiet
Ожидаемый результат:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance-2]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-2].
Затем удалите Cloud Router. Из Cloud Shell:
gcloud compute routers delete consumer-cr \ --region us-east4 --quiet
Вы должны ожидать следующий вывод:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].
Освободите все внешние IP-адреса. Из Cloud Shell:
gcloud compute addresses delete nat-address-1 \ nat-address-2 producer-address-1 \ producer-address-2 --region us-east4 --quiet
Вы должны ожидать следующий вывод:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-3]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].
Удалите правила брандмауэра VPC. Из Cloud Shell:
gcloud compute firewall-rules delete consumer-allow-iap \ producer-allow-80 --quiet
Вы должны ожидать следующий вывод:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/consumer-allow-iap]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-80].
Удалить подсети. Из Cloud Shell:
gcloud compute networks subnets delete cons-net-e4 \ prod-net-e4 --region=us-east4 --quiet
Вы должны ожидать следующий вывод:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/cons-net-e4]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/prod-net-e4].
Наконец, давайте удалим VPC. Из Cloud Shell:
gcloud compute networks delete consumer-vpc \ producer-vpc --quiet
Вы должны ожидать следующий вывод:
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc]. Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/producer-vpc].
11. Поздравляем!
Вы завершили лабораторную работу Cloud NAT DPA!
Что вы покрыли
- Как настроить шлюз Cloud NAT при подготовке к DPA.
- Как проверить распределение портов без DPA.
- Как включить и настроить DPA для шлюза NAT.
- Как наблюдать за эффектом DPA, запуская параллельные выходные соединения.
- Как добавить правила NAT к шлюзу NAT с включенным DPA.
- Как просмотреть поведение DPA с помощью правил, запустив исходящие подключения к нескольким местам назначения.
Следующие шаги
- Просмотрите нашу страницу документации по динамическому распределению портов.
- Поэкспериментируйте с настройкой тайм-аутов NAT и значений выделения портов в вашем приложении.
- Узнайте больше о сети на Google Cloud Platform.
©Google, Inc. или ее дочерние компании. Все права защищены. Не распространяйте.