Inicia PGAdapter

En esta página, se explica cómo iniciar PGAdapter en Spanner. Para obtener más información sobre PGAdapter, consulta Acerca de PGAdapter. Para obtener el objeto binario PGAdapter, consulta Cómo obtener PGAdapter.

Puedes iniciar PGAdapter de las siguientes maneras:

  • Como un proceso independiente
  • En un contenedor de Docker
  • En Cloud Run
  • Usar PGAdapter como proxy de sidecar (por ejemplo, en un clúster de Kubernetes)
  • En proceso con tu aplicación de Java

Antes de comenzar

Antes de iniciar PGAdapter, asegúrate de haberte autenticado con una cuenta de usuario o de servicio en la máquina en la que se ejecutará PGAdapter. Si usas una cuenta de servicio, debes conocer la ubicación del archivo de claves JSON (el archivo de credenciales). Luego, puedes especificar la ruta de acceso de las credenciales con la opción -c de PGAdapter o configurar la variable de entorno GOOGLE_APPLICATION_CREDENTIALS.

Para obtener más información, consulta:

Elige un método para ejecutar PGAdapter

Puedes iniciar PGAdapter como un proceso independiente, dentro de un contenedor de Docker, en Cloud Run o en proceso con tu aplicación de Java. Cuando inicias PGAdapter, debes especificar el proyecto, la instancia de Spanner y la base de datos a los que te conectarás. También puedes especificar la ruta de acceso para un archivo de credenciales con formato JSON (archivo de claves).

Independiente

Descarga PGAdapter con el siguiente comando.

wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
  && tar -xzvf pgadapter.tar.gz

Inicia PGAdapter con el siguiente comando.

java -jar pgadapter.jar -p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME \
  -c CREDENTIALS_FILE_PATH \
  ADDITIONAL_OPTIONS

Se requieren las siguientes opciones:

-p project_name
Nombre del proyecto en el que se ejecuta la base de datos de Spanner.
-i instance_name
Nombre de la instancia de Spanner.
-d database_name
Nombre de la base de datos a la que te conectarás.

Las siguientes configuraciones son opcionales:

-r databaseRole=database_role
Es un rol de base de datos para usar en la sesión. Para obtener más información, consulta Autorización con PGAdapter.
-c credentials_file_path
Ruta completa para el archivo de claves que contiene las credenciales de la cuenta de servicio en formato JSON. Si no se configura esta opción, las credenciales se leen desde la ruta de acceso especificada por la variable de entorno GOOGLE_APPLICATION_CREDENTIALS.

Para aprender a crear una cuenta de servicio y descargar un archivo de claves con formato JSON, consulta Crea una cuenta de servicio.

Asegúrate de otorgar a la cuenta de servicio las credenciales suficientes para acceder a la base de datos.

Puedes omitir esta opción si primero te autenticas con Google Cloud CLI con el siguiente comando:

gcloud auth application-default login

Para obtener más información, consulta Configura la autenticación y la autorización.

-s port
Puerto en el que PGAdapter escucha. El valor predeterminado es 5432 (el puerto predeterminado de PostgreSQL).
-v version_number

Número de versión de PostgreSQL para exponer al cliente durante la conexión. El valor predeterminado es 14.1.

Algunos controladores y aplicaciones de PostgreSQL habilitan funciones adicionales según este número de versión. Es posible que Spanner no admita estas funciones. Consulta Controladores y clientes para obtener una lista completa de los clientes compatibles.

-x

Habilita las conexiones desde hosts que no sean localhost. No lo uses cuando inicies PGAdapter en modo independiente. Usalo solo cuando inicies dentro de un contenedor Docker.

De forma predeterminada, como medida de seguridad, PGAdapter solo acepta conexiones de localhost.

En el siguiente ejemplo simple, se inicia PGAdapter en modo independiente en el puerto 5432 con las credenciales predeterminadas de la aplicación.

java -jar pgadapter.jar \
  -p my-project \
  -i my-instance \
  -d my-database \
  -s 5432
            

Docker

Inicia PGAdapter con el siguiente comando.

docker run -d -p HOST-PORT:DOCKER-PORT \
    -v CREDENTIALS_FILE_PATH:/acct_credentials.json \
    gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
    -p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME  \
    -c /acct_credentials.json -x OTHER_PGAdapter_OPTIONS

