Conectar-se ao Cloud SQL pelo Google Kubernetes Engine

Nesta página, descrevemos como configurar uma conexão de um aplicativo em execução no Google Kubernetes Engine (GKE) com uma instância do Cloud SQL.

Para instruções passo a passo sobre como executar um aplicativo da Web de amostra do Google Kubernetes Engine conectado ao Cloud SQL, veja a guia de início rápido para se conectar no Google Kubernetes Engine.

O Cloud SQL é um serviço de banco de dados totalmente gerenciado que ajuda a configurar, manter, gerenciar e administrar seus bancos de dados relacionais na nuvem.

O Google Kubernetes Engine é uma maneira simples de implantar, escalonar e gerenciar o Kubernetes automaticamente.

Sobre a conexão do Google Kubernetes Engine ao Cloud SQL

Para acessar uma instância do Cloud SQL por meio de um aplicativo em execução no Google Kubernetes Engine, use o proxy de autenticação do Cloud SQL (com IP público ou particular) ou conecte-se diretamente usando um endereço IP particular.

É recomendável usar o proxy de autenticação do Cloud SQL para se conectar ao Cloud SQL, mesmo quando um IP particular está em uso. Isso porque o proxy de autenticação do Cloud SQL fornece criptografia e autenticação fortes por meio do IAM, o que pode ajudar a proteger o banco de dados.

As conexões do banco de dados consomem recursos no servidor e no aplicativo conectado. Sempre use boas práticas de gerenciamento de conexões para minimizar o espaço ocupado pelo seu aplicativo e reduzir a probabilidade de exceder os limites de conexão do Cloud SQL. Para mais informações, consulte Como gerenciar conexões de banco de dados.

Antes de começar

Para se conectar ao Cloud SQL, é preciso ter:

  • Um cluster do GKE, com a ferramenta de linha de comando kubectl instalada e configurada para se comunicar com o cluster.

    Para ajuda com o GKE, consulte Implantar um aplicativo em um cluster do GKE.

    Para se conectar usando um IP particular, o cluster do GKE precisa ser nativo de VPC e ter peering com a mesma rede de nuvem privada virtual (VPC) da instância do Cloud SQL.

  • Uma instância criada.

    Para ajuda na criação de uma instância do Cloud SQL, consulte Como criar instâncias.

  • Uma conta de usuário do MySQL configurada na instância.

    Seu aplicativo usará essa conta para se conectar ao banco de dados. Para ajuda na criação de uma conta de usuário, consulte Como criar um usuário.

Sobre os secrets do Kubernetes

No Kubernetes, os Secrets são uma maneira segura de transmitir detalhes de configuração para seu aplicativo. É possível criar um Secret com detalhes como o nome do banco de dados, o usuário e a senha que podem ser injetados no aplicativo como variáveis de ambiente.

Há muitas maneiras diferentes de usar Secrets, dependendo do tipo de conexão:

  • Um Secret de credenciais de banco de dados inclui o nome do usuário do banco de dados a que você está se conectando e a senha do banco de dados do usuário.
  • Ao se conectar ao proxy de autenticação do Cloud SQL, é possível usar um secret para armazenar o arquivo de credencial da conta de serviço.
  • Se você se conectar a um IP particular, um Secret poderá ser usado para especificar o endereço IP particular da instância do Cloud SQL.

Para exemplos completos de como usar secrets, consulte os repositórios do GitHub mencionados posteriormente nesta página.

Criar um objeto Secret

  1. Crie os objetos Secret usando o comando kubectl create secret.

    Para criar um Secret de credenciais de banco de dados:

    kubectl create secret generic <YOUR-DB-SECRET> \
      --from-literal=username=<YOUR-DATABASE-USER> \
      --from-literal=password=<YOUR-DATABASE-PASSWORD> \
      --from-literal=database=<YOUR-DATABASE-NAME>
    
  2. Após a criação, é possível visualizar os objetos na seção Configuração da página do Google Kubernetes Engine no console do Google Cloud.

Conectar-se ao Cloud SQL usando o proxy de autenticação do Cloud SQL

Quando você se conecta usando o proxy de autenticação do Cloud SQL, ele é adicionado ao pod por meio do padrão de contêiner sidecar. O contêiner do proxy de autenticação do Cloud SQL está no mesmo pod que o aplicativo, o que permite que o aplicativo se conecte ao proxy por meio de localhost, aumentando a segurança e o desempenho.

