我需要使用 Go 从 Kubernetes pod 连接到 Google Cloud SQL。
我一直虔诚地遵循以下指南: https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine https://cloud.google.com/sql/docs/mysql/connect-external-app#go
这是我的 Kubernetes 部署 yaml 文件:
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-service
labels:
app: my-service
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 10%
maxSurge: 10%
replicas: 1
template:
metadata:
labels:
app: my-service
spec:
imagePullSecrets:
- name: regsecret
containers:
- name: my-service
image: my-image
imagePullPolicy: IfNotPresent
env:
- name: DB_INSTANCE
value: "my-project-id:europe-west1:uk"
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=my-project-id:europe-west1:uk=tcp:3306",
"-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
这是我尝试使用 Go 进行连接的尝试:
import (
"github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
"github.com/spf13/viper"
"log"
)
func Connect() {
cfg := mysql.Cfg(
viper.GetString("DB_INSTANCE"),
viper.GetString("DB_USERNAME"),
viper.GetString("DB_PASSWORD"))
cfg.DBName = "my-db-name"
db, err := mysql.DialCfg(cfg)
if err != nil {
log.Fatalf("Failed to create the Cloud SQL client: %v", err)
}
}
遗憾的是,运行此代码会导致:
2018/08/08 15:19:45 Failed to create the Cloud SQL client: ensure that the Cloud SQL API is enabled for your project (https://console.cloud.google.com/flows/enableapi?apiid=sqladmin). Error during createEphemeral for my-project-id:europe-west1:uk: googleapi: Error 403: Insufficient Permission, insufficientPermissions
我可以确认该数据库显然存在于 Cloud SQL 中,Cloud SQL API 确实已启用,并且我用于生成凭据的服务帐户(如上述链接中所述(确实附加了 Cloud SQL 客户端角色(我也尝试过使用 Cloud SQL 管理员甚至项目所有者,但没有成功(。
我错过了什么?
编辑:
通过将我的 Go 代码更新为:
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s",
viper.GetString("DB_USERNAME"),
viper.GetString("DB_PASSWORD"),
"127.0.0.1:3306",
"my-db-name")
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatalf("Failed to create the Cloud SQL client: %v", err)
}
感谢@DazWilkin提示。
您可以通过两种方式连接到实例: 1:通过TCP连接:您已经有了该解决方案,此页面向您显示详细信息。由于云 SQL 代理容器与应用容器在同一容器上运行,因此主机应指向 localhost
。 2:Unix套接字:
您还应该能够通过以下代码进行连接(此处详细介绍(:
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
dsn := fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s",
dbUser,
dbPassword,
INSTANCE_CONNECTION_NAME,
dbName)
db, err := sql.Open("mysql", dsn)
您可能需要从 deployment.yaml 文件中删除=tcp:3306
部分。