Como se conectar pelo Google Kubernetes Engine

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

Introdução

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

É recomendável usar o proxy do Cloud SQL Auth para se conectar ao Cloud SQL, mesmo quando um IP particular estiver sendo usado. Isso ocorre porque o proxy do Cloud SQL Auth fornece criptografia e autenticação fortes usando o 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ão 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 o Início rápido.

    Para se conectar usando um IP privado, o cluster do GKE precisa ser nativo de VPC e estar na mesma rede 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 PostgreSQL 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 secrets

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.
  • Se você estiver se conectando ao proxy do Cloud SQL Auth, um Secret poderá ser usado para armazenar o arquivo de credencial da sua 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.

Como 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 Cloud.

Como se conectar pelo proxy do Cloud SQL Auth

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

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

Para se conectar usando o proxy do Cloud SQL Auth, 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 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.

    Ative a API

Como fornecer a conta de serviço ao proxy do Cloud SQL Auth

A primeira etapa para executar o proxy do Cloud SQL Auth no Google Kubernetes Engine é criar uma conta de serviço do Google (GSA, na sigla em inglês) 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 do Cloud SQL Auth. Há duas maneiras recomendadas de fazer isso: identidade da carga de trabalho ou um arquivo de chave da conta de serviço.

Workload Identity

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-GCP-PROJECT>.svc.id.goog[<YOUR-K8S-NAMESPACE>/<YOUR-KSA-NAME>]" \
      <YOUR-GSA-NAME>@<YOUR-GCP-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-GCP-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

Como alternativa, se não for possível usar a Identidade da carga de trabalho, o padrão recomendado é ativar um arquivo de chave da conta de serviço no pod do proxy do Cloud SQL Auth e usar a sinalização -credential_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 do Cloud SQL Auth.

Como executar o proxy do Cloud SQL Auth como um arquivo secundário

Recomendamos a execução do proxy do Cloud SQL Auth em um padrão sidecar, que apresenta um contêiner adicional que compartilha um pod com seu 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 do Cloud SQL Auth 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 do Cloud SQL Auth, permitindo usar 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 do Cloud SQL Auth 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 Cloud SQL Proxy à configuração do pod em containers:

    - name: cloud-sql-proxy
      # It is recommended to use the latest version of the Cloud SQL proxy
      # Make sure to update on a regular schedule!
      image: gcr.io/cloudsql-docker/gce-proxy:1.17
      command:
        - "/cloud_sql_proxy"
    
        # If connecting from a VPC-native GKE cluster, you can use the
        # following flag to have the proxy connect over private IP
        # - "-ip_address_types=PRIVATE"
    
        # Replace DB_PORT with the port the proxy should listen on
        # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
        - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
      securityContext:
        # The default Cloud SQL proxy image runs as the
        # "nonroot" user and group (uid: 65532) by default.
        runAsNonRoot: true

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

      # This flag specifies where the service account key can be found
      - "-credential_file=/secrets/service_account.json"
    securityContext:
      # The default Cloud SQL 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 exemplo:

Proxy do Cloud SQL Auth com identidade de carga de trabalho

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 proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloudsql-docker/gce-proxy:1.17
        command:
          - "/cloud_sql_proxy"

          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "-ip_address_types=PRIVATE"

          # Replace DB_PORT with the port the proxy should listen on
          # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
        securityContext:
          # The default Cloud SQL proxy image runs as the
          # "nonroot" user and group (uid: 65532) by default.
          runAsNonRoot: true

Proxy do Cloud SQL Auth com chave de conta de serviço

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 proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloudsql-docker/gce-proxy:1.17
        command:
          - "/cloud_sql_proxy"

          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "-ip_address_types=PRIVATE"

          # Replace DB_PORT with the port the proxy should listen on
          # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"

          # This flag specifies where the service account key can be found
          - "-credential_file=/secrets/service_account.json"
        securityContext:
          # The default Cloud SQL 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
      volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>

Como se conectar sem o proxy do Cloud SQL Auth

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 privado sem o proxy do Cloud SQL Auth.

  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ê terá que usar a porta correta para o PostgreSQL: 5432

Conclua o arquivo de configuração de exemplo:

Sem proxy do Cloud SQL Auth - IP particular

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

Precisa de ajuda? Para receber ajuda na solução de problemas com o proxy, consulte Como solucionar problemas nas conexões do proxy do Cloud SQL Auth. ou veja a página de suporte do Cloud SQL.

A seguir