Para mais informações sobre o proxy de autenticação do Cloud SQL, consulte Sobre o proxy de autenticação do Cloud SQL. Para mais informações sobre como trabalhar com pods, consulte Visão geral de pods na documentação do Kubernetes.

Para se conectar usando o proxy de autenticação do Cloud SQL, você precisa do seguinte:

  1. O nome da conexão da instância do Cloud SQL.

    O nome da conexão da instância está disponível na página Detalhes da instância do Cloud SQL do console do Google Cloud ou pelo comando gcloud sql instances describe INSTANCE_ID.

  2. O local do arquivo de chaves associado a uma conta de serviço com os privilégios adequados para sua instância do Cloud SQL.

    Para mais informações, consulte Como criar uma conta de serviço.

  3. A API Cloud SQL Admin está ativada.

    Enable the API

Fornecer a conta de serviço ao proxy de autenticação do Cloud SQL

A primeira etapa para executar o proxy de autenticação do Cloud SQL no Google Kubernetes Engine é criar uma conta de serviço do Google (GSA) para representar o aplicativo. É recomendável criar uma conta de serviço exclusiva para cada aplicativo, em vez de usar a mesma em todos os lugares. Este modelo é mais seguro, porque permite limitar as permissões por aplicativo.

A conta de serviço do seu aplicativo precisa atender aos seguintes critérios:

  • pertencer a um projeto com a API Cloud SQL Admin ativada;
  • ter o papel do IAM de cliente do Cloud SQL (ou equivalente) no projeto que contém a instância à qual você quer se conectar;
  • ao se conectar usando IP privado, é preciso usar um cluster do GKE nativo de VPC na mesma VPC da sua instância do Cloud SQL.

Você precisa configurar o GKE para fornecer a conta de serviço ao proxy de autenticação do Cloud SQL. Há duas maneiras recomendadas de fazer isso: identidade da carga de trabalho ou um arquivo de chave da conta de serviço.

Identidade da carga de trabalho

Se você estiver usando o Google Kubernetes Engine, o método preferencial é usar o recurso Identidade da carga de trabalho do GKE. Esse método permite vincular uma conta de serviço do Kubernetes (KSA, na sigla em inglês) a uma conta de serviço do Google (GSA, na sigla em inglês). A GSA poderá ser acessada por aplicativos que usam a KSA correspondente.

Uma conta de serviço do Google (GSA) é uma identidade do IAM que representa o aplicativo no Google Cloud. De modo similar, uma conta de serviço do Kubernetes (KSA) é uma identidade que representa o aplicativo em um cluster do Google Kubernetes Engine.

A Identidade da carga de trabalho vincula uma KSA a uma GSA, fazendo com que qualquer implantação com essa KSA seja autenticada como a GSA nas interações com o Google Cloud.

  1. Ativar a identidade da carga de trabalho para o cluster
  2. Em geral, cada aplicativo tem a própria identidade, representada por um par de KSA e GSA. Crie uma KSA para seu aplicativo executando kubectl apply -f service-account.yaml:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: <YOUR-KSA-NAME> # TODO(developer): replace these values
  3. Ative a vinculação do IAM entre YOUR-GSA-NAME e YOUR-KSA-NAME:

    gcloud iam service-accounts add-iam-policy-binding \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:YOUR-GOOGLE-CLOUD-PROJECT.svc.id.goog[YOUR-K8S-NAMESPACE/YOUR-KSA-NAME]" \
    YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
  4. Adicione uma anotação a YOUR-KSA-NAME para concluir a vinculação:

    kubectl annotate serviceaccount \
    YOUR-KSA-NAME \
    iam.gke.io/gcp-service-account=YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
  5. Por fim, especifique a conta de serviço do objeto k8s.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: <YOUR-DEPLOYMENT-NAME>
    spec:
      selector:
        matchLabels:
          app: <YOUR-APPLICATION-NAME>
      template:
        metadata:
          labels:
            app: <YOUR-APPLICATION-NAME>
        spec:
          serviceAccountName: <YOUR-KSA-NAME>

Arquivo de chave da conta de serviço

