Как подключиться к Cloud SQL (2-го поколения) через MySQL Proxy Docker Container через TCP

Работая в Mac OS X, я пытался подключиться к экземпляру Cloud SQL через прокси, используя эти направления. После того, как вы установили клиент MySQL, контейнер gce-proxy и создали учетную запись службы в Google Cloud Platform, вы можете приступить к выполнению этих двух команд, указанных в документации:

docker run -d -v /cloudsql:/cloudsql \
  -v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
  b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
  -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 -credential_file=[CLOUD_KEY_FILE_PATH]

mysql -h127.0.0.1 -uroot -p

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

ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61)

Но если я открываю порт, добавляя -p 3306:3306 к команде docker run, я все равно не могу подключиться. Вместо этого я получаю от клиента MySQL следующую ошибку:

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

Я успешно подключился к прокси, запущенному cloud_sql_proxy на моем хост-компьютере докера, следуя этой документации, поэтому я уверен, что мой файл учетных данных и мой клиент mysql настроены правильно. В журналах контейнера не указывается, что была предпринята попытка подключения. У меня нет проблем с подключением к обычному контейнеру mysql через докер. Что мне здесь не хватает?


person Technetium    schedule 14.10.2016    source источник


Ответы (3)


Похоже, что в документации есть некоторые упущения.

1) Как вы указываете, вам нужно выставить порт из контейнера. Убедитесь, что вы открываете его только для локального компьютера, указав -p 127.0.0.1:3306:3306.

2) Затем при запуске контейнера вы захотите открыть порт за пределами контейнера, указав -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306

person Vadim    schedule 16.10.2016

Мне удалось выяснить, как использовать cloudql-proxy в моей локальной среде докеров с помощью docker-compose. Вам нужно будет загрузить учетные данные своего экземпляра Cloud SQL и подготовить их. Я сохраняю их в корне моего проекта как credentials.json и добавляю их в свой .gitignore в проекте.

Ключевой частью, которую я обнаружил, было использование =tcp:0.0.0.0:5432 после идентификатора экземпляра GCP, чтобы порт можно было перенаправить. Затем в вашем приложении используйте cloudsql-proxy вместо localhost в качестве имени хоста. Убедитесь, что остальные ваши кредиты БД действительны в секретах вашего приложения, чтобы оно могло подключаться через локальный прокси-сервер, предоставляемый контейнером cloudql-proxy.

Примечание. Имейте в виду, что я пишу Java-приложение Tomcat, и мой docker-compose.yml это отражает.

docker-compose.yml:

version: '3'
services:
  cloudsql-proxy:
      container_name: cloudsql-proxy
      image: gcr.io/cloudsql-docker/gce-proxy:1.11
      command: /cloud_sql_proxy --dir=/cloudsql -instances=<YOUR INSTANCE ID HERE>=tcp:0.0.0.0:5432 -credential_file=/secrets/cloudsql/credentials.json
      ports:
        - 5432:5432
      volumes:
        - ./credentials.json:/secrets/cloudsql/credentials.json
      restart: always

  tomcatapp-api:
    container_name: tomcatapp-api
    build: .
    volumes:
      - ./build/libs:/usr/local/tomcat/webapps
    ports:
      - 8080:8080
      - 8000:8000
    env_file:
      - ./secrets.env
    restart: always
person Dan    schedule 24.01.2018

Я попробовал предложение @Vadim, которое в основном таково:

docker run -d -v /cloudsql:/cloudsql \
  -p 127.0.0.1:3306:3306 \ 
  -v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
  b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
  -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 -credential_file=[CLOUD_KEY_FILE_PATH]

Мне все еще не удалось установить соединение, так как я все еще получаю эту ошибку:

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

Однако журналы контейнера докеров показали соединение, например:

2016/10/16 07:52:32 New connection for "[INSTANCE_CONNECTION_NAME]"
2016/10/16 07:52:32 couldn't connect to "[INSTANCE_CONNECTION_NAME]": Post https://www.googleapis.com/sql/v1beta4/projects/[PROJECT_NAME]/instances/[CLOUD_SQL_INSTANCE_NAME]/createEphemeral?alt=json: oauth2: cannot fetch token: Post https://accounts.google.com/o/oauth2/token: x509: failed to load system roots and no roots provided

Итак, теперь оказалось, что он получает трафик, но не находит сертификаты для контейнера SSL. Я использовал OpenSSL cert.pem экспорт моих сертификатов и смонтировал его в то же место в контейнере докера. Логично предположить, что произвольное сопоставление [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] не помогло прокси-серверу определить, где находятся сертификаты. Поэтому я воспользовался подсказкой из этого руководства по установке Kubernetes. и измените смонтированный том на -v [LOCAL_CERTIFICATE_FILE_PATH]:/etc/ssl/certs. К счастью, это сработало.

TL; DR - вот последний синтаксис для запуска контейнера Docker через TCP:

docker run -d \
    -p 127.0.0.1:3306:3306 \
    -v [SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY]:[SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY] \
    -v [LOCAL_CERTIFICATE_DIRECTORY]:/etc/ssl/certs \
    b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
    -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 \
    -credential_file=[SERVICE_ACCOUNT_PRIVATE_KEY_JSON_FILE]
person Technetium    schedule 17.10.2016
comment
Чтобы уточнить, файл сертификатов предназначен для сертификатов корневого центра сертификации. Вам не нужно предоставлять прокси-серверы сертификаты Cloud SQL. - person Vadim; 17.10.2016