Criar uma implantação de vários clusters para o Spanner Omni no Kubernetes

Neste documento, descrevemos como configurar uma implantação do Spanner Omni em vários clusters do Kubernetes. É possível implantar o Spanner Omni com ou sem criptografia TLS. Se você usar criptografia, o Spanner Omni usará o Transport Layer Security (TLS) 1.3 para criptografar e autenticar a comunicação na implantação e com os clientes dela.

Uma implantação sem criptografia TLS tem os seguintes riscos de segurança:

  • Qualquer pessoa pode acessar a implantação se conseguir alcançar o endereço IP dela.
  • Não há criptografia de rede entre o cliente e o servidor ou entre os pods.

Por causa desses riscos, evite uma implantação que não esteja configurada com criptografia TLS para ambientes de produção.

Antes de começar

Para se preparar para a implantação, atenda a estes requisitos:

  • Crie vários clusters do Kubernetes em cada local para sua implantação. Os clusters podem ser zonais se você implantar em apenas uma zona nesse cluster. O Spanner Omni é compatível com a configuração de gráficos do Helm para ambientes do Google Kubernetes Engine (GKE) e do Amazon Elastic Kubernetes Service (Amazon EKS). Outros ambientes podem exigir configurações personalizadas.

  • Acesse a imagem do contêiner hospedada no Artifact Registry.

  • Instale e configure a ferramenta de linha de comando kubectl e o Helm.

  • Se você configurar o ambiente do Kubernetes em máquinas da plataforma de virtualização vSphere, desative a virtualização do contador de carimbos de data/hora (TSC) adicionando monitor_control.virtual_rdtsc = FALSE ao arquivo de configuração .vmx da máquina virtual. Isso ajuda o TrueTime a funcionar corretamente.

  • Configure a rede do cluster do Kubernetes para que os pods em um cluster possam se conectar com pods em outro cluster. Por padrão, o Spanner Omni usa as portas TCP 15000 a 15025 para comunicação interna. Para ativar a comunicação entre pods nesses clusters, abra essas portas para o tráfego.

  • Configure o DNS do cluster para resolver o nome do host de um pod, como spanner-a-0.pod.spanner-ns-r1, para o endereço IP dele. O Spanner Omni exige resolução de nome do host para conexões TCP entre pods em clusters diferentes.

Preparar a configuração do gráfico Helm

Crie uma configuração do Helm. Para mais informações, consulte Criar uma configuração do Helm.

O número de servidores raiz por zona precisa ser um número ímpar entre 1 e 9, inclusive, para garantir o quorum de consistência. Se o número de servidores for par, as implantações poderão falhar. Ao configurar as zonas, designe servidores como servidores raiz. Recomendamos que você use um para desenvolvimento ou teste e três para zonas de produção de alta disponibilidade.

Como essa é uma implantação multicluster, verifique se o arquivo YAML de configuração do Helm inclui o seguinte:

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

deployment:
  multiCluster: true

Exemplo de configuração de gráfico do Helm para implantação em vários clusters

Confira um exemplo de gráfico do Helm configurado para uma implantação multicluster do Spanner Omni. Essa configuração cria uma implantação em três regiões de Google Cloud : us-west1, us-west2 e us-west3. A implantação é distribuída em cinco zonas, e cada uma delas representa uma réplica. As réplicas em us-west1 e us-west2 são de leitura e gravação, enquanto a única réplica em us-west3 é uma réplica de testemunha.

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

Configurar kubectl para se conectar a vários clusters

Antes de continuar, crie clusters com contextos do kubectl. Por exemplo, no arquivo YAML de configuração do Helm, é possível nomear os contextos com base no local, como ctx-usw1, ctx-usw2 e ctx-usw3.

Configurar a criptografia TLS

Se você estiver configurando uma implantação sem criptografia, pule para Instalar um gráfico do Helm para cada cluster.

Para configurar a criptografia TLS em uma implantação multicluster, crie uma autoridade certificadora (CA) e gere certificados para cada cluster. Para mais informações, consulte Adicionar criptografia TLS à implantação do Kubernetes.

Gerar os certificados

Crie a CA e os certificados para o servidor e a API. Os certificados do servidor e da API precisam incluir os hosts de todos os clusters.

Criar o certificado do servidor do Spanner Omni

Os servidores do Spanner Omni usam certificados de servidor para criptografar a comunicação entre servidores.

Para criar o certificado do servidor, execute o seguinte comando: Substitua SERVER_LIST por uma lista separada por vírgulas de FQDNs de pods de servidor do Spanner Omni ou use caracteres curinga.

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

Criar o certificado da API

Os certificados de API criptografam a comunicação de sistemas que interagem com a implantação.

Para criar o certificado da API, execute o seguinte. Substitua OMNI_ENDPOINT pelos endpoints de serviço de cada cluster.

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

Envie os certificados para cada cluster do Kubernetes

Para cada cluster, crie o namespace e um secret genérico que contenha os 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>

Instalar um gráfico do Helm para cada cluster

Crie uma configuração do Helm. Para mais informações, consulte Criar uma configuração do Helm.