Se não for possível usar a Identidade da carga de trabalho, o padrão recomendado é montar um arquivo de chave da conta de serviço no pod do proxy de autenticação do Cloud SQL e usar a flag --credentials-file.

  1. Crie um arquivo de credencial para a chave da sua conta de serviço:

    gcloud iam service-accounts keys create ~/key.json \
    --iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com
  2. Transforme a chave da sua conta de serviço em um Secret do k8s:

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
  3. Ative o secret como um volume no spec: do objeto k8s:

    volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>
  4. Siga as instruções na próxima seção para acessar o volume pelo pod do proxy de autenticação do Cloud SQL.

Executar o proxy de autenticação do Cloud SQL em um padrão de arquivo secundário

Recomendamos executar o proxy de autenticação do Cloud SQL em um padrão sidecar, que apresenta um contêiner adicional que compartilha um pod com o aplicativo. Recomendamos isso em vez de ser executado como um serviço separado por vários motivos:

  • Impede que o tráfego SQL seja exposto localmente. O proxy de autenticação do Cloud SQL fornece criptografia nas conexões de saída, mas você precisa limitar a exposição das conexões de entrada.
  • Impede um único ponto de falha. O acesso de cada aplicativo ao seu banco de dados é independente dos outros, tornando-o mais resiliente.
  • Limita o acesso ao proxy de autenticação do Cloud SQL, permitindo o uso de permissões do IAM por aplicativo, em vez de expor o banco de dados a todo o cluster.
  • Permite que você defina o escopo das solicitações de recursos com mais precisão. Como o proxy de autenticação do Cloud SQL consome recursos linearmente ao uso, esse padrão permite que você defina o escopo com mais precisão e solicite recursos para corresponder aos seus aplicativos à medida que eles são escalonados.

  • Adicione o proxy de autenticação do Cloud SQL à configuração do pod em containers:

    - name: cloud-sql-proxy
      # It is recommended to use the latest version of the Cloud SQL Auth Proxy
      # Make sure to update on a regular schedule!
      image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.14.1
      args:
        # If connecting from a VPC-native GKE cluster, you can use the
        # following flag to have the proxy connect over private IP
        # - "--private-ip"
    
        # If you are not connecting with Automatic IAM, you can delete
        # the following flag.
        - "--auto-iam-authn"
    
        # Enable structured logging with LogEntry format:
        - "--structured-logs"
    
        # Replace DB_PORT with the port the proxy should listen on
        - "--port=<DB_PORT>"
        - "<INSTANCE_CONNECTION_NAME>"
    
      securityContext:
        # The default Cloud SQL Auth Proxy image runs as the
        # "nonroot" user and group (uid: 65532) by default.
        runAsNonRoot: true
      # You should use resource requests/limits as a best practice to prevent
      # pods from consuming too many resources and affecting the execution of
      # other pods. You should adjust the following values based on what your
      # application needs. For details, see
      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
      resources:
        requests:
          # The proxy's memory use scales linearly with the number of active
          # connections. Fewer open connections will use less memory. Adjust
          # this value based on your application's requirements.
          memory: "2Gi"
          # The proxy's CPU use scales linearly with the amount of IO between
          # the database and the application. Adjust this value based on your
          # application's requirements.
          cpu: "1"

    Se você estiver usando uma chave de conta de serviço, especifique o volume do secret e adicione a sinalização --credentials-file ao comando:

      # This flag specifies where the service account key can be found
      - "--credentials-file=/secrets/service_account.json"
    securityContext:
      # The default Cloud SQL Auth Proxy image runs as the
      # "nonroot" user and group (uid: 65532) by default.
      runAsNonRoot: true
    volumeMounts:
      - name: <YOUR-SA-SECRET-VOLUME>
        mountPath: /secrets/
        readOnly: true
  • Por fim, configure seu aplicativo para se conectar usando 127.0.0.1 no DB_PORT especificado na seção de comando.

Conclua os arquivos de configuração de amostra:

