Conéctate 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 hasta una instancia de Cloud SQL.

Introducción

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

El proxy de Cloud SQL Auth es la forma recomendada para conectarse a Cloud SQL, incluso cuando se usa una IP privada. Esto se debe a que el proxy de Cloud SQL Auth proporciona una encriptación sólida y autenticación mediante IAM, lo que puede ayudar a mantener tu base de datos segura.

Las conexiones de bases de datos consumen recursos en el servidor y en la aplicación de conexión. Usa siempre prácticas adecuadas de administración de conexión para minimizar el espacio de tu aplicación y reducir la posibilidad de superar los límites de conexión de Cloud SQL. Para obtener más información, consulta la sección sobre cómo administrar conexiones de bases de datos.

Antes de comenzar

Para conectarte a Cloud SQL, se deben cumplir estos requisitos:

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

    Si quieres obtener ayuda para comenzar a usar GKE, consulta la guía de inicio rápido.

    Para conectarte mediante una IP privada, el clúster de GKE debe ser nativo de VPC y estar en la misma red de VPC que la instancia de Cloud SQL.

  • Debes tener una instancia.

    Si quieres obtener ayuda para crear una instancia de Cloud SQL, consulta Crea 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 Crea un usuario.

Información acerca de los objetos Secret

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

Existen muchas formas de usar los Secretos, según el tipo de conexión:

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

Para ver ejemplos completos sobre cómo usar Secretos, consulta los repositorios de GitHub que se mencionan abajo en esta página.

Crea un objeto Secret

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

    Para crear un Secreto de credenciales de una base de datos, ingresa el siguiente comando:

    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 que se crearon los objetos, puedes verlos en la sección Configuración de la página de Google Kubernetes Engine en Cloud Console.

Conexión con el proxy de autenticación de Cloud SQL

Cuando te conectas mediante el proxy de Cloud SQL Auth, el proxy de Cloud SQL Auth se agrega al pod mediante el patrón de contenedor de sidecar. El contenedor del proxy de Cloud SQL Auth está en el mismo pod que tu aplicación, lo que permite que la aplicación se conecte al proxy de Cloud SQL Auth mediante localhost, lo que aumenta la seguridad y el rendimiento. Más información

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

Para conectarte mediante el proxy de autenticación de Cloud SQL, se deben cumplir estos requisitos:

  1. Debes tener el nombre de la conexión de la instancia de Cloud SQL.

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

  2. La ubicación del archivo de claves asociada a una cuenta de servicio que tenga los privilegios adecuados para tu instancia de Cloud SQL.

    Para obtener más información, consulta la sección Crea una cuenta de servicio.

  3. La API de Administrador de Cloud SQL habilitada.

    Habilita la API

Proporciona la cuenta de servicio al proxy de Cloud SQL Auth

El primer paso para ejecutar el proxy de Cloud SQL Auth en Google Kubernetes Engine es crear una cuenta de servicio de Google (GSA) para representar tu aplicación. Se recomienda crear 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 con los siguientes criterios:

  • Pertenece a un proyecto que tenga habilitada la API de Administrador de Cloud SQL.
  • Se le otorgó la función de IAM de cliente de Cloud SQL (o equivalente) para el proyecto que contiene la instancia a la que deseas conectarte.
  • Si te conectas con una IP privada, debes usar un clúster de GKE nativo de la VPC, en la misma VPC que tu instancia de Cloud SQL.

Debes configurar GKE para proporcionar la cuenta de servicio al proxy de Cloud SQL Auth. Hay dos maneras recomendadas de hacerlo: identidad de carga de trabajo o archivo de claves 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). Luego, las aplicaciones que usen la KSA coincidente podrán acceder a la GSA.

Una cuenta de servicio de Google (GSA) es una identidad de IAM que representa a la aplicación en Google Cloud. De manera similar, una cuenta de servicio de Kubernetes (KSA) es una identidad que representa a la aplicación en un clúster de Google Kubernetes Engine.

Workload Identity vincula una KSA a una GSA, lo que hace que las implementaciones con esa KSA se autentiquen como la GSA en sus interacciones con Google Cloud.

  1. Habilita Workload Identity para el clúster
  2. Por lo general, cada aplicación tiene su propia identidad, representada por un par de KSA y GSA. Crea una KSA para la aplicación mediante el comando kubectl apply -f service-account.yaml:

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

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

Como alternativa, si no puedes usar Workload Identity, el patrón recomendado es activar un archivo de claves de cuenta de servicio en el pod del proxy de Cloud SQL Auth y usar la marca -credential_file.

  1. Crea un archivo de credenciales para la clave de la 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 la cuenta de servicio en un secreto de k8s:

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
    
  3. Activa el Secreto como un volumen en spec: para el objeto de k8s:

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

Ejecuta el proxy de Cloud SQL Auth como archivo adicional

Recomendamos ejecutar el proxy de autenticación de Cloud SQL en un patrón de sidecar (como un contenedor adicional que comparte un pod con tu aplicación). Se recomienda este método en lugar de ejecutarlo como un servicio independiente por varias razones, que se detallan a continuación:

  • Evita que el tráfico de SQL se exponga de manera local; el proxy de Cloud SQL Auth proporciona encriptación en conexiones salientes, pero necesitas limitar la exposición para las conexiones entrantes
  • Se evita un punto único de fallo. El acceso de cada aplicación a la base de datos es independiente de las demás, por lo que es más resistente.
  • Limita el acceso al proxy de Cloud SQL Auth, lo que te permite usar permisos de IAM por aplicación, en lugar de exponer la base de datos a todo el clúster.
  • Te permite definir el alcance de las solicitudes de recursos con mayor precisión. Debido a que el proxy de Cloud SQL Auth consume recursos de forma lineal según el uso, este patrón te permite definir el alcance y solicitar recursos con mayor precisión para que se ajusten a las aplicaciones a medida que se realiza el escalamiento.

  • Agrega el proxy de Cloud SQL Auth a la configuración del pod en 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
      # 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"

    Si usas una clave de cuenta de servicio, especifica el volumen del Secreto y agrega la marca -credential_file al 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 último, configura la 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 muestra completos:

Workload Identity

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
        # 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"

Clave de cuenta de servicio

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
        # 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>

Conéctate 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 la VPC a una instancia de Cloud SQL en la misma VPC mediante la IP privada sin el proxy de Cloud SQL Auth.

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

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. A continuación, asegúrate de agregar el Secreto al contenedor de la aplicación:

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

Archivo de configuración de muestra completo:

IP privada

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

¿Necesitas ayuda? Para solucionar problemas del proxy, consulta Solución de problemas de conexión del proxy de autenticación de Cloud SQL o nuestra página Asistencia de Cloud SQL.

¿Qué sigue?