Понимание облачных SQL-соединений

Как и многие облачные инженеры, я начал свой путь в облаке на AWS. Я быстро освоился с Amazon Relational Database Service (RDS). Хотя это PaaS-служба, контролировать подключения с помощью групп безопасности или сетевых ACL — понятий, которые легко переносятся, если вы работали с другими службами AWS, взаимодействующими с VPC.

Когда я впервые получил возможность поработать с GCP, я ожидал, что та же простота использования RDS перейдет и на Cloud SQL. Я быстро обнаружил, что сетевое взаимодействие в GCP и AWS значительно отличается, что стало очевидным, когда я попытался подключиться к экземпляру Cloud SQL.

В этой статье я хочу внести некоторую ясность в то, как можно подключиться к экземплярам Cloud SQL в GCP.

Параметры подключения

Экземпляр Cloud SQL может быть настроен с публичным IP и частным IP. Это означает, что существует два различных сетевых пути, которые можно использовать для подключения к экземпляру Cloud SQL —

  1. частный сетевой путь только для VPC или
  2. публичный сетевой путь с доступом в Интернет.

Здесь необходимо отметить, что в отличие от экземпляров RDS, где у вас есть группы безопасности, действующие как брандмауэры для входящих соединений, брандмауэры VPC не нацелены на экземпляры Cloud SQL в GCP. Вместо этого мы авторизуем соединения. Существует 3 способа авторизации подключения:

  1. Авторизованные сети — Это список IP-адресов, которым разрешено подключаться к экземплярам Cloud SQL.
  2. Cloud SQL Auth proxy — использует IAM для авторизации соединения от клиента. Соединения автоматически шифруются.
  3. Самоуправляемые сертификаты SSL/TLS — они разрешают подключения только на основе определенных открытых ключей.

Существенным различием между сетевыми путями является необходимость наличия вышеуказанных мер авторизации. В зависимости от выбранного вами сетевого пути, вам может потребоваться авторизация соединения. Независимо от выбранного сетевого пути, вам потребуется аутентификация соединения через пользователя базы данных SQL.

Я сведем этот факт в таблицу ниже. Это почти всегда помогало мне легко настроить или устранить неполадки при подключении Cloud SQL.

Подключение Частный IP Публичный IP
Авторизация Необязательно Требуется
Аутентификация Требуется Требуется

Кроме того, для частных IP-соединений может потребоваться настройка авторизованной сети только в том случае, если вы пытаетесь напрямую подключиться к данному экземпляру (без Auth-прокси), а IP-адрес клиента не является адресом RFC 1918.

Cloud SQL Auth Proxy

Вот краткая справка о назначении Cloud SQL Auth Proxy, так как вначале, когда я сравнивал с ним, как работает Identity-Aware Proxy (IAP), он был немного запутан.

Cloud SQL Auth Proxy только авторизует клиентское соединение с помощью IAM принципала и оборачивает соединение в безопасный туннель к экземпляру Cloud SQL.

Однако если клиент не может подключиться к экземпляру Cloud SQL из-за топологии сети, использование Cloud SQL Auth Proxy не обойдет это требование и позволит клиенту установить соединение в любом случае. Например, клиент GCE, пытающийся получить доступ к частному экземпляру Cloud SQL, должен иметь доступ к VPC, связанному с частным IP-адресом экземпляра Cloud SQL. Только после этого Cloud SQL Auth Proxy может попытаться установить соединение на основе авторизации IAM принципалов.

Это становится очевидным, когда мы видим, как работает прокси. Из документации GCP:

Прокси Cloud SQL Auth использует защищенный туннель для связи со своим процессом-компаньоном, запущенным на сервере. Каждое соединение, установленное через прокси Cloud SQL Auth, создает одно соединение с экземпляром Cloud SQL.

Исследование 🥾