Identidade da carga de trabalho

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      serviceAccountName: <YOUR-KSA-NAME>
      containers:
        - name: <YOUR-APPLICATION-NAME>
          # ... other container configuration
          env:
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: username
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: password
            - name: DB_NAME
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: database
        - name: cloud-sql-proxy
          # It is recommended to use the latest version of the Cloud SQL Auth Proxy
          # Make sure to update on a regular schedule!
          image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.14.1
          args:
            # If connecting from a VPC-native GKE cluster, you can use the
            # following flag to have the proxy connect over private IP
            # - "--private-ip"

            # If you are not connecting with Automatic IAM, you can delete
            # the following flag.
            - "--auto-iam-authn"

            # Enable structured logging with LogEntry format:
            - "--structured-logs"

            # Replace DB_PORT with the port the proxy should listen on
            - "--port=<DB_PORT>"
            - "<INSTANCE_CONNECTION_NAME>"

          securityContext:
            # The default Cloud SQL Auth Proxy image runs as the
            # "nonroot" user and group (uid: 65532) by default.
            runAsNonRoot: true
          # You should use resource requests/limits as a best practice to prevent
          # pods from consuming too many resources and affecting the execution of
          # other pods. You should adjust the following values based on what your
          # application needs. For details, see
          # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
          resources:
            requests:
              # The proxy's memory use scales linearly with the number of active
              # connections. Fewer open connections will use less memory. Adjust
              # this value based on your application's requirements.
              memory: "2Gi"
              # The proxy's CPU use scales linearly with the amount of IO between
              # the database and the application. Adjust this value based on your
              # application's requirements.
              cpu: "1"

Chave da conta de serviço

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
        - name: <YOUR-APPLICATION-NAME>
          # ... other container configuration
          env:
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: username
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: password
            - name: DB_NAME
              valueFrom:
                secretKeyRef:
                  name: <YOUR-DB-SECRET>
                  key: database
        - name: cloud-sql-proxy
          # It is recommended to use the latest version of the Cloud SQL Auth Proxy
          # Make sure to update on a regular schedule!
          image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.14.1
          args:
            # If connecting from a VPC-native GKE cluster, you can use the
            # following flag to have the proxy connect over private IP
            # - "--private-ip"

            # If you are not connecting with Automatic IAM AuthN, you can delete
            # the following flag.
            - "--auto-iam-authn"

            # Enable structured logging with LogEntry format:
            - "--structured-logs"

            # Replace DB_PORT with the port the proxy should listen on
            - "--port=<DB_PORT>"
            - "<INSTANCE_CONNECTION_NAME>"

            # This flag specifies where the service account key can be found
            - "--credentials-file=/secrets/service_account.json"
          securityContext:
            # The default Cloud SQL Auth Proxy image runs as the
            # "nonroot" user and group (uid: 65532) by default.
            runAsNonRoot: true
          volumeMounts:
            - name: <YOUR-SA-SECRET-VOLUME>
              mountPath: /secrets/
              readOnly: true
          # Resource configuration depends on an application's requirements. You
          # should adjust the following values based on what your application
          # needs. For details, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
          resources:
            requests:
              # The proxy's memory use scales linearly with the number of active
              # connections. Fewer open connections will use less memory. Adjust
              # this value based on your application's requirements.
              memory: "2Gi"
              # The proxy's CPU use scales linearly with the amount of IO between
              # the database and the application. Adjust this value based on your
              # application's requirements.
              cpu: "1"
      volumes:
        - name: <YOUR-SA-SECRET-VOLUME>
          secret:
            secretName: <YOUR-SA-SECRET>

Conectar-se ao Cloud SQL sem o proxy de autenticação do Cloud SQL

Ainda que não seja tão seguro, é possível se conectar por um cluster do GKE nativo de VPC a uma instância do Cloud SQL na mesma VPC usando um IP particular sem o proxy de autenticação do Cloud SQL.

  1. Crie um secret com o endereço IP privado da instância:

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. Em seguida, adicione o secret ao contêiner do aplicativo:

    - name: DB_HOST
      valueFrom:
        secretKeyRef:
          name: <YOUR-PRIVATE-IP-SECRET>
          key: db_host
  3. Por fim, configure seu aplicativo para se conectar usando o endereço IP a partir da variável de ambiente DB_HOST. Você precisará usar a porta correta para o MySQL: 3306

Conclua o arquivo de configuração de amostra:

IP particular

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: <YOUR-PRIVATE-IP-SECRET>
              key: db_host

Solução de problemas

Precisa de ajuda? Para receber ajuda na solução de problemas do proxy, consulte Solução de problemas de conexões do proxy de autenticação do Cloud SQL ou a página Suporte do Cloud SQL.

A seguir