Crea una implementación de varios clústeres para Spanner Omni en Kubernetes

En este documento, se describe cómo configurar una implementación de Spanner Omni en varios clústeres de Kubernetes. Puedes implementar Spanner Omni con o sin encriptación TLS. Si usas la encriptación, Spanner Omni usa la seguridad de la capa de transporte (TLS) 1.3 para encriptar y autenticar la comunicación dentro de la implementación y con sus clientes.

Una implementación sin encriptación TLS tiene los siguientes riesgos de seguridad:

  • Cualquier persona puede acceder a la implementación si puede llegar a su dirección IP.
  • No hay encriptación de red entre el cliente y el servidor ni entre los pods.

Debido a estos riesgos, evita una implementación que no esté configurada con encriptación TLS para entornos de producción.

La versión preliminar de Spanner Omni no admite la encriptación TLS y deja de escribir datos 90 días después de crear una implementación. Para obtener acceso anticipado a la edición con funciones completas, comunícate con Google.

Antes de comenzar

Para prepararte para la implementación, cumple con estos requisitos:

  • Crea varios clústeres de Kubernetes en cada ubicación para tu implementación. Los clústeres pueden ser zonales si implementas en una sola zona de ese clúster. Spanner Omni admite la configuración de gráficos de Helm para entornos de Google Kubernetes Engine (GKE) y Amazon Elastic Kubernetes Service (Amazon EKS). Es posible que otros entornos requieran configuraciones personalizadas.

  • Obtén acceso a la imagen de contenedor alojada en Artifact Registry.

  • Instala y configura la kubectl herramienta de línea de comandos y Helm.

  • Si configuras el entorno de Kubernetes en máquinas de la plataforma de virtualización vSphere, inhabilita la virtualización del contador de marcas de tiempo (TSC) agregando monitor_control.virtual_rdtsc = FALSE al archivo de configuración .vmx de la máquina virtual. Esto ayuda a que TrueTime funcione correctamente.

  • Configura la red del clúster de Kubernetes para que los pods de un clúster puedan conectarse con los pods de otro clúster. De forma predeterminada, Spanner Omni usa los puertos TCP 15000 a 15025 para la comunicación interna. Para habilitar la comunicación entre los pods de estos clústeres, abre estos puertos para el tráfico.

  • Configura el DNS del clúster para resolver el nombre de host de un pod, como spanner-a-0.pod.spanner-ns-r1, en su dirección IP. Spanner Omni requiere la resolución de nombres de host para las conexiones TCP entre pods en diferentes clústeres.

Prepara la configuración del gráfico de Helm

Crea una configuración de Helm. Para obtener más información, consulta Crea una configuración de Helm.

La cantidad de servidores raíz por zona debe ser un número impar entre uno y nueve, inclusive, para garantizar el quórum para la coherencia. Si la cantidad de servidores es un número par, es posible que las implementaciones fallen. Cuando configures tus zonas, designa servidores como servidores raíz. Te recomendamos que uses uno para el desarrollo o las pruebas y tres para las zonas de producción de alta disponibilidad.

Como se trata de una implementación de varios clústeres, asegúrate de que el archivo YAML de configuración de Helm incluya lo siguiente:

# This is required for a multi-cluster deployment setup.

deployment:
  multiCluster: true

Ejemplo de configuración de gráfico de Helm para la implementación de varios clústeres

El siguiente es un ejemplo de un gráfico de Helm configurado para una implementación de varios clústeres de Spanner Omni. Esta configuración crea una implementación en tres Google Cloud regiones: us-west1, us-west2, y us-west3. La implementación se distribuye en cinco zonas, y cada zona representa una réplica. Las réplicas en us-west1 y us-west2 son de lectura y escritura, mientras que la réplica única en us-west3 es una réplica testigo.

# The platform of the deployment
global:
  platform: gke

# This is required for a multi-cluster deployment setup.
deployment:
  multiCluster: true

# Locations and zones where clusters are created for the deployment
locations:
  - name: us-west1
    namespace: spanner-ns-usw1
    zones:
      - name: "us-west1-a"
        shortName: "a"
      - name: "us-west1-b"
        shortName: "b"
  - name: us-west2
    namespace: spanner-ns-usw2
    zones:
      - name: "us-west2-a"
        shortName: "a"
      - name: "us-west2-b"
        shortName: "b"
  - name: us-west3
    namespace: spanner-ns-usw3
    zones:
      - name: "us-west3-a"
        shortName: "a"
        replicaType: WITNESS

# Remaining configuration like storage, resources, isn't included in this sample.

Configura kubectl para conectarte con varios clústeres

Antes de continuar, crea clústeres con contextos kubectl. Por ejemplo, en el archivo YAML de configuración de Helm, puedes nombrar los contextos según la ubicación, como ctx-usw1, ctx-usw2, y ctx-usw3.

Configura la encriptación TLS

Si configuras una implementación sin encriptación, ve a Instala un gráfico de Helm para cada clúster.