Además de las opciones de PGAdapter para especificar el proyecto, la instancia, la base de datos y las credenciales, se requieren las siguientes opciones:

-p 127.0.0.1:HOST-PORT:DOCKER-PORT

Con esta opción de Docker, se asigna el puerto DOCKER-PORT dentro del contenedor de Docker al puerto HOST-PORT fuera del contenedor. DOCKER-PORT debe coincidir con la forma en que se configura PGAdapter dentro del contenedor. El valor predeterminado es 5432. HOST-PORT es el puerto que Docker debe escuchar fuera del contenedor para las solicitudes de conexión. Siempre debe ser un puerto disponible en localhost.

Para obtener más información, consulta Puerto de publicación o exposición (-p, --exposición) en la documentación de Docker.

-v CREDENTIALS_FILE_PATH:in_container_mount_point

Esta opción de Docker activa un volumen compartido. Asigna la ruta de acceso del host fuera del contenedor a un volumen (punto de activación) dentro del contenedor. Las rutas de acceso de host y de contenedor están separadas por dos puntos (:).

Esta opción permite que PGAdapter acceda al archivo de credenciales JSON que está fuera del contenedor. En el ejemplo anterior, la opción -c hace referencia al punto de activación dentro del contenedor. En este ejemplo, se asigna al nombre el punto de activación /acct_credentials.json en el contenedor. Puedes nombrarlo como desees.

Para obtener más información, consulta VOLUMEN (sistemas de archivos compartidos) VOLUMEN (sistemas de archivos compartidos) en la documentación de Docker.

-x

Habilita las conexiones desde hosts que no sean localhost. Esto es necesario porque el puerto interno del contenedor asignado al puerto del host no parece PGAdapter como localhost.

Las siguientes configuraciones son opcionales:

-r databaseRole=database_role
Es un rol de base de datos para usar en la sesión. Para obtener más información, consulta Autorización con PGAdapter.

En el siguiente ejemplo, el puerto de Docker y el puerto de host están configurados en el puerto 5432 predeterminado del servicio de base de datos de PostgreSQL.

docker run -d -p 127.0.0.1:5432:5432 \
    -v /tmp/credentials.json:/acct_credentials.json \
    gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
    -p my_project -i my_instance -d my_database \
    -c /acct_credentials.json -x

Cloud Run

No puedes implementar PGAdapter como un servicio independiente en Cloud Run, pero puedes implementarlo como un proxy de sidecar.

Se recomienda ejecutar PGAdapter en un patrón de archivo adicional en lugar de ejecutarlo como un servicio independiente por los siguientes motivos:
  • Evita un punto único de fallo. El acceso de cada aplicación a tu base de datos es independiente de las demás, lo que las hace más resilientes.
  • La cantidad de instancias de PGAdapter se escala automáticamente de forma lineal con la cantidad de instancias de la aplicación.

El repositorio de PGAdapter de GitHub contiene varias aplicaciones de muestra en funcionamiento que usan Cloud Run y PGAdapter como proxy de archivo adicional para varios lenguajes de programación.

En el siguiente archivo de configuración, se muestra cómo agregar PGAdapter como proxy de sidecar a Cloud Run:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
    # This example uses an in-memory volume for Unix domain sockets.
    # This is a Cloud Run beta feature.
    run.googleapis.com/launch-stage: BETA
  name: pgadapter-sidecar-example
