У меня есть группа экземпляров, настроенная с автоматическим масштабированием и балансировкой нагрузки. Я также использую Google Cloud SQL для сервера MySQL.
Всякий раз, когда группа экземпляров масштабируется и добавляет еще один экземпляр, экземпляр получает новый IP-адрес. Проблема в том, что у этого экземпляра больше нет доступа к экземпляру Google SQL (поскольку экземпляр SQL требует предварительной настройки авторизованных сетей). Что я могу с этим поделать?
В настоящее время я принимаю большинство IP-адресов для моего SQL-сервера, добавляя следующие IP-адреса к авторизованным IP-адресам в диспетчере SQL:
100.0.0.0/6
104.0.0.0/5
112.0.0.0/4
Как уже упоминал @justbeez, я считаю, что лучше всего использовать экземпляры второго поколения и Прокси-сервер Cloud SQL. В случае, если это невозможно, экземпляры первого поколения могут быть настроены так, чтобы разрешать только SSL-соединения и вносить в белый список любое происхождение, как описано Вот.
Более сложным подходом было бы создание экземпляра шаблон так что сценарий запуска запускается во время загрузки и авторизует IP-адрес экземпляра через gcloud. IP-адрес можно удалить таким же образом на неисправность время.
IP-адрес виртуальной машины GCE можно получить с сервера метаданных.
curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"
Если вы используете экземпляр Cloud SQL второго поколения, вы можете рассмотреть возможность использования метода подключения Cloud SQL Proxy: https://cloud.google.com/sql/docs/mysql-connect-proxy
Короче говоря, вы устанавливаете прокси-сервер Cloud SQL локально в свои экземпляры, и он проходит проверку подлинности через учетную запись службы. Затем вы подключаетесь к нему аналогично тому, как вы подключаетесь с помощью сокета UNIX или TCP.
Это требует небольшой настройки, но не требует внесения IP-адресов в белый список. После того, как вы его настроите, вы просто добавите эту версию к любому используемому вами шаблону автоматического масштабирования.
Примечание. Если вы используете контейнеры Docker, у них есть версия прокси-сервера Cloud SQL, заключенная в образ Docker, который вы можете добавить в свои модули в качестве службы: https://cloud.google.com/sql/docs/mysql-connect-docker
(Единственный другой вариант, о котором я могу думать, - это использовать API для редактирования белого списка в ответ на события автомасштабирования.)
Хорошо, я мало публикую, но эта проблема стоила мне потери времени и усилий. Надеюсь, эта информация поможет людям, которые сталкиваются с той же проблемой:
Использование прокси-сервера Cloud SQL, похоже, является способом, которым GCP подталкивает всех к преодолению этого препятствия. Однако имейте в виду, что как только вы пойдете по этому пути, вы будете связаны с GCP. Ваше приложение должно иметь непосредственные знания о специфическом для GCP компоненте, чтобы иметь возможность взаимодействовать с БД - то, что необходимо только для работы приложения в GCP и нигде больше.
Из-за этого нежелательного последствия я решил последовать «более сложному» подходу @Carlos. Преимущество этого подхода состоит в том, что он изолирует логику, необходимую для взаимодействия с экземпляром SQL, и связывает ее с конфигурациями, специфичными для GCP, а не с самим приложением.
Следующий код - это сценарий запуска, который я написал, чтобы разрешить автоматически запускаемому шаблону экземпляра получить авторизацию для экземпляра SQL. Он работает в ОС GCP, оптимизированной для контейнеров, в которой не установлен gcloud.
#!/bin/bash
PROJECT=<your project>
DB=<your db name>
METADATA=http://metadata.google.internal/computeMetadata/v1
# Get the external IP of this instance
EXTERNAL_IP=$(curl -s "$METADATA/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google")
# Get access to call the SQL API
curl -s --header "Authorization: Bearer $ACCESS_TOKEN" -X GET https://www.googleapis.com/sql/v1beta4/projects/$PROJECT/instances/$DB?fields=settings/ipConfiguration/authorizedNetworks/value | grep value | awk -F\" '{print $4}' && \
SVC_ACCT=$METADATA/instance/service-accounts/default && \
ACCESS_TOKEN=$(curl -H 'Metadata-Flavor: Google' $SVC_ACCT/token | cut -d'"' -f 4)
# Get the IPs that are authorized to the database
EXISTING_IPS=$(curl -s --header "Authorization: Bearer $ACCESS_TOKEN" -X GET https://www.googleapis.com/sql/v1beta4/projects/$PROJECT/instances/$DB?fields=settings/ipConfiguration/authorizedNetworks/value | grep -B1 -A1 value | tr -d '\n')
# If the $EXTERNAL_IP is already authorized, then there's nothing to do
[ -n "$(echo $EXISTING_IPS | grep $EXTERNAL_IP)" ] && exit 0
# If the $EXISTING_IPS is not empty, prepend a comma
[ -n "$EXISTING_IPS" ] && EXISTING_IPS=", $EXISTING_IPS"
# Patch the database settings with the new authorized IPs
curl -s --header "Authorization: Bearer ${ACCESS_TOKEN}" \
--header 'Content-Type: application/json' \
--data "{\"settings\":{\"ipConfiguration\":{\"authorizedNetworks\":[{\"value\":\"$EXTERNAL_IP\"}$EXISTING_IPS]}}}" \
-X PATCH \
https://www.googleapis.com/sql/v1beta4/projects/$PROJECT/instances/$DB
# Dump the database settings for visual verification
curl -s --header "Authorization: Bearer $ACCESS_TOKEN" -X GET https://www.googleapis.com/sql/v1beta4/projects/$PROJECT/instances/$DB?fields=settings
Обновить: Это решение доступно на мое публичное репозиторий GitHub.