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 (con IP pública o privada) o conectarte directamente mediante una dirección IP privada.

Se recomienda optar por el proxy de Cloud SQL para conectar a Cloud SQL, incluso cuando se usa una IP privada. Esto se debe a que el proxy proporciona encriptación y autenticación sólidas mediante IAM, lo que puede ayudar a mantener la 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 conectarse 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, se puede usar un Secreto para guardar el archivo de credenciales de la 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 Cloud SQL

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

Para obtener más información sobre el proxy de Cloud SQL, consulta Acerca del proxy 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 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.

  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

El primer paso para ejecutar el proxy de Cloud SQL en Google Kubernetes Engine es crear una cuenta de servicio 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. 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 la cuenta de servicio en el pod del proxy de Cloud SQL 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 de la siguiente sección para acceder al volumen desde el Pod del proxy.

Ejecuta el proxy como un sidecar

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

  • Se evita que el tráfico de SQL se exponga de forma local. El proxy 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 los demás accesos, por lo que es más resistente.
  • Se limita el acceso al proxy, 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 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.
  1. Agrega el proxy de Cloud SQL 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

    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
  2. 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 ejemplo completos:

Proxy con 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

Proxy con clave de la 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
      volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>

Conéctate sin el proxy de Cloud SQL

Si bien este método 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.

  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 ejemplo completo:

Sin proxy, 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 Cómo solucionar problemas de conexión del proxy de Cloud SQL. También puedes consultar nuestra página de asistencia de Cloud SQL.

Pasos siguientes