Para uma implantação em vários clusters, aplique a configuração do gráfico do Helm do arquivo de configuração do Helm a cada cluster do Kubernetes. Em cada comando, direcione um local específico e o namespace dele para vinculá-lo à implantação do Spanner Omni. Aplique a configuração a cada local na mesma ordem em que estão listados no arquivo de configuração do Helm. Quando você aplica a configuração ao local final, o sistema cria um trabalho de bootstrap de implantação nesse cluster.

Antes de instalar o Helm em cada cluster, crie o namespace de monitoramento no cluster em que você planeja hospedar a pilha de observabilidade:

kubectl create namespace monitoring --context ctx-usw1

Exemplos de comandos de instalação de gráficos do Helm

Os comandos a seguir instalam um gráfico do Helm em clusters. Em cada comando, PATH_TO_HELM_CONFIG_FILE é o caminho para o arquivo YAML de configuração do gráfico Helm que você criou para sua implantação.

Instalar um gráfico em us-west1 com o monitoramento ativado

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 1.0.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

Instalar um gráfico em us-west2 sem monitoramento

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

Instalar um gráfico em us-west3 sem monitoramento

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

Acompanhar o progresso da implantação

Depois de aplicar a configuração do gráfico Helm, um job de bootstrap será iniciado em cada cluster do Kubernetes. Depois que o job de inicialização for iniciado no último cluster, execute o comando a seguir para acompanhar o processo de implantação:

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

Se os registros indicarem que a implantação não consegue alcançar todos os servidores, verifique se o serviço de DNS em cada cluster está configurado corretamente.

Configurar o serviço de DNS do cluster

Se você estiver usando um DNS externo com seu cluster do Kubernetes e ele gerenciar entradas DNS para serviços headless, pule esta etapa.

O Spanner usa o nome do host do pod para toda a comunicação interna. Configure o DNS para que os pods possam resolver nomes de host mesmo quando executados em clusters diferentes do Kubernetes. Para fazer isso, exponha o serviço kube-dns em cada cluster para que outros clusters possam acessá-lo executando o script dns-setup.sh.

Esse script implanta um serviço de balanceador de carga em cada cluster para o aplicativo kube-dns e atualiza a configuração de DNS para apontar para os serviços do balanceador de carga. Embora o dns-setup.sh configure o kube-dns e o CoreDNS no GKE e no Amazon EKS, talvez seja necessário configurar para seu ambiente.

Para configurar o serviço DNS do cluster:

  1. Se ainda não tiver feito isso, baixe o script dns-setup.sh do bucket do Cloud Storage spanner-omni.

    Acessar o bucket do Spanner Omni

  2. Execute o script dns-setup.sh:

    dns-setup.sh -n CSV_NAME_SPACE_LIST CONTEXTS
    
    • Substitua CSV_NAME_SPACE_LIST por uma lista separada por vírgulas dos seus namespaces.

    • Substitua CONTEXTS por uma lista dos seus contextos.

    Confira um exemplo de uso do script dns-setup.sh:

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

Depois de executar o script, verifique os registros do job de implantação. As mensagens indicam que a implantação está em andamento, e uma mensagem Deployment created successfully aparece.

Atualizar o certificado da API

Se você estiver configurando a implantação sem criptografia TLS, vá para Interagir com o Spanner Omni.

Para implementar a criptografia TLS, atualize o certificado da API com os endereços IP externo ou nomes DNS dos balanceadores de carga de cada cluster. Isso garante que os clientes possam se conectar à implantação por canais seguros.

  1. Receba os detalhes do serviço para cada cluster:

    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. Atualize o certificado da API com os endereços IP externo:

    # 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. Atualize os secrets em cada cluster do Kubernetes com o novo certificado da 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)\"}}"
    

Interagir com o Spanner Omni

Cada cluster em uma configuração multicluster tem um serviço de balanceador de carga. É possível usar qualquer um dos endereços IP externo do serviço para interagir com o Spanner Omni. Para gravações e leituras consistentes, use o endereço que funciona como a região líder. Para solicitações de leitura desatualizadas, use a região mais próxima do seu aplicativo para ter o melhor desempenho.

  1. Execute o comando a seguir para receber o endereço do serviço:

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

    O EXTERNAL-IP:PORT é o DEPLOYMENT_ENDPOINT da sua implantação.

  2. Se ainda não tiver feito isso, baixe a CLI do Spanner Omni do bucket do Cloud Storage spanner-omni.

    Acessar o bucket do Spanner Omni

  3. Se você criou uma implantação com criptografia TLS, inclua o certificado da CA em cada comando para estabelecer uma conexão criptografada. Se você ativou o mTLS para clientes, inclua também o diretório de certificados do cliente.

    • --ca-certificate-file=certs/ca-api.crt
    • --client-certificate-directory=clientcerts
  4. Use a CLI do Spanner Omni para criar um banco de dados GoogleSQL ou PostgreSQL e interagir com ele.

    GoogleSQL

    Para criar e interagir com um banco de dados do GoogleSQL, execute o seguinte:

    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 criar e interagir com um banco de dados PostgreSQL, execute o seguinte:

    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
    

    Também é possível interagir com um banco de dados PostgreSQL seguindo as instruções em Conectar usando o PGAdapter para configurar o PGAdapter e usar ferramentas do PostgreSQL, como psql, com seus bancos de dados de dialeto PostgreSQL.

A seguir