Conectarse desde Google Kubernetes Engine

En esta página se describe cómo configurar una conexión desde una aplicación que se ejecuta en Google Kubernetes Engine (GKE) a una instancia de Cloud SQL.

Para obtener instrucciones detalladas sobre cómo ejecutar una aplicación web de ejemplo de Google Kubernetes Engine conectada a Cloud SQL, consulta la guía de inicio rápido para conectarse desde Google Kubernetes Engine.

Cloud SQL es un servicio de base de datos totalmente gestionado que te permite configurar, mantener, gestionar y administrar tus bases de datos relacionales en la nube.

Google Kubernetes Engine es una manera sencilla de desplegar, escalar y gestionar Kubernetes automáticamente.

Información sobre la conexión de Google Kubernetes Engine a Cloud SQL

Para acceder a una instancia de Cloud SQL desde una aplicación que se ejecuta en Google Kubernetes Engine, puedes usar el proxy de autenticación de Cloud SQL (con IP pública o privada) o conectarte directamente mediante una dirección IP privada.

El proxy de autenticación de Cloud SQL es la forma recomendada de conectarse a Cloud SQL, incluso cuando se usa una IP privada. Esto se debe a que el proxy de autenticación de Cloud SQL proporciona un cifrado y una autenticación sólidos mediante Gestión de Identidades y Accesos, lo que puede ayudar a proteger tu base de datos.

Las conexiones de bases de datos consumen recursos en el servidor y en la aplicación que se conecta. Aplica siempre buenas prácticas de gestión de conexiones para minimizar la huella de tu aplicación y reducir la probabilidad de superar los límites de conexión de Cloud SQL. Para obtener más información, consulta Gestionar conexiones de bases de datos.

Antes de empezar

Para conectarte a Cloud SQL, debes tener lo siguiente:

  • Un clúster de GKE con la herramienta de línea de comandos kubectl instalada y configurada para comunicarse con el clúster.

    Para obtener ayuda sobre cómo empezar a usar GKE, consulta el artículo Desplegar una aplicación en un clúster de GKE.

    Para conectarse mediante una IP privada, el clúster de GKE debe ser nativo de VPC y estar emparejado con la misma red de nube privada virtual (VPC) que la instancia de Cloud SQL.

  • Se ha creado una instancia.

    Si quieres obtener ayuda para crear una instancia de Cloud SQL, consulta la sección sobre cómo crear instancias.

  • Una cuenta de usuario de PostgreSQL configurada en la instancia.

    Tu aplicación usará esta cuenta para conectarse a la base de datos. Si quieres obtener ayuda para crear una cuenta de usuario, consulta la sección sobre cómo crear un usuario.

Información sobre los secretos de Kubernetes

En Kubernetes, los secretos son una forma segura de transferir detalles de configuración a tu aplicación. Puedes crear un secreto con detalles como el nombre de tu base de datos, el usuario y la contraseña, que se pueden insertar en tu aplicación como variables de entorno.

Hay muchas formas diferentes de usar Secretos, según el tipo de conexión:

  • Un secreto de credenciales de base de datos incluye el nombre del usuario de la base de datos con el que te conectas y la contraseña de la base de datos del usuario.
  • Si te conectas con el proxy de autenticación de Cloud SQL, puedes usar un secreto para almacenar el archivo de credenciales de tu cuenta de servicio.
  • Si te conectas con una IP privada, puedes usar un secreto para especificar la dirección IP privada de tu instancia de Cloud SQL.

Para ver ejemplos completos de cómo usar Secrets, consulta los repositorios de GitHub que se mencionan más adelante en esta página.

Crear un objeto Secret

  1. Para crear los objetos Secret, usa el comando kubectl create secret.

    Para crear un secreto de credenciales de base de datos, sigue estos pasos:

    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. Una vez creados, puedes ver los objetos en la sección Configuración de la página de Google Kubernetes Engine en la Google Cloud consola.

