IT

클라우드 함수에서 Google Cloud SQL을 연결하는 방법은 무엇입니까?

itgroup 2023. 6. 17. 09:02
반응형

클라우드 함수에서 Google Cloud SQL을 연결하는 방법은 무엇입니까?

Cloud Functions for Firebase를 사용하여 Google Cloud SQL(Postgre)과 대화하는 API를 구축하려고 합니다.SQL) 인스턴스입니다.

HTTP(S) 트리거를 사용하고 있습니다.

데스크톱의 IP 주소를 화이트리스트에 올리면 로컬 컴퓨터에서 함수의 node.js 코드로 Cloud SQL에 연결할 수 있습니다.그러나 배포할 때 연결할 수 없고 Firebase Function 서버의 HOST IP 주소를 화이트리스트로 확인할 수 없습니다.

Firebase용 Cloud Functions에서 Google Cloud SQL과 어떻게 대화합니까?

감사합니다!

// Code Sample, of what's working on Localhost.
var functions = require('firebase-functions');

var pg = require('pg');
var pgConfig = {
  user: functions.config().pg.user,
  database: functions.config().pg.database,
  password: functions.config().pg.password,
  host: functions.config().pg.host
}

exports.helloSql = functions.https.onRequest((request, response) => {
  console.log('connecting...');
  try {
    client.connect(function(err) {
      if (err) throw err;

      console.log('connection success');
      console.log('querying...');

      client.query('SELECT * FROM guestbook;', function(err, result){
        if (err) throw err;

        console.log('querying success.');
        console.log('Results: ', result);
        console.log('Ending...');

        client.end(function(err){
          if (err) throw err;
          console.log('End success.');
          response.send(result);
        });
      });

    });
  } catch(er) {
    console.error(er.stack)
    response.status(500).send(er);
  }
});

#36388165에 대한 추가 논의에서 답을 찾았습니다.

고지 사항: 공식적으로 발표되지 않은 것 같으니 이후에 변경될 수 있습니다.또한 나는 mysql에서만 테스트를 합니다. 하지만 이 솔루션의 특성상 pg 모듈과 동일한 방식으로 작동해야 한다고 생각합니다(도메인 소켓 경로를 호스트 매개 변수로 수락하는 것 같습니다).

EDIT(2017/12/7): 구글은 공식적인 조기 접속을 제공하는 것으로 보이며, 동일한 방법이 여전히 작동합니다.
EDIT (2018/07/04): 누군가가 제 예시 코드를 복사해서 붙여넣고 문제를 일으키는 것 같습니다.구글이 말하는 것처럼, 당신은 sql 연결 누출을 피하기 위해 연결 풀을 사용해야 합니다.(ECONNREFUSE를 유발함) 그래서 예제 코드를 조금 변경합니다.EDIT(2019/04/04): 아래 예제에서 $DBNAME을 스패너 인스턴스 이름으로 사용하는 것은 혼란스럽습니다. 예제를 수정합니다.

https://issuetracker.google.com/issues/36388165#comment44 에서 Google guy는 클라우드 함수 인스턴스가 '/cloudsql/$PROJECT_ID:$REGION:$DBNAME' 경로의 도메인 소켓을 통해 클라우드 SQL과 대화할 수 있다고 말합니다.

저는 실제로 아래의 클라우드 함수 코드에서 클라우드 SQL을 연결하고 운영할 수 있습니다.

const mysql = require('mysql');
const pool = mysql.createPool({
    connectionLimit : 1,
    socketPath: '/cloudsql/' + '$PROJECT_ID:$REGION:$SPANNER_INSTANCE_NAME',
    user: '$USER',
    password: '$PASS',
    database: '$DATABASE'
});
exports.handler = function handler(req, res) {
    //using pool instead of creating connection with function call
    pool.query(`SELECT * FROM table where id = ?`, 
                                req.body.id, function (e, results) {
        //made reply here
    });
};

이것이 구글의 공식 발표를 기다릴 수 없는 사람들에게 도움이 되기를 바랍니다.

답변:

다른 답변을 참조하십시오. 이제 공식적으로 지원됩니다.https://cloud.google.com/functions/docs/sql

이전 답변:

현재는 불가능합니다.그러나 문제 추적기 #36388165의 기능 요청입니다.

UNIX 소켓이 존재하지 않고(ENONT 발생) 화이트리스트에 대한 정의된 IP 범위가 없기 때문에(ETIMEDOUT 발생) Cloud Functions에서 Cloud SQL에 연결하는 것은 현재 지원되지 않습니다.Cloud SQL 인스턴스에서 0.0.0.0/0을 화이트리스트로 지정할 수 있지만 보안상의 이유로 이 방법을 사용하지 않는 것이 좋습니다.

