Desplegar PostgreSQL en GKE con Zalando

En esta guía se explica cómo usar el operador de Zalando Postgres para desplegar clústeres de Postgres en Google Kubernetes Engine (GKE).

PostgreSQL es un sistema de bases de datos relacionales de objetos de código abierto potente con varias décadas de desarrollo activo que le han valido una sólida reputación por su fiabilidad, la solidez de sus funciones y su rendimiento.

Esta guía está dirigida a administradores de plataformas, arquitectos de soluciones en la nube y profesionales de operaciones que quieran ejecutar PostgreSQL como aplicación de base de datos en GKE en lugar de usar Cloud SQL para PostgreSQL.

Objetivos

  • Planificar y desplegar la infraestructura de GKE para PostgreSQL
  • Implementar y configurar el operador de Zalando Postgres
  • Configurar PostgreSQL mediante el operador para asegurar la disponibilidad, la seguridad, la observabilidad y el rendimiento

Ventajas

Zalando ofrece las siguientes ventajas:

  • Una forma declarativa y nativa de Kubernetes de gestionar y configurar los clústeres de PostgreSQL
  • Alta disponibilidad proporcionada por Patroni
  • Compatibilidad con la gestión de copias de seguridad mediante segmentos de Cloud Storage
  • Actualizaciones continuas de los cambios en el clúster de Postgres, incluidas las actualizaciones rápidas de versiones secundarias
  • Declarativa Usuario gestión con generación y rotación de contraseñas mediante recursos personalizados
  • Compatibilidad con TLS, rotación de certificados y agrupaciones de conexiones
  • Clonación de clústeres y replicación de datos

Arquitectura de despliegue

En este tutorial, usarás el operador de Zalando Postgres para desplegar y configurar un clúster de Postgres de alta disponibilidad en GKE. El clúster tiene una réplica líder y dos réplicas de espera (de solo lectura) gestionadas por Patroni. Patroni es una solución de código abierto mantenida por Zalando para proporcionar alta disponibilidad y conmutación por error automática a PostgreSQL. En caso de que falle el líder, una réplica en espera se convierte automáticamente en líder.

También despliega un clúster de GKE regional de alta disponibilidad para Postgres, con varios nodos de Kubernetes distribuidos en varias zonas de disponibilidad. Esta configuración ayuda a garantizar la tolerancia a fallos, la escalabilidad y la redundancia geográfica. Permite realizar actualizaciones y tareas de mantenimiento continuas, al tiempo que ofrece acuerdos de nivel de servicio de tiempo de actividad y disponibilidad. Para obtener más información, consulta Clústeres regionales.

En el siguiente diagrama se muestra un clúster de PostgreSQL que se ejecuta en varios nodos y zonas de un clúster de GKE:

En el diagrama, Postgres StatefulSet se implementa en tres nodos de tres zonas diferentes. Puedes controlar cómo se implementa GKE en los nodos configurando las reglas de afinidad y antiafinidad de pods necesarias en la especificación de recursos personalizados postgresql. Si falla una zona, GKE reprograma los pods en otros nodos disponibles de tu clúster con la configuración recomendada. Para conservar los datos, se usan discos SSD (premium-rwo StorageClass), que son recomendables en la mayoría de los casos para bases de datos con mucha carga debido a su baja latencia y a su alto número de IOPS.

Costes

En este documento, se utilizan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

Los usuarios nuevos pueden disfrutar de una prueba gratuita. Google Cloud

Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que hayas creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