Conectarse a Cloud SQL mediante el proxy de autenticación de Cloud SQL

Cuando te conectas mediante el proxy de autenticación de Cloud SQL, este se añade a tu pod mediante el patrón de contenedor sidecar. El contenedor del proxy de autenticación de Cloud SQL está en el mismo pod que tu aplicación, lo que permite que la aplicación se conecte al proxy de autenticación de Cloud SQL mediante localhost, lo que aumenta la seguridad y el rendimiento.

Para obtener más información sobre el proxy de autenticación de Cloud SQL, consulta Información sobre el proxy de autenticación de Cloud SQL. Para obtener más información sobre cómo trabajar con pods, consulta Descripción general de los pods en la documentación de Kubernetes.

Para conectarse mediante el proxy de autenticación de Cloud SQL, necesita lo siguiente:

  1. El nombre de conexión de la instancia de Cloud SQL.

    El nombre de conexión de la instancia está disponible en la página Detalles de la instancia de Cloud SQL de la consola de Google Cloud Google Cloud o con el comando gcloud sql instances describe INSTANCE_ID.

  2. Ubicación del archivo de claves asociado a una cuenta de servicio con los privilegios adecuados para tu instancia de Cloud SQL.

    Consulta más información en el artículo Crear una cuenta de servicio.

  3. La API Admin de Cloud SQL está habilitada.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

Proporcionar la cuenta de servicio al proxy de autenticación de Cloud SQL

El primer paso para ejecutar Cloud SQL Auth Proxy en Google Kubernetes Engine es crear una cuenta de servicio de Google (GSA) que represente a tu aplicación. Te recomendamos que crees una cuenta de servicio única para cada aplicación, en lugar de usar la misma cuenta de servicio en todas partes. Este modelo es más seguro, ya que te permite limitar los permisos por aplicación.

La cuenta de servicio de tu aplicación debe cumplir los siguientes criterios:

  • Pertenecer a un proyecto con la API Admin de Cloud SQL habilitada
  • Se le ha concedido el rol de IAM Cliente de Cloud SQL (o un rol equivalente) en el proyecto que contiene la instancia a la que quieres conectarte.
  • Si te conectas mediante una IP privada, debes usar un clúster de GKE nativo de VPC en la misma VPC que tu instancia de Cloud SQL.

Debes configurar GKE para que proporcione la cuenta de servicio al proxy de autenticación de Cloud SQL. Hay dos formas recomendadas de hacerlo: identidad de carga de trabajo o un archivo de clave de cuenta de servicio.

Workload Identity

Si usas Google Kubernetes Engine, el método preferido es usar la función Workload Identity de GKE. Este método te permite vincular una cuenta de servicio de Kubernetes (KSA) a una cuenta de servicio de Google (GSA). La GSA será accesible para las aplicaciones que usen la KSA correspondiente.

Una cuenta de servicio de Google (GSA) es una identidad de gestión de identidades y accesos que representa tu aplicación en Google Cloud. Del mismo modo, una cuenta de servicio de Kubernetes (KSA) es una identidad que representa tu aplicación en un clúster de Google Kubernetes Engine.

Workload Identity vincula una KSA a una GSA, lo que provoca que cualquier implementación con esa KSA se autentique como la GSA en sus interacciones con Google Cloud.

  1. Habilita Workload Identity en el clúster
  2. Normalmente, cada aplicación tiene su propia identidad, representada por un par KSA y GSA. Crea una KSA para tu aplicación ejecutando kubectl apply -f service-account.yaml:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: <YOUR-KSA-NAME> # TODO(developer): replace these values
  3. Habilita el enlace de IAM entre tu YOUR-GSA-NAME y 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. Añade una anotación a YOUR-KSA-NAME para completar el enlace:

    kubectl annotate serviceaccount \
    YOUR-KSA-NAME \
    iam.gke.io/gcp-service-account=YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
  5. Por último, asegúrate de especificar la cuenta de servicio del 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>