Para configurar la encriptación TLS en una implementación de varios clústeres, debes crear una autoridad certificadora (AC) y generar certificados para cada clúster. Para obtener más información, consulta Agrega encriptación TLS a tu implementación de Kubernetes.

Genera los certificados

Crea la AC y los certificados para el servidor y la API. Los certificados del servidor y de la API deben incluir los hosts de todos los clústeres.

Crea el certificado del servidor de Spanner Omni

Los servidores de Spanner Omni usan certificados de servidor para encriptar la comunicación entre servidores.

Para crear el certificado del servidor, ejecuta lo siguiente. Reemplaza SERVER_LIST por una lista separada por comas de los FQDN de los pods del servidor de Spanner Omni o usa comodines.

SERVER_NAMES=*.pod.spanner-ns-usw1,*.pod.spanner-ns-usw2,*.pod.spanner-ns-usw3
Spanner Omni CLI certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

Crea el certificado de la API

Los certificados de la API encriptan la comunicación de los sistemas que interactúan con la implementación.

Para crear el certificado de la API, ejecuta lo siguiente. Reemplaza OMNI_ENDPOINT por los extremos de servicio de cada clúster.

OMNI_ENDPOINT=spanner.spanner-ns-usw1,spanner.spanner-ns-usw2,spanner.spanner-ns-usw3
Spanner Omni CLI certificates create-server --filename-prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output-directory certs

Envía los certificados a cada clúster de Kubernetes

Para cada clúster, crea el espacio de nombres y un secreto genérico que contenga los certificados.

# Repeat for each context (for example, ctx-usw1, ctx-usw2, ctx-usw3)
# Replace NAMESPACE with the appropriate namespace for each region

kubectl create namespace <var>NAMESPACE</var> --context <var>CONTEXT</var>
kubectl create secret generic tls-certs \
  --from-file=ca.crt="certs/ca.crt" \
  --from-file=ca-api.crt="certs/ca-api.crt" \
  --from-file=server.crt="certs/server.crt" \
  --from-file=server.key="certs/server.key" \
  --from-file=api.crt="certs/api.crt" \
  --from-file=api.key="certs/api.key" \
  -n <var>NAMESPACE</var> \
  --context <var>CONTEXT</var>

Instala un gráfico de Helm para cada clúster

Crea una configuración de Helm. Para obtener más información, consulta Crea una configuración de Helm.

Para una implementación de varios clústeres, aplica la configuración del gráfico de Helm de tu archivo de configuración de Helm a cada clúster de Kubernetes. En cada comando, orienta una ubicación específica y su espacio de nombres para vincularlo a la implementación de Spanner Omni. Aplica la configuración a cada ubicación en el mismo orden en que aparece en tu archivo de configuración de Helm. Cuando aplicas la configuración a la ubicación final, el sistema crea un trabajo de bootstrap de implementación en ese clúster.

Antes de instalar Helm para cada clúster, crea el espacio de nombres de supervisión en el clúster en el que planeas alojar la pila de observabilidad:

kubectl create namespace monitoring --context ctx-usw1

Ejemplos de comandos de instalación de gráficos de Helm

Los siguientes comandos instalan un gráfico de Helm en los clústeres. En cada comando, PATH_TO_HELM_CONFIG_FILE es la ruta de acceso al archivo YAML de configuración del gráfico de Helm que creaste para tu implementación.

Instala un gráfico en us-west1 con la supervisión habilitada

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw1 \
  --set currentLocation=us-west1 \
  --set monitoring.enabled=true \
  --create-namespace \
  --kube-context ctx-usw1

Instala un gráfico en us-west2 sin supervisión

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw2 \
  --set currentLocation=us-west2 \
  --create-namespace \
  --kube-context ctx-usw2

Instala un gráfico en us-west3 sin supervisión

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 0.1.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw3 \
  --set currentLocation=us-west3 \
  --create-namespace \
  --kube-context ctx-usw3

Sigue el progreso de tu implementación

Después de aplicar la configuración del gráfico de Helm, se inicia un trabajo de bootstrap en cada clúster de Kubernetes. Después de que se inicie el trabajo de bootstrap en el último clúster, ejecuta el siguiente comando para seguir el proceso de implementación:

kubectl logs -n spanner-ns-usw3 -l app.kubernetes.io/component=bootstrap -f

Si los registros indican que la implementación no puede llegar a todos los servidores, asegúrate de que el servicio DNS de cada clúster esté configurado correctamente.

Configura el servicio DNS del clúster

Si usas un DNS externo con tu clúster de Kubernetes y este administra las entradas DNS para los servicios sin encabezado, puedes omitir este paso.

Spanner usa el nombre de host del pod para toda la comunicación interna. Configura el DNS para que los pods puedan resolver nombres de host incluso cuando se ejecutan en diferentes clústeres de Kubernetes. Para ello, expón el servicio kube-dns en cada clúster para que otros clústeres puedan comunicarse con él ejecutando la secuencia de comandos dns-setup.sh.