Cloud Shell tiene preinstalado el software que necesitas para este tutorial, como kubectl, la CLI de gcloud, Helm y Terraform. Si no usas Cloud Shell, debes instalar la CLI de gcloud.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine, IAM, GKE, Backup for GKE APIs:

    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.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Compute Engine, IAM, GKE, Backup for GKE APIs:

    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.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/storage.objectViewer, roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin, roles/gkebackup.admin, roles/monitoring.viewer

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example, myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.
  15. Configurar un entorno

    Para configurar tu entorno, sigue estos pasos

    1. Define las variables de entorno:

      export PROJECT_ID=PROJECT_ID
      export KUBERNETES_CLUSTER_PREFIX=postgres
      export REGION=us-central1
      

      Sustituye PROJECT_ID por el Google Cloud ID de tu proyecto.

    2. Clona el repositorio de GitHub:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
      
    3. Cambia al directorio de trabajo:

      cd kubernetes-engine-samples/databases/postgres-zalando
      

    Crear la infraestructura del clúster

    En esta sección, ejecutarás una secuencia de comandos de Terraform para crear un clúster de GKE privado, regional y de alta disponibilidad.

    Puedes instalar el operador con un clúster estándar o Autopilot.

    Estándar

    En el siguiente diagrama se muestra un clúster de GKE estándar regional privado desplegado en tres zonas diferentes:

    Implementa esta infraestructura:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform -chdir=terraform/gke-standard init
    terraform -chdir=terraform/gke-standard apply \
      -var project_id=${PROJECT_ID} \
      -var region=${REGION} \
      -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    Cuando se te solicite, escribe yes. Este comando puede tardar varios minutos en completarse y el clúster en mostrar el estado "Listo".

    Terraform crea los siguientes recursos:

    • Una red de VPC y una subred privada para los nodos de Kubernetes
    • Un router para acceder a Internet a través de NAT
    • Un clúster de GKE privado en la región us-central1
    • Un grupo de nodos con el autoescalado habilitado (de uno a dos nodos por zona, con un mínimo de un nodo por zona)
    • Un ServiceAccount con permisos de registro y monitorización
    • Copia de seguridad de GKE para la recuperación tras fallos
    • Google Cloud Managed Service para Prometheus para la monitorización de clústeres

    El resultado debería ser similar al siguiente:

    ...
    Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
    ...
    

    Autopilot

    En el siguiente diagrama se muestra un clúster de Autopilot de GKE regional privado:

    Despliega la infraestructura:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform -chdir=terraform/gke-autopilot init
    terraform -chdir=terraform/gke-autopilot apply \
      -var project_id=${PROJECT_ID} \
      -var region=${REGION} \
      -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    Cuando se te solicite, escribe yes. Este comando puede tardar varios minutos en completarse y el clúster en mostrar el estado "Listo".

    Terraform crea los siguientes recursos:

    • Una red de VPC y una subred privada para los nodos de Kubernetes
    • Un router para acceder a Internet a través de NAT
    • Un clúster de GKE privado en la región us-central1
    • Un ServiceAccount con permiso de registro y monitorización
    • Google Cloud Managed Service para Prometheus para la monitorización de clústeres

    El resultado debería ser similar al siguiente:

    ...
    Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
    ...
    

    Conéctate al clúster

    Configura kubectl para que se comunique con el clúster:

    gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${REGION}
    

    Desplegar el operador de Zalando en el clúster

    Despliega el operador de Zalando en tu clúster de Kubernetes mediante un gráfico de Helm.

    1. Añade el repositorio del gráfico de Helm del operador de Zalando:

      helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
      
    2. Crea un espacio de nombres para el operador de Zalando y el clúster de PostgreSQL:

      kubectl create ns postgres
      kubectl create ns zalando
      
    3. Despliega el operador de Zalando con la herramienta de línea de comandos Helm:

      helm install postgres-operator postgres-operator-charts/postgres-operator -n zalando \
          --set configKubernetes.enable_pod_antiaffinity=true \
          --set configKubernetes.pod_antiaffinity_preferred_during_scheduling=true \
          --set configKubernetes.pod_antiaffinity_topology_key="topology.kubernetes.io/zone" \
          --set configKubernetes.spilo_fsgroup="103"
      

      No puedes configurar los ajustes de podAntiAffinity directamente en el recurso personalizado que representa el clúster de Postgres. En su lugar, define podAntiAffinity ajustes globales para todos los clústeres de Postgres en la configuración del operador.

    4. Comprueba el estado de implementación del operador de Zalando con Helm:

      helm ls -n zalando
      

      El resultado debería ser similar al siguiente:

      NAME                 NAMESPACE    REVISION    UPDATED                                STATUS      CHART                       APP VERSION
      postgres-operator    zalando     1           2023-10-13 16:04:13.945614 +0200 CEST    deployed    postgres-operator-1.10.1    1.10.1
      

    Implementar Postgres

    La configuración básica de la instancia del clúster de Postgres incluye los siguientes componentes:

    • Tres réplicas de PostgreSQL: una principal y dos de reserva.
    • Asignación de recursos de CPU de una solicitud de CPU y dos límites de CPU, con 4 GB de solicitudes y límites de memoria.
    • Tolerancias, nodeAffinities y topologySpreadConstraints configuradas para cada carga de trabajo, lo que asegura una distribución adecuada entre los nodos de Kubernetes, utilizando sus respectivos grupos de nodos y diferentes zonas de disponibilidad.

    Esta configuración representa la configuración mínima necesaria para crear un clúster de Postgres listo para producción.

    El siguiente manifiesto describe un clúster de Postgres:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      dockerImage: ghcr.io/zalando/spilo-15:3.0-p1
      teamId: "my-team"
      numberOfInstances: 3
      users:
        mydatabaseowner:
        - superuser
        - createdb
        myuser: []
      databases:
        mydatabase: mydatabaseowner
      postgresql:
        version: "15"
        parameters:
          shared_buffers: "32MB"
          max_connections: "10"
          log_statement: "all"
          password_encryption: scram-sha-256
      volume:
        size: 5Gi
        storageClass: premium-rwo
      enableShmVolume: true
      podAnnotations:
        cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
      tolerations:
      - key: "app.stateful/component"
        operator: "Equal"
        value: "postgres-operator"
        effect: NoSchedule
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
            - key: "app.stateful/component"
              operator: In
              values:
              - "postgres-operator"
      resources:
        requests:
          cpu: "1"
          memory: 4Gi
        limits:
          cpu: "2"
          memory: 4Gi
      sidecars:
        - name: exporter
          image: quay.io/prometheuscommunity/postgres-exporter:v0.14.0
          args:
          - --collector.stat_statements
          ports:
          - name: exporter
            containerPort: 9187
            protocol: TCP
          resources:
            limits:
              cpu: 500m
              memory: 256M
            requests:
              cpu: 100m
              memory: 256M
          env:
          - name: "DATA_SOURCE_URI"
            value: "localhost/postgres?sslmode=require"
          - name: "DATA_SOURCE_USER"
            value: "$(POSTGRES_USER)"
          - name: "DATA_SOURCE_PASS"
            value: "$(POSTGRES_PASSWORD)"

    Este manifiesto tiene los siguientes campos:

    • spec.teamId: prefijo de los objetos del clúster que elijas
    • spec.numberOfInstances: número total de instancias de un clúster
    • spec.users: la lista de usuarios con privilegios
    • spec.databases: la lista de bases de datos en el formato dbname: ownername
    • spec.postgresql: parámetros de PostgreSQL
    • spec.volume: parámetros de Persistent Disk
    • spec.tolerations: la plantilla de tolerancias de pods que permite programar pods de clúster en nodos pool-postgres
    • spec.nodeAffinity: la plantilla de nodeAffinity Pod que indica a GKE que los pods del clúster prefieren programarse en nodos pool-postgres.
    • spec.resources: solicitudes y límites de los pods de clúster
    • spec.sidecars: una lista de contenedores sidecar que contiene postgres-exporter

    Para obtener más información, consulta la referencia del manifiesto de clúster en la documentación de PostgreSQL.

    Crear un clúster básico de Postgres

    1. Crea un clúster de Postgres con la configuración básica:

      kubectl apply -n postgres -f manifests/01-basic-cluster/my-cluster.yaml
      

      Este comando crea un recurso personalizado de PostgreSQL del operador de Zalando con lo siguiente:

      • Solicitudes y límites de CPU y memoria
      • Intolerancias y afinidades para distribuir las réplicas de Pod aprovisionadas en los nodos de GKE.
      • Una base de datos
      • Dos usuarios con permisos de propietario de la base de datos
      • Un usuario sin permisos
    2. Espera a que GKE inicie las cargas de trabajo necesarias:

      kubectl wait pods -l cluster-name=my-cluster  --for condition=Ready --timeout=300s -n postgres
      

      Este comando puede tardar unos minutos en completarse.

    3. Comprueba que GKE haya creado las cargas de trabajo de Postgres:

      kubectl get pod,svc,statefulset,deploy,pdb,secret -n postgres
      

      El resultado debería ser similar al siguiente:

      NAME                                    READY   STATUS  RESTARTS   AGE
      pod/my-cluster-0                        1/1     Running   0         6m41s
      pod/my-cluster-1                        1/1     Running   0         5m56s
      pod/my-cluster-2                        1/1     Running   0         5m16s
      pod/postgres-operator-db9667d4d-rgcs8   1/1     Running   0         12m
      
      NAME                        TYPE        CLUSTER-IP  EXTERNAL-IP   PORT(S)   AGE
      service/my-cluster          ClusterIP   10.52.12.109   <none>       5432/TCP   6m43s
      service/my-cluster-config   ClusterIP   None        <none>      <none>  5m55s
      service/my-cluster-repl     ClusterIP   10.52.6.152 <none>      5432/TCP   6m43s
      service/postgres-operator   ClusterIP   10.52.8.176 <none>      8080/TCP   12m
      
      NAME                        READY   AGE
      statefulset.apps/my-cluster   3/3   6m43s
      
      NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/postgres-operator   1/1     1           1           12m
      
      NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
      poddisruptionbudget.policy/postgres-my-cluster-pdb   1              N/A             0                   6m44s
      
      NAME                                                            TYPE                DATA   AGE
      secret/my-user.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m45s
      secret/postgres.my-cluster.credentials.postgresql.acid.zalan.do   Opaque            2   6m44s
      secret/sh.helm.release.v1.postgres-operator.v1                  helm.sh/release.v1   1      12m
      secret/standby.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
      secret/zalando.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
      

    El operador crea los siguientes recursos:

    • Un StatefulSet de Postgres, que controla tres réplicas de Pod para Postgres
    • Un PodDisruptionBudgets, que garantiza que haya al menos una réplica disponible
    • El servicio my-cluster, que solo se dirige a la réplica principal
    • El servicio my-cluster-repl, que expone el puerto de Postgres para las conexiones entrantes y para la replicación entre réplicas de Postgres
    • El servicio my-cluster-config sin encabezado para obtener la lista de réplicas de Pod de Postgres en ejecución
    • Secretos con credenciales de usuario para acceder a la base de datos y a la replicación entre nodos de PostgreSQL

    Autenticarse en PostgreSQL

    Puede crear usuarios de PostgreSQL y asignarles permisos de base de datos. Por ejemplo, el siguiente manifiesto describe un recurso personalizado que asigna usuarios y roles:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      users:
        mydatabaseowner:
        - superuser
        - createdb
        myuser: []
      databases:
        mydatabase: mydatabaseowner
    

    En este manifiesto:

    • El usuario mydatabaseowner tiene los roles SUPERUSER y CREATEDB, que le permiten tener derechos de administrador completos (es decir, gestionar la configuración de Postgres, crear nuevas bases de datos, tablas y usuarios). No debes compartir este usuario con los clientes. Por ejemplo, Cloud SQL no permite que los clientes tengan acceso a usuarios con el rol SUPERUSER.
    • El usuario myuser no tiene ningún rol asignado. De esta forma, se sigue la práctica recomendada de usar SUPERUSER para crear usuarios con los mínimos privilegios. mydatabaseowner concede derechos granulares a myuser. Para mantener la seguridad, solo debes compartir las credenciales myuser con las aplicaciones cliente.

    Almacenar contraseñas

    Debes usar el scram-sha-256 método recomendado para almacenar contraseñas. Por ejemplo, el siguiente manifiesto describe un recurso personalizado que especifica el cifrado scram-sha-256 mediante el campo postgresql.parameters.password_encryption:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      postgresql:
        parameters:
          password_encryption: scram-sha-256
    

    Rotar credenciales de usuario

    Puedes rotar las credenciales de usuario que se almacenan en secretos de Kubernetes con Zalando. Por ejemplo, el siguiente manifiesto describe un recurso personalizado que define la rotación de credenciales de usuario mediante el campo usersWithSecretRotation:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      usersWithSecretRotation:
      - myuser
      - myanotheruser
      - ...
    

    Ejemplo de autenticación: conectarse a Postgres

    En esta sección se muestra cómo desplegar un cliente de Postgres de ejemplo y conectarse a la base de datos con la contraseña de un secreto de Kubernetes.

    1. Ejecuta el pod del cliente para interactuar con tu clúster de Postgres:

      kubectl apply -n postgres -f manifests/02-auth/client-pod.yaml
      

      Las credenciales de los usuarios myuser y mydatabaseowner se toman de los secretos relacionados y se montan como variables de entorno en el pod.

    2. Conéctate al Pod cuando esté listo:

      kubectl wait pod postgres-client --for=condition=Ready --timeout=300s -n postgres
      kubectl exec -it postgres-client -n postgres -- /bin/bash
      
    3. Conéctate a Postgres e intenta crear una tabla con las myuser credenciales:

      PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);"
      

      El comando debería fallar y mostrar un error similar al siguiente:

      ERROR:  permission denied for schema public
      LINE 1: CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR...
      

      El comando falla porque, de forma predeterminada, los usuarios sin privilegios asignados solo pueden iniciar sesión en PostgreSQL y enumerar bases de datos.

    4. Crea una tabla con credenciales mydatabaseowner y concede todos los privilegios de la tabla a myuser:

      PGPASSWORD=$OWNERPASSWORD psql \
        -h my-cluster \
        -U $OWNERUSERNAME \
        -d mydatabase \
        -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);GRANT ALL ON test TO myuser;GRANT ALL ON SEQUENCE test_id_seq TO myuser;"
      

      El resultado debería ser similar al siguiente:

      CREATE TABLE
      GRANT
      GRANT
      
    5. Inserta datos aleatorios en la tabla con las credenciales de myuser:

      for i in {1..10}; do
        DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
        PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
      done
      

      El resultado debería ser similar al siguiente:

      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      
    6. Obtén los valores que has insertado:

      PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "SELECT * FROM test;"
      

      El resultado debería ser similar al siguiente:

      id |  randomdata
      ----+---------------
        1 | jup9HYsAjwtW4
        2 | 9rLAyBlcpLgNT
        3 | wcXSqxb5Yz75g
        4 | KoDRSrx3muD6T
        5 | b9atC7RPai7En
        6 | 20d7kC8E6Vt1V
        7 | GmgNxaWbkevGq
        8 | BkTwFWH6hWC7r
        9 | nkLXHclkaqkqy
       10 | HEebZ9Lp71Nm3
      (10 rows)
      
    7. Sal del shell del pod:

      exit
      

    Información sobre cómo recoge Prometheus las métricas de tu clúster de PostgreSQL

    En el siguiente diagrama se muestra cómo funciona la recogida de métricas de Prometheus:

    En el diagrama, un clúster privado de GKE contiene lo siguiente:

    • Un pod de Postgres que recoge métricas en la ruta / y el puerto 9187
    • Recogedores basados en Prometheus que procesan las métricas del pod de PostgreSQL
    • Un recurso PodMonitoring que envía métricas a Cloud Monitoring

    Google Cloud Managed Service para Prometheus admite la recogida de métricas en formato Prometheus. Cloud Monitoring usa un panel de control integrado para las métricas de PostgreSQL.

    Zalando expone las métricas de clúster en formato Prometheus mediante el componente postgres_exporter como contenedor sidecar.

    1. Crea el recurso PodMonitoring para recoger métricas por labelSelector:

      kubectl apply -n postgres -f manifests/03-prometheus-metrics/pod-monitoring.yaml
      
    2. En la Google Cloud consola, ve a la página Panel de control de clústeres de GKE.

      Ir al panel de control de clústeres de GKE

      El panel de control muestra una tasa de ingestión de métricas distinta de cero.

    3. En la Google Cloud consola, ve a la página Paneles de control.

      Ir a Paneles

    4. Abre el panel de control de resumen de PostgreSQL Prometheus. En el panel de control se muestra el número de filas obtenidas. El aprovisionamiento automático del panel de control puede tardar varios minutos.

    5. Conéctate al pod del cliente:

      kubectl exec -it postgres-client -n postgres -- /bin/bash
      
    6. Insertar datos aleatorios:

      for i in {1..100}; do
        DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
        PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
      done
      
    7. Actualiza la página. Los gráficos Filas y Bloques se actualizan para mostrar el estado real de la base de datos.

    8. Sal del shell del pod:

      exit
      

    Limpieza

    Eliminar el proyecto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Eliminar recursos concretos

    1. Define las variables de entorno.

      export PROJECT_ID=${PROJECT_ID}
      export KUBERNETES_CLUSTER_PREFIX=postgres
      export REGION=us-central1
      
    2. Ejecuta el comando terraform destroy:

      export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
      terraform  -chdir=terraform/FOLDER destroy \
        -var project_id=${PROJECT_ID} \
        -var region=${REGION} \
        -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
      

      Sustituye FOLDER por gke-autopilot o gke-standard.

      Cuando se te solicite, escribe yes.

    3. Para encontrar todos los discos sin vincular, haz lo siguiente:

      export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
      
    4. Elimina los discos:

      for i in $disk_list; do
        disk_name=$(echo $i| cut -d'|' -f1)
        disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||')
        echo "Deleting $disk_name"
        gcloud compute disks delete $disk_name --zone $disk_zone --quiet
      done
      
    5. Elimina el repositorio de GitHub:

      rm -r ~/kubernetes-engine-samples/
      

    Siguientes pasos