만약 이것이 당신에게 중요한 기능이라면, 저는 당신이 이슈 추적기를 방문하여 인기를 얻도록 도와줄 것을 제안합니다.

GCP > SQL > Instances 페이지에서 데이터베이스 영역 및 인스턴스 이름을 찾습니다.

enter image description here

다음을 실행하여 데이터베이스 암호를 Firebase 환경에 저장합니다.

$ firebase functions:config:set \
    db.user="<username>" \
    db.password="<password>" \
    db.database="<database>"

그러면...

db.js

const { Pool } = require('pg');
const { config } = require('firebase-functions');

const project = process.env.GCP_PROJECT;
const region = 'europe-west1';
const instance = 'db';

module.exports = new Pool({
  max: 1,
  host: `/cloudsql/${project}:${region}:${instance}`,
  ...config().db
});

someFunction.js

const { https } = require('firebase-functions');
const db = require('./db');

module.exports = https.onRequest((req, res) =>
  db
    .query('SELECT version()')
    .then(({ rows: [{ version }]) => {
      res.send(version);
    }));

참고 항목: https://stackoverflow.com/a/48825037/82686 (Babel을 통한 최신 JavaScript 구문 사용)

이제 이것에 대한 공식 문서가 있지만, 2018년 7월에도 여전히 베타에 있습니다.

https://cloud.google.com/functions/docs/sql

TCP 및 UNIX 도메인 소켓을 사용하여 구글 클라우드 기능에서 클라우드 SQL로 연결 2020

1. 새 프로젝트 만들기

gcloud projects create gcf-to-sql
gcloud config set project gcf-to-sql
gcloud projects describe gcf-to-sql

2. 프로젝트에 대한 청구 활성화: https://cloud.google.com/billing/docs/how-to/modify-project

3. Compute project-info 메타데이터를 설정합니다.

gcloud compute project-info describe --project gcf-to-sql
#Enable the Api, and you can check that default-region,google-compute-default-zone are not set. Set the metadata.
gcloud compute project-info add-metadata --metadata google-compute-default-region=europe-west2,google-compute-default-zone=europe-west2-b

4.서비스 네트워킹 API 사용:

gcloud services list --available
gcloud services enable servicenetworking.googleapis.com

5. 2개의 클라우드 SQL 인스턴스를 생성합니다(내부 IP가 있는 인스턴스와 공용 IP가 있는 인스턴스). - https://cloud.google.com/sql/docs/mysql/create-instance :

6.외부 IP를 사용하는 Cloud Sql 인스턴스:

#Create the sql instance in the 
gcloud --project=con-ae-to-sql beta sql instances create database-external --region=europe-west2
#Set the password for the "root@%" MySQL user:
gcloud sql users set-password root --host=% --instance database-external --password root 
#Create a user
gcloud sql users create user_name --host=% --instance=database-external  --password=user_password
#Create a database
gcloud sql databases create user_database --instance=database-external
gcloud sql databases list --instance=database-external

6.b 내부 IP를 사용하는 Cloud Sql Instance:

i.#Create a private connection to Google so that the VM instances in the default VPC network can use private services access to reach Google services that support it.

gcloud compute addresses create google-managed-services-my-network     --global  --purpose=VPC_PEERING --prefix-length=16  --description="peering range for Google"  --network=default --project=con-ae-to-sql
gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com --ranges=google-managed-services-my-network  --network=default  --project=con-ae-to-sql
#Check whether the operation was successful.
gcloud services vpc-peerings operations describe     --name=operations/pssn.dacc3510-ebc6-40bd-a07b-8c79c1f4fa9a
#Listing private connections
gcloud services vpc-peerings list --network=default --project=con-ae-to-sql
 
ii.Create the instance:

gcloud --project=con-ae-to-sql beta sql instances create database-ipinternal --network=default --no-assign-ip  --region=europe-west2
#Set the password for the "root@%" MySQL user:
gcloud sql users set-password root --host=% --instance database-ipinternal --password root
#Create a user
gcloud sql users create user_name --host=% --instance=database-ipinternal  --password=user_password
#Create a database
gcloud sql databases create user_database --instance=database-ipinternal
gcloud sql databases list --instance=database-ipinternal 


gcloud sql instances list
gcloud sql instances describe database-external
gcloud sql instances describe database-ipinternal
#Remember the instances connectionName

두 개의 mysql 인스턴스가 있습니다. 이제 Google Cloud Functions에서 Serverless Access 및 TCP를 사용하는 database-ipinternal로 연결하고 Google Cloud Functions에서 Unix 도메인 소켓을 사용하는 database-external로 연결합니다.

7.Cloud SQL Admin API 사용

gcloud services list --available
gcloud services enable sqladmin.googleapis.com

참고: 기본적으로 Cloud Functions는 TCP를 사용한 Cloud SQL 인스턴스 연결을 지원하지 않습니다.서버리스 VPC 액세스를 구성하지 않은 경우 코드는 IP 주소(예: 127.0.0.1 또는 172.17.0.1)를 사용하여 인스턴스에 액세스하려고 하면 안 됩니다.

8.a 프로젝트에 대해 서버리스 VPC 액세스 API가 활성화되었는지 확인합니다.

gcloud services enable vpcaccess.googleapis.com

8.b 커넥터 생성:

gcloud compute networks vpc-access connectors create serverless-connector --network default --region europe-west2 --range 10.10.0.0/28
#Verify that your connector is in the READY state before using it
gcloud compute networks vpc-access connectors describe serverless-connector --region europe-west2

9.클라우드 기능을 위한 서비스 계정을 만듭니다.서비스의 서비스 계정에 다음 IAM 역할이 있는지 확인합니다.Cloud SQL Client 및 App Engine Standard에서 내부 IP의 Cloud Sql로 연결하려면 Compute Network User 역할도 필요합니다.

gcloud iam service-accounts create cloud-function-to-sql
gcloud projects add-iam-policy-binding gcf-to-sql --member serviceAccount:cloud-function-to-sql@gcf-to-sql.iam.gserviceaccount.com   --role roles/cloudsql.client
gcloud projects add-iam-policy-binding gcf-to-sql --member serviceAccount:cloud-function-to-sql@gcf-to-sql.iam.gserviceaccount.com  --role roles/compute.networkUser

이제 설정을 구성했으므로

Tcp 및 unix 도메인 소켓을 사용하여 Google Cloud Functions에서 CloudSql로 연결

cd app-engine-standard/
ls
#main.py requirements.txt

cat requirements.txt
sqlalchemy
pymysql
      
cat main.py 
import pymysql
from sqlalchemy import create_engine


 def gcf_to_sql(request):

    engine_tcp = create_engine('mysql+pymysql://user_name:user_password@10.36.0.3:3306')
    existing_databases_tcp = engine_tcp.execute("SHOW DATABASES;")
    con_tcp = "Connecting from Google Cloud Functions to Cloud SQL using TCP: databases => " + str([d[0] for d in existing_databases_tcp]).strip('[]') + "\n"
    engine_unix_socket = create_engine('mysql+pymysql://user_name:user_password@/user_database?unix_socket=/cloudsql/gcf-to-sql:europe-west2:database-external')
    existing_databases_unix_socket = engine_unix_socket.execute("SHOW DATABASES;")
    con_unix_socket = "Connecting from Google Cloud Function  to Cloud SQL using Unix Sockets: tables in sys database:  => " + str([d[0] for d in existing_databases_unix_socket]).strip('[]') + "\n"
    return con_tcp + con_unix_socket
     

2. 클라우드 기능 배포:

gcloud beta functions deploy gcf_to_sql --runtime python37 --region europe-west2 --vpc-connector projects/gcf-to-sql/locations/europe-west2/connectors/serverless-connector  --trigger-http
 

Function( 기능하여 3을 선택합니다. Cloud Function(클라우드 기능)으로 이동하여gcf-to-sql테스트, 테스트 기능:

#Connecting from Google Cloud Functions to Cloud SQL using TCP: databases => 'information_schema', 'mysql', 'performance_schema', 'sys', 'user_database'
#Connecting from Google Cloud Function  to Cloud SQL using Unix Sockets: tables in sys database:  => 'information_schema', 'mysql', 'performance_schema', 'sys', 'user_database'

성공!

클라우드 기능 - 지원되는 서비스 - 이 목록에 Cloud SQL이 없으므로 아직 지원되지 않을 수 있습니다.

Firebase가 외부에서 사용하는 IP 주소를 잘 모르기 때문에 Firebase IP 주소 범위를 승인할 수도 있습니다.

저는 그것에 대해 실험해 보았습니다.Google Cloud SQL은 내부 IP 주소를 사용하지 않습니다.사용할 수 없습니다.10.128.0.0/20Google Cloud SQL의 내부 IP 주소를 허용합니다.

정답.

콘솔에서 다음으로 이동합니다.Google Cloud SQL > Instance > Authorization추가할 수 있는 항목:

151.101.0.0/17

그게 당신을 허락할 것입니다.151.101.0.0로.151.101.127.255IP 주소 범위. 여기서 Firebase 서버 도메인은 현재151.101.1.195그리고.151.101.65.195.

이 IP 주소가 변경될지 확신할 수 없습니다.

또한 Cloud SQL Database에서 다음을 사용하고 있는지 확인합니다.us-central지역입니다. 소방 기지는 다음 지역에서 이용할 수 있는 것 같습니다.us-central.

언급URL : https://stackoverflow.com/questions/43023107/how-to-connect-google-cloud-sql-from-cloud-functions

반응형