Давайте рассмотрим несколько распространенных сценариев и изучим, как можно легко установить соединение Cloud SQL, используя вышеизложенную информацию. Обратите внимание, что мы в первую очередь изучаем аспект подключения. Я бы не рекомендовал запускать ресурсы с такими конфигурациями на практике.

1. Подключение к публичному экземпляру Cloud SQL с локальной машины.

Это путь, который вы можете использовать при работе с базой данных для разработки. Хотя это и не слишком распространенный сценарий, его полезно изучить. Частный экземпляр базы данных почти всегда является строгим требованием безопасности в большинстве компаний; этот сценарий будет рассмотрен позже.

Давайте создадим публичный экземпляр Cloud SQL sql-instance-public-ip из Cloud Shell (который также будет выступать в качестве клиента в этом демо).

gcloud sql instances create sql-instance-public-ip 
  --assign-ip 
  --database-version=MYSQL_8_0 
  --cpu=1 --memory=4GB 
  --region=us-central1 
  --no-backup 
  --no-deletion-protection

gcloud sql users create testuser 
  --instance=sql-instance-public-ip 
  --password=testpassword 
  --type=BUILT_IN
Вход в полноэкранный режим Выход из полноэкранного режима

Флаг --assign-ip создаст публичный IP для экземпляра, который позволит подключаться непосредственно из интернета. Для нашего экземпляра SQL это 35.192.117.97, как показано ниже:

Обратившись к нашей таблице, мы видим, что для соединений по публичному IP нам необходимы авторизация и аутентификация.

  • Аутентификация: Был создан пользователь базы данных testuser. Это соответствует критериям аутентификации.
  • Авторизация: Как говорилось выше, у нас есть 3 варианта выполнения этого требования: Авторизованная сеть, Cloud SQL Auth Proxy, и самоуправляемые SSL/TLS сертификаты. Мы можем выбрать любой из этих вариантов. Для этого демонстрационного ролика давайте выберем Авторизованную сеть.

Поскольку я пытаюсь подключиться с экземпляра Cloud Shell, я возьму его публичный IP-адрес и добавлю его в авторизованную сеть экземпляра:

CLIENT_PUBLIC_IP=$(curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//')/32
gcloud sql instances patch sql-instance-public-ip 
  --authorized-networks=$CLIENT_PUBLIC_IP
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь, когда мы удовлетворяем критериям авторизации и аутентификации, мы можем проверить наше подключение с помощью клиента mysql из нашей Cloud Shell непосредственно к публичному IP (35.192.117.97) экземпляра Cloud SQL.

mysql 
  --host=35.192.117.97 
  --user=testuser 
  --password=testpassword
Вход в полноэкранный режим Выход из полноэкранного режима

Мы смогли успешно соединиться с экземпляром Cloud SQL по публичному сетевому пути!

2. Подключение к частному экземпляру Cloud SQL с экземпляра Compute Engine.

По сравнению с предыдущим сценарием вы, скорее всего, будете иметь дело с частными подключениями. Мы попытаемся подключиться к частному экземпляру Cloud SQL без публичного подключения с экземпляра Compute Engine, который будет выступать в качестве клиента с доступом к VPC, к которому подключен частный IP-адрес Cloud SQL.

Настройка сети

Прежде чем мы сможем создать частный экземпляр SQL, нам необходимо настроить VPC для обеспечения доступа к частным службам. Это требуется из-за того, как GCP моделирует сетевое взаимодействие экземпляров SQL. Это обсуждение выходит за рамки данной статьи, но вы можете ознакомиться с официальной документацией здесь, чтобы узнать больше о том, почему требуется доступ к частным службам.

Так или иначе, мы создадим новый VPC для этого демо, названный connectivity-demo-vpc, и подготовим его для экземпляра CloudSQL. Обратите внимание, что подсеть имеет RFC 1918 CIDR (192.168.1.0/24). Как упоминалось в разделе «Параметры подключения», это позволит нам полностью пропустить авторизацию с помощью Authorized Network для частных подключений, поскольку они авторизованы неявно.

gcloud compute networks create connectivity-demo-vpc 
  --subnet-mode=custom

gcloud compute networks subnets create subnet-a 
  --network=connectivity-demo-vpc 
  --range=192.168.1.0/24 
  --region=us-central1

gcloud compute addresses create private-services-ips 
  --network=connectivity-demo-vpc 
  --purpose=VPC_PEERING 
  --prefix-length=20 
  --global

gcloud services vpc-peerings connect 
  --service=servicenetworking.googleapis.com 
  --network=connectivity-demo-vpc 
  --ranges=private-services-ips

gcloud compute routers create nat-router 
  --network=connectivity-demo-vpc 
  --region=us-central1

gcloud compute routers nats create nat-config 
  --router-region=us-central1 
  --router=nat-router 
  --nat-all-subnet-ip-ranges 
  --auto-allocate-nat-external-ips
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь частная сеть настроена для экземпляра Cloud SQL. Мы также добавили Cloud Router и Cloud NAT, чтобы разрешить исходящие соединения с Интернетом из нашего частного экземпляра Compute Engine, который будет создан позже. Они не понадобятся, если ваш экземпляр вычислительной машины имеет публичный IP.

Экземпляр Cloud SQL

Теперь мы можем создать частный экземпляр Cloud SQL sql-instance-private-ip, который будет доступен только из вышеуказанного VPC.

gcloud sql instances create sql-instance-private-ip 
  --no-assign-ip 
  --network=connectivity-demo-vpc 
  --database-version=MYSQL_8_0 
  --cpu=1 --memory=4GB 
  --region=us-central1 
  --no-backup 
  --no-deletion-protection
Вход в полноэкранный режим Выход из полноэкранного режима

Флаг --no-assign-ip гарантирует, что публичный IP не будет назначен экземпляру, а флаг --network указывает VPC, из которого будет доступен частный IP экземпляра Cloud SQL.

Интересно отметить, что частный IP, назначенный экземпляру Cloud SQL, — это 10.250.64.3, который не попадает в диапазон подсетей, созданный для нашей сети! Вместо этого, он попадает в диапазон IP, который был автоматически назначен, когда мы создали выделенный диапазон IP private-services-ips в предыдущем шаге для доступа к частным службам. Это, опять же, следствие того, как GCP моделирует сеть для Cloud SQL.

Экземпляр Compute Engine

Мы настроим экземпляр Compute Engine в качестве клиента для экземпляра Cloud SQL, используя ту же сеть, которую мы создали выше, чтобы обеспечить частный сетевой путь между ними. На практике полезно настроить вычислительный экземпляр без внешнего IP в GCP. В зависимости от конкретного случая использования это может обеспечить лучшую изоляцию сети и дополнительные преимущества в плане безопасности.

Фактически, именно так мы настроим экземпляр для данного демонстрационного ролика.

gcloud compute instances create client-vm 
  --network-interface=network=connectivity-demo-vpc,subnet=subnet-a,no-address 
  --zone=us-central1-c 
  --machine-type=e2-micro 
  --scopes=default,sql-admin 
  --boot-disk-device-name=client-vm 
  --boot-disk-size=10GB 
  --image=projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20220810
Вход в полноэкранный режим Выход из полноэкранного режима

Опция --network-interface используется для того, чтобы сделать экземпляр частным и назначить его вышеуказанному VPC. Мы видим, что экземпляр создан без внешнего IP.

Поскольку у экземпляра Compute Engine нет внешнего IP, мы будем использовать IAP для доступа к нему извне сети. Мы внесем службу IAP в белый список нашей сети.

gcloud compute firewall-rules create allow-ssh-ingress-from-iap 
  --network=connectivity-demo-vpc 
  --direction=INGRESS 
  --action=allow 
  --rules=tcp:22 
  --source-ranges=35.235.240.0/20
Вход в полноэкранный режим Выход из полноэкранного режима

Кроме того, вам могут потребоваться эти роли в IAM, прежде чем вы сможете подключиться с помощью SSH через туннель IAP:

  • Пользователь защищенного туннеля IAP
  • Пользователь учетной записи службы
  • Администратор вычислительного экземпляра (v1)

Тест подключения (Direct)

Чтобы проверить подключение, давайте снова обратимся к таблице подключений. Мы видим, что для соединений Private IP нам действительно нужно настроить только аутентификацию. Авторизация необязательна, и мы избежали исключения для авторизованной сети, выбрав подсеть с RFC 1918 CIDR.

Поэтому все, что нам действительно нужно, это пользователь базы данных для аутентификации. Это должно удовлетворить критерии подключения для частного соединения.

gcloud sql users create testuser 
  --instance=sql-instance-private-ip 
  --password=testpassword 
  --type=BUILT_IN
Вход в полноэкранный режим Выход из полноэкранного режима

Мы можем подключиться по SSH к клиентскому экземпляру и попытаться соединиться с сервером Cloud SQL на его частном IP 10.250.64.3:

sudo apt install mysql-client -y
mysql 
  --host=10.250.64.3 
  --user=testuser 
  --password=testpassword
Вход в полноэкранный режим Выход из полноэкранного режима

Действительно, мы смогли успешно соединиться с экземпляром Cloud SQL по частному сетевому пути!

Добавление авторизации с помощью Cloud SQL Auth Proxy (необязательно)

Хотя мы и получили доступ к экземпляру Cloud SQL, соединение не авторизовано. Давайте пойдем дальше и рассмотрим, как можно использовать Cloud SQL Auth proxy для создания безопасного соединения с экземпляром Cloud SQL и авторизации соединения с помощью IAM.

Существуют различные способы использования Cloud SQL Auth Proxy, но я считаю, что им довольно просто управлять с помощью Docker. О других вариантах смотрите здесь.

Начнем с установки docker в вычислительном экземпляре.

sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo 
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu 
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
docker version
Входим в полноэкранный режим Выйти из полноэкранного режима

Это приведет к установке и запуску демона Docker. Загрузите докер-образ Cloud SQL Auth Proxy и создайте контейнер, передав ему имя подключения экземпляра Cloud SQL.

docker pull gcr.io/cloudsql-docker/gce-proxy:1.31.2
CONNECTION_NAME=$(gcloud sql instances describe sql-instance-private-ip --format="value(connectionName)")
docker run -d 
  -p 127.0.0.1:3306:3306 
  gcr.io/cloudsql-docker/gce-proxy:1.31.2 /cloud_sql_proxy 
  -instances=$CONNECTION_NAME=tcp:0.0.0.0:3306
Войти в полноэкранный режим Выход из полноэкранного режима

Cloud SQL Auth Proxy теперь туннелирует TCP сокет 127.0.0.1:3306 к экземпляру Cloud SQL. Это можно подтвердить, попробовав подключиться к серверу через локальный TCP-сокет.

mysql 
  --host=127.0.0.1 
  --user=testuser 
  --password=testpassword
Вход в полноэкранный режим Выход из полноэкранного режима

Мы смогли успешно подключиться к экземпляру Cloud SQL через Cloud SQL Auth Proxy.

Причина, по которой соединение было установлено, заключается в том, что экземпляру Compute Engine уже была предоставлена область доступа sql-admin, когда он был создан на предыдущем шаге, что позволяет учетной записи службы экземпляра получить положительную оценку доступа Cloud SQL Auth Proxy. В качестве альтернативы вы можете убедиться, что учетная запись службы VM имеет роль Cloud SQL Client или более высокие привилегии, чтобы Cloud SQL Auth Proxy мог авторизовать соединение.


Надеюсь, эта информация внесла некоторую ясность в то, как настраивать и диагностировать подключения к экземплярам Cloud SQL в GCP. Не стесняйтесь делиться любыми предложениями или вопросами.

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