Esta secuencia de comandos implementa un servicio de balanceador de cargas en cada clúster para la aplicación kube-dns y actualiza la configuración de DNS para que apunte a los servicios del balanceador de cargas. Si bien dns-setup.sh configura kube-dns y CoreDNS en GKE y Amazon EKS, es posible que debas configurarlo para tu entorno.

Para configurar el servicio DNS del clúster, haz lo siguiente:

  1. Si aún no lo hiciste, descarga la secuencia de comandos dns-setup.sh del bucket de Cloud Storage spanner-omni.

    Ir al bucket de Spanner Omni

  2. Ejecuta la secuencia de comandos dns-setup.sh:

    dns-setup.sh -n CSV_NAME_SPACE_LIST CONTEXTS
    
    • Reemplaza CSV_NAME_SPACE_LIST por una lista separada por comas de tus espacios de nombres.

    • Reemplaza CONTEXTS por una lista de tus contextos.

    El siguiente es un ejemplo del uso de la secuencia de comandos dns-setup.sh:

    dns-setup.sh -n spanner-ns-usw1,spanner-ns-usw2,spanner-ns-usw3 ctx-usw1 ctx-usw2 ctx-usw3
    

Después de ejecutar la secuencia de comandos, verifica los registros del trabajo de implementación. Los mensajes indican que la implementación está en curso y aparece un mensaje Deployment created successfully.

Actualiza el certificado de la API

Si configuras la implementación sin encriptación TLS, continúa con Interactúa con Spanner Omni.

Para implementar la encriptación TLS, debes actualizar el certificado de la API con las direcciones IP externas o los nombres de DNS de los balanceadores de cargas para cada clúster. Esto garantiza que los clientes puedan conectarse a la implementación a través de canales seguros.

  1. Obtén los detalles del servicio para cada clúster:

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    kubectl get service spanner -n spanner-ns-usw2 --context ctx-usw2
    kubectl get service spanner -n spanner-ns-usw3 --context ctx-usw3
    
  2. Actualiza el certificado de la API con las direcciones IP externas:

    # Replace <var>EXTERNAL_IP_USW1</var>, <var>EXTERNAL_IP_USW2</var>, and <var>EXTERNAL_IP_USW3</var>
    # with the actual external IP addresses or DNS names.
    
    OMNI_ENDPOINT=<var>EXTERNAL_IP_USW1</var>,<var>EXTERNAL_IP_USW2</var>,<var>EXTERNAL_IP_USW3</var>,spanner.spanner-ns.svc
    Spanner Omni CLI certificates update --filename_prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output_directory certs --overwrite
    
  3. Actualiza los secretos en cada clúster de Kubernetes con el nuevo certificado de la API:

    # Repeat for each context
    kubectl patch secret tls-certs -n spanner-ns-usw1 --context ctx-usw1 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw2 --context ctx-usw2 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw3 --context ctx-usw3 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    

Interactúa con Spanner Omni

Cada clúster de una configuración de varios clústeres tiene un servicio de balanceador de cargas. Puedes usar cualquiera de las direcciones IP externas del servicio para interactuar con Spanner Omni. Para las escrituras y las lecturas sólidas, usa la dirección que actúa como la región líder. Para las solicitudes de lectura inactiva, usa la región más cercana a tu aplicación para lograr un rendimiento óptimo.

  1. Ejecuta el siguiente comando para obtener la dirección del servicio:

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    

    El EXTERNAL-IP:PORT es el DEPLOYMENT_ENDPOINT de tu implementación.

  2. Si aún no lo hiciste, descarga la CLI de Spanner Omni del bucket de Cloud Storage spanner-omni.

    Ir al bucket de Spanner Omni

  3. Si creaste una implementación con encriptación TLS, debes incluir el certificado de AC con cada comando para establecer una conexión encriptada. Si habilitaste mTLS para los clientes, también incluye el directorio de certificados de cliente.

    • --ca-certificate-file=certs/ca-api.crt
    • --client-certificate-directory=clientcerts
  4. Usa la CLI de Spanner Omni para crear una base de datos de GoogleSQL o PostgreSQL y para interactuar con ella.

    GoogleSQL

    Para crear una base de datos de GoogleSQL y para interactuar con ella, ejecuta lo siguiente:

    Spanner Omni CLI databases create DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    PostgreSQL

    Para crear una base de datos de PostgreSQL y para interactuar con ella, ejecuta lo siguiente:

    Spanner Omni CLI databases create POSTGRESQL_DATABASE_NAME \
      --database_dialect POSTGRESQL \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=POSTGRESQL_DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    También puedes interactuar con una base de datos de PostgreSQL siguiendo las instrucciones que se indican en Conéctate con PGAdapter para configurar PGAdapter y usar herramientas de PostgreSQL, como psql, con tus bases de datos de dialecto de PostgreSQL.

¿Qué sigue?