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

时间:2016-12-15 21:04:04

标签: kubernetes google-cloud-sql cloud-sql-proxy

我想将我的Kubernetes群集连接到Google Cloud SQL。

我有至少10个不同部署的pod,目前使用JDBC url +用户名/密码连接到MySQL [部署到k8s的docker镜像]。

是否可以使用单个Google Cloud SQL Proxy实例并通过此代理将所有pod连接到Cloud SQL数据库?理想情况下,我想用代理替换容器中运行的mysql。

我不希望在每个部署中运行代理。我发现的唯一样本似乎表明需要在每个部署中声明代理。

3 个答案:

答案 0 :(得分:12)

我找到了解决方案。

使用下面的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代理,而无需对客户端配置进行任何修改。

答案 1 :(得分:1)

您可以创建部署和服务,以将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

因此,在您的任何广告连播中,MYSQL_HOST:MYSQL_PORT将是cloudsqlproxy:3306

的数据库

对于通过同一代理的多个数据库,您具有相同的代理部署结构,但您现在将从容器中公开2个端口,如下所示:

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

然后,您可以创建2个服务,以便在这些端口上进行发现,如下所示:

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

答案 2 :(得分:0)

使用Google“私有IP”,云代理现在不再需要了!