多个K8S容器通过代理连接Google Cloud SQL

8
我想将我的Kubernetes集群连接到Google Cloud SQL。
目前,我至少有10个不同的部署pod,它们使用JDBC url +用户名/密码连接到MySQL [在k8s上部署的docker镜像]。
是否可以使用单个Google Cloud SQL代理实例,并通过此代理将所有pod连接到Cloud SQL数据库?理想情况下,我希望用代理替换容器中运行的mysql。
我不想在每个部署中都运行代理。我找到的唯一示例似乎表明代理需要在每个部署中声明。
3个回答

15

我找到了一个解决方案。

使用下面的 yml 部署代理,并将部署暴露为服务。最重要的是,让代理监听 0.0.0.0,而不是默认的 127.0.0.1。所有的秘密都按照 Google Cloud sql 文档。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  template:
    metadata:
      name: mysql
      labels:
        name: mysql
    spec:
      containers:
         - image: b.gcr.io/cloudsql-docker/gce-proxy:1.05
           name: cloudsql-proxy
           command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                     "-instances=MYSQL:ZONE:DATABASE_INSTANCE=tcp:0.0.0.0:3306",
                     "-credential_file=/secrets/cloudsql/credentials.json"]
           volumeMounts:
             - name: cloudsql-oauth-credentials
               mountPath: /secrets/cloudsql
               readOnly: true
             - name: ssl-certs
               mountPath: /etc/ssl/certs
           ports:
             - containerPort: 3306
               name: mysql
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs

相比于将代理与客户端软件部署在同一个位置上,该解决方案略微更昂贵,因为需要额外的TCP连接。

然而,它有许多好处:

  • 更简单,不需要修改现有的K8S部署文件
  • 允许在不修改客户端配置的情况下将实现切换到MySQL Docker容器或使用Google Cloud SQL代理。

我对@Hylton Peimer的问题很感兴趣 - 我面临着同样的问题:我需要在一个单独的pod中托管SQL代理,但是你是如何让你的两个pod相互通信的呢?我要么得到连接被拒绝的错误,要么得到找不到主机名的错误。 - J Young
为部署暴露一个 Kubernetes 服务。然后使用该服务的名称。例如,以上命令 "kubectl expose deployment mysql",然后客户端使用 "mysql" 就像使用主机名一样。 - Hylton Peimer
1
虽然我和你有同样的问题,但在同一个 pod 中运行代理作为 sidecar 容器有一些好处:
  • 通过将代理暴露给集群,除非以其他方式保护它,否则您会失去对哪些服务可以访问它的控制权。
  • 如果不使用标签和选择器,您无法确定每个需要它的节点上是否正在运行代理 pod,这可能会影响性能,具体取决于哪个客户端需要与服务器通信以及该客户端是否恰好在与代理相同的节点上。
- Khash
将默认值tcp:5432更改为tcp:0.0.0.0:5432对我起了作用,因为tcp:5432隐式地转换为tcp:127.0.0.1:5432 - Cole
考虑使用 Google Cloud SQL 的私有 IP。这样,您就不再需要代理,可以直接从 K8S 内部连接到 SQL 实例。 - Hylton Peimer

3
您可以创建一个部署和一个服务来将CloudSQL代理暴露给其他Pod,方法如下:
apiVersion: v1
kind: Service
metadata:
  name: cloudsqlproxy
spec:
  ports:
  - port: 3306
    targetPort: database-port
  selector:
    app: cloudsqlproxy
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cloudsqlproxy
spec:
  template:
    metadata:
      labels:
        app: cloudsqlproxy
    spec:
      volumes:
      - name: service-account-token
        secret:
          secretName: service-account-token
      containers:
      - name: cloudsql-proxy
        image: gcr.io/cloudsql-docker/gce-proxy:1.11
        imagePullPolicy: Always
        command:
        - /cloud_sql_proxy
        - -instances=<project>:<cloudsqlinstance>=tcp:0.0.0.0:3306
        - -credential_file=/secrets/cloudsql/credentials.json
        ports:
        - name: database-port
          containerPort: 3306
        volumeMounts:
        - name: service-account-token
          mountPath: /secrets/cloudsql
          readOnly: true

在任何一个pod中,你的数据库 MYSQL_HOST:MYSQL_PORT 都将是 cloudsqlproxy:3306

如果要通过同一个代理使用多个数据库,则代理的部署结构相同,只不过现在需要从pod中公开2个端口,如下所示:

apiVersion: extensions/v1beta1
...
spec:
  template:
    ...
    spec:
      volumes:
      ...
      containers:
      - name: cloudsql-proxy
        ...
        ports:
        - name: database-port1
          containerPort: 3306
        - name: database-port2
          containerPort: 3307
        ...

然后您需要创建两个服务来为这些端口进行发现,如下所示:

apiVersion: v1
kind: Service
metadata:
  name: cloudsqlproxy-db1
spec:
  ports:
  - port: 3306
    targetPort: database-port1
  selector:
    app: cloudsqlproxy
---
apiVersion: v1
kind: Service
metadata:
  name: cloudsqlproxy-db2
spec:
  ports:
  - port: 3306
    targetPort: database-port2
  selector:
    app: cloudsqlproxy

所以,当两个服务都设置为端口3306时,您可以在该端口连接到每个数据库:
mysql --host=cloudsqlproxy-db1 --port=3306 ...
mysql --host=cloudsqlproxy-db2 --port=3306 ...

参考资料:https://github.com/GoogleCloudPlatform/cloudsql-proxy/blob/master/Kubernetes.md

这篇文章介绍了如何在Kubernetes中使用Google Cloud SQL Proxy。Google Cloud SQL Proxy是一种用于连接Google Cloud SQL数据库的代理程序,它可以帮助您更安全地访问和管理数据库。


这太棒了,应该标记为被接受的答案。 - Surabhi Sharma

0

通过谷歌的“私有IP”,云代理现在已经不再重要!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接