Archivo de clave de cuenta de servicio

Si no puedes usar Workload Identity, el patrón recomendado es montar un archivo de claves de cuenta de servicio en el pod del proxy de autenticación de Cloud SQL y usar la marca --credentials-file.

  1. Crea un archivo de credenciales para la clave de tu cuenta de servicio:

    gcloud iam service-accounts keys create ~/key.json \
    --iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com
  2. Convierte la clave de tu cuenta de servicio en un secreto de k8s:

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
  3. Monta el secreto como un volumen en spec: de tu objeto de Kubernetes:

    volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>
  4. Sigue las instrucciones de la sección siguiente para acceder al volumen desde el pod del proxy de autenticación de Cloud SQL.

Ejecutar el proxy de autenticación de Cloud SQL con un patrón sidecar

Te recomendamos que ejecutes el proxy de autenticación de Cloud SQL con un patrón sidecar (como un contenedor adicional que comparte un pod con tu aplicación). Te recomendamos esta opción en lugar de ejecutarlo como un servicio independiente por varios motivos:

  • Evita que tu tráfico SQL se exponga de forma local. El proxy de autenticación de Cloud SQL proporciona cifrado en las conexiones salientes, pero debes limitar la exposición de las conexiones entrantes.
  • Evita que haya un único punto de fallo: el acceso de cada aplicación a tu base de datos es independiente del de las demás, lo que la hace más resistente.
  • Limita el acceso al proxy de autenticación de Cloud SQL, lo que te permite usar permisos de gestión de identidades y accesos por aplicación en lugar de exponer la base de datos a todo el clúster.
  • Te permite acotar las solicitudes de recursos con mayor precisión, ya que el proxy de autenticación de Cloud SQL consume recursos de forma lineal en función del uso. Este patrón te permite acotar y solicitar recursos con mayor precisión para que se ajusten a tus aplicaciones a medida que se escalan.

  • Añade el proxy de autenticación de Cloud SQL a la configuración del pod en initContainers:

    initContainers:
      - name: cloud-sql-proxy
        restartPolicy: Always
        # 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"

    Si utilizas una clave de cuenta de servicio, especifica tu volumen secreto y añade la marca --credentials-file al 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 último, configura tu aplicación para que se conecte mediante 127.0.0.1 en el DB_PORT que hayas especificado en la sección de comandos.

Archivos de configuración de ejemplo completos:

Workload Identity

# 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
      initContainers:
        - name: cloud-sql-proxy
          restartPolicy: Always
          # 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"

Clave de cuenta de servicio

# 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
      initContainers:
        - name: cloud-sql-proxy
          restartPolicy: Always
          # 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>

Conectarse a Cloud SQL sin el proxy de autenticación de Cloud SQL

Aunque no es tan seguro, es posible conectarse desde un clúster de GKE nativo de VPC a una instancia de Cloud SQL en la misma VPC mediante una IP privada sin el proxy de autenticación de Cloud SQL.

  1. Crea un secreto con la dirección IP privada de tu instancia:

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. A continuación, añade el secreto al contenedor de tu aplicación:

    - name: DB_HOST
      valueFrom:
        secretKeyRef:
          name: <YOUR-PRIVATE-IP-SECRET>
          key: db_host
  3. Por último, configura tu aplicación para que se conecte mediante la dirección IP de la variable de entorno DB_HOST. Tendrás que usar el puerto correcto para PostgreSQL: 5432.

Archivo de configuración de ejemplo completo:

IP privada

# 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

Solución de problemas

¿Necesitas ayuda? Para obtener ayuda para solucionar problemas con el proxy, consulta el artículo Solucionar problemas de conexiones del proxy de autenticación de Cloud SQL o visita nuestra página de asistencia de Cloud SQL.

Siguientes pasos