spec:
  template:
    metadata:
      annotations:
        run.googleapis.com/execution-environment: gen1
        # This registers 'pgadapter' as a dependency of 'app' and ensures that pgadapter starts
        # before the app container.
        run.googleapis.com/container-dependencies: '{"app":["pgadapter"]}'
    spec:
      # Create an in-memory volume that can be used for Unix domain sockets.
      volumes:
        - name: sockets-dir
          emptyDir:
            # This directory contains the virtual socket files that are used to
            # communicate between your application and PGAdapter.
            sizeLimit: 50Mi
            medium: Memory
      containers:
        # This is the main application container.
        - name: app
          # Example: europe-north1-docker.pkg.dev/my-test-project/cloud-run-source-deploy/pgadapter-sidecar-example
          image: MY-REGION.pkg.dev/MY-PROJECT/cloud-run-source-deploy/pgadapter-sidecar-example
          # The PGADAPTER_HOST variable is set to point to /sockets, which is the shared in-memory
          # volume that is used for Unix domain sockets.
          env:
            - name: SPANNER_PROJECT
              value: my-project
            - name: SPANNER_INSTANCE
              value: my-instance
            - name: SPANNER_DATABASE
              value: my-database
            - name: PGADAPTER_HOST
              value: /sockets
            - name: PGADAPTER_PORT
              value: "5432"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
        # This is the PGAdapter sidecar container.
        - name: pgadapter
          image: gcr.io/cloud-spanner-pg-adapter/pgadapter
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
          args:
            - -dir /sockets
            - -x
          # Add a startup probe that checks that PGAdapter is listening on port 5432.
          startupProbe:
            initialDelaySeconds: 10
            timeoutSeconds: 10
            periodSeconds: 10
            failureThreshold: 3
            tcpSocket:
              port: 5432
          

Proxy de sidecar

Puedes usar PGAdapter como proxy de sidecar, por ejemplo, en un clúster de Kubernetes. Los contenedores de archivos adicionales de Kubernetes se ejecutan en paralelo con el contenedor principal del Pod.

Se recomienda ejecutar PGAdapter en un patrón de archivo adicional en lugar de ejecutarlo como un servicio independiente por los siguientes motivos:

  • Evita un punto único de fallo. El acceso de cada aplicación a tu base de datos es independiente de las demás, lo que las hace más resilientes.
  • Debido a que PGAdapter consume recursos de forma lineal con el uso, este patrón te permite definir el alcance y solicitar recursos con mayor precisión para que coincidan con tus aplicaciones a medida que se escalan.

En el siguiente archivo de configuración, se muestra cómo agregar PGAdapter como proxy de sidecar a tu clúster de Kubernetes:

containers:
- name: pgadapter
  image: gcr.io/cloud-spanner-pg-adapter/pgadapter
  ports:
    - containerPort: 5432
  args:
    - "-p my-project"
    - "-i my-instance"
    - "-d my-database"
    - "-x"
  resources:
    requests:
      # PGAdapter'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: "512Mi"
      # PGAdapter'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"

El repositorio de GitHub de PGAdapter contiene una guía paso a paso y una aplicación de ejemplo. En esta muestra, se incluyen instrucciones para usar Workload Identity con PGAdapter.

Java en proceso

Crea e inicia una instancia de PGAdapter con tu código de Java. Esta es la configuración recomendada para las aplicaciones de Java.

Si usas una cuenta de servicio para la autenticación, asegúrate de que la variable de entorno GOOGLE_APPLICATION_CREDENTIALS esté configurada para la ruta del archivo de credenciales.

  1. Agrega google-cloud-spanner-pgadapter como dependencia a tu proyecto. Para obtener más información, consulta Cómo obtener PGAdapter.
  2. <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-spanner-pgadapter</artifactId>
      <version>0.32.0</version>
    </dependency>
  3. Compila un servidor con la clase com.google.cloud.spanner.pgadapter.ProxyServer.
  4. /**
      * Starts PGAdapter in-process and returns a reference to the server. Use this reference to
      * gracefully shut down the server when your application shuts down.
      *
      * @param project the Google Cloud project that PGAdapter should connect to
      * @param instance the Spanner instance that PGAdapter should connect to
      * @param credentialsFile the full path of a credentials file that PGAdapter should use, or 
      *     null if PGAdapter should use the application default credentials
      */
    static Server startPGAdapter(String project, String instance, String credentialsFile) {
      OptionsMetadata.Builder builder =
          OptionsMetadata.newBuilder()
              .setProject(project)
              .setInstance(instance)
              // Start PGAdapter on any available port.
              .setPort(0);
      if (credentialsFile != null) {
        builder.setCredentialsFile(credentialsFile);
      }
      ProxyServer server = new ProxyServer(builder.build());
      server.startServer();
      server.awaitRunning();
    
      return new PGAdapter(server);
    }
                  

El repositorio de PGAdapter de GitHub contiene una aplicación de ejemplo completa.

¿Qué sigue?