Implantar o Redis no GKE usando o Spotahome


O Redis é um banco de dados NoSQL na memória de código aberto usado principalmente para armazenamento em cache. Ele tem replicação integrada, scripting Lua, remoção de LRU, transações, persistência no disco e alta disponibilidade.

Este guia é destinado a administradores de plataformas, arquitetos de nuvem e profissionais de operações interessados em implantar clusters do Redis no Google Kubernetes Engine (GKE).

Neste guia, você vai aprender como usar o operador do Redis do Spotahome para implantar clusters do Redis.

O operador está licenciado sob a Licença Apache 2.0.

O Spotahome oferece os seguintes benefícios:

  • Um gerenciamento de clusters do Redis nativo do Kubernetes
  • Alta disponibilidade fornecida pelo Redis Sentinel
  • Integração total com o Prometheus para observabilidade do banco de dados
  • Suporte para definir configurações personalizadas do Redis

Objetivos

  • Planejar e implantar a infraestrutura do GKE para Redis
  • Implantar e configurar o operador do Spotahome para Redis
  • Configurar o Redis usando o operador para garantir disponibilidade, segurança, observabilidade e desempenho

Arquitetura de implantação

Neste tutorial, você vai usar o operador Spotahome do Redis para implantar e configurar um cluster do Redis altamente disponível no GKE com um nó líder e duas réplicas de leitura, além do cluster do Redis Sentinel que consiste em três réplicas de dois minutos.

O Redis Sentinel é um sistema de alta disponibilidade e monitoramento para o Redis de código aberto. Ele monitora continuamente as instâncias do Redis, incluindo o líder e as réplicas associadas. Se o nó líder falhar, o Sentinel poderá promover automaticamente uma das réplicas para se tornar o novo líder, garantindo que haja sempre um nó líder funcional disponível para leituras e gravações de dados. Quando ocorrem eventos significativos em um cluster do Redis, como uma falha de líder ou um evento de failover, o Sentinel pode notificar os administradores ou outros sistemas por e-mail ou outros mecanismos de notificação.

Você também vai implantar um cluster do GKE regional altamente disponível para o Redis, com vários nós do Kubernetes espalhados por várias zonas de disponibilidade. Essa configuração ajuda a garantir tolerância a falhas, escalonabilidade e redundância geográfica. Ele permite atualizações e manutenção graduais, fornecendo SLAs para tempo de atividade e disponibilidade. Para mais informações, consulte Clusters regionais.

O diagrama a seguir mostra como um cluster do Redis é executado em vários nós e zonas em um cluster do GKE:

No diagrama, o StatefulSet do Redis é implantado em três nós de três zonas diferentes. Para controlar como o GKE implanta o StatefulSet em nós e zonas, defina regras de afinidade e distribuição de topologia de pods na especificação de recurso personalizada RedisFailover.

Se uma zona falhar, o GKE usará a configuração recomendada, reprogramando os pods em novos nós.

O diagrama a seguir mostra uma implantação do Sentinel programada em três nós em três zonas diferentes:

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  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. To initialize the gcloud CLI, run the following command:

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

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

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Compute Engine, IAM, GKE, Backup for GKE, and Resource Manager APIs:

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

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

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

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the Compute Engine, IAM, GKE, Backup for GKE, and Resource Manager APIs:

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com
  12. 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 PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.

configure seu ambiente

Neste tutorial, você usará o Cloud Shell para gerenciar recursos hospedados no Google Cloud. O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo kubectl, a gcloud CLI, Helm, e o Terraform.

Para configurar o ambiente com o Cloud Shell, siga estas etapas:

  1. Inicie uma sessão do Cloud Shell no Console do Google Cloud clicando em Ícone de ativação do Cloud Shell Ativar o Cloud Shell no Console do Google Cloud. Isso inicia uma sessão no painel inferior do Cloud Console.

  2. Defina as variáveis de ambiente:

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

    Substitua PROJECT_ID: o Google Cloud pelo ID do projeto.

  3. Clone o repositório do GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. Mude para o diretório de trabalho:

    cd kubernetes-engine-samples/databases/redis-spotahome
    

Criar a infraestrutura do cluster

Nesta seção, você executa um script do Terraform para criar um cluster regional do GKE privado e altamente disponível. As etapas a seguir permitem acesso público ao plano de controle.

É possível instalar o operador usando um cluster padrão ou Autopilot.

Padrão

O diagrama a seguir mostra um cluster regional padrão particular do GKE implantado em três zonas diferentes:

Para implantar essa infraestrutura, execute os seguintes comandos no Cloud Shell:

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}

Quando solicitado, digite yes. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.

O Terraform cria os seguintes recursos:

  • Uma rede VPC e uma sub-rede particular para os nós do Kubernetes.
  • Um roteador para acessar a Internet usando NAT.
  • Um cluster particular do GKE na região us-central1.
  • Dois pools de nós com escalonamento automático ativado (de um a dois nós por zona, sendo no mínimo um nó por zona).
  • Um ServiceAccount com permissões de registro e monitoramento
  • Backup do GKE para recuperação de desastres.
  • Google Cloud Managed Service para Prometheus para monitoramento de clusters.

O resultado será assim:

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

Piloto automático

O diagrama a seguir mostra um cluster particular regional do Autopilot do GKE:

Para implantar a infraestrutura, execute os seguintes comandos do Cloud Shell:

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}

Quando solicitado, digite yes. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.

O Terraform cria os seguintes recursos:

  • Rede VPC e sub-rede privada para os nós do Kubernetes.
  • Um roteador para acessar a Internet usando NAT.
  • Um cluster particular do GKE na região us-central1.
  • Um ServiceAccount com permissão de geração de registros e monitoramento.
  • Google Cloud Managed Service para Prometheus para monitoramento de clusters.

O resultado será assim:

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

Conexão ao cluster

Usando o Cloud Shell, configure kubectl para se comunicar com o cluster:

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

Implantar o operador do Spotahome no cluster

Nesta seção, você vai aprender como implantar o operador do Spotahome no cluster do Kubernetes usando um gráfico do Helm e, em seguida, implantar um cluster do Redis.

  1. Adicione o repositório de gráficos do Helm do operador do Spotahome para Redis:

    helm repo add redis-operator https://spotahome.github.io/redis-operator
    
  2. Adicione um namespace para o operador do Spotahome e o cluster do Redis:

    kubectl create ns redis
    
  3. Implante o operador do Spotahome usando a ferramenta de linha de comando Helm:

    helm install redis-operator redis-operator/redis-operator --version 3.2.9 -n redis
    
  4. Verifique o status da implantação do operador do Spotahome usando o Helm:

    helm ls -n redis
    

    O resultado será assim:

    NAME             NAMESPACE    REVISION    UPDATED                                STATUS      CHART                   APP VERSION
    redis-operator    redis      1           2023-09-12 13:21:48.179503 +0200 CEST    deployed    redis-operator-3.2.9    1.2.4
    

Implantar o Redis

A configuração básica da instância do cluster do Redis inclui os seguintes componentes:

  • Três réplicas de nós do Redis: uma líder e duas réplicas de leitura.
  • Três réplicas de nós do Sentinel, formando um quórum.
  • Alocação de recursos da CPU de uma solicitação de CPU e dois limites de CPU, com solicitações e limites de memória de 4 GB para Redis, e 100 m/500 m de CPU e 500 MB para o Sentinel.
  • As tolerâncias, nodeAffinities e topologySpreadConstraints configurados para cada carga de trabalho, garantindo a distribuição adequada entre os nós do Kubernetes, utilizando os respectivos pools de nós e as diferentes zonas de disponibilidade.

Essa configuração representa a configuração mínima necessária para criar um cluster do Redis pronto para produção.

Criar um cluster básico do Redis

  1. Crie um secret com as credenciais de usuário:

    export PASSWORD=$(openssl rand -base64 12)
    kubectl create secret generic my-user -n redis \
        --from-literal=password="$PASSWORD"
    

    O operador não tem um recurso para gerar credenciais, e a senha do banco de dados precisa ser pré-gerada.

  2. Crie um novo cluster do Redis usando a configuração básica:

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

    Este comando cria um recurso personalizado RedisFailover do operador do Spotahome que especifica CPU, solicitações de memória e limites, taints e afinidades para distribuir as réplicas de pod provisionadas nos nós do Kubernetes.

  3. Aguarde alguns minutos enquanto o Kubernetes inicia as cargas de trabalho necessárias:

    kubectl wait pods -l redisfailovers.databases.spotahome.com/name=my-cluster --for condition=Ready --timeout=300s -n redis
    
  4. Verifique se as cargas de trabalho do Redis foram criadas:

    kubectl get pod,svc,statefulset,deploy,pdb -n redis
    

    O resultado será assim:

    NAME                                READY   STATUS  RESTARTS   AGE
    pod/redis-operator-5dc65cb7cc-krlcs   1/1   Running   0         49m
    pod/rfr-my-cluster-0                2/2     Running   0         60s
    pod/rfr-my-cluster-1                2/2     Running   0         60s
    pod/rfr-my-cluster-2                2/2     Running   0         60s
    pod/rfs-my-cluster-8475dfd96c-h5zvw   1/1   Running   0         60s
    pod/rfs-my-cluster-8475dfd96c-rmh6f   1/1   Running   0         60s
    pod/rfs-my-cluster-8475dfd96c-shzxh   1/1   Running   0         60s
    
    NAME                    TYPE        CLUSTER-IP  EXTERNAL-IP   PORT(S)   AGE
    service/redis-my-cluster ClusterIP   10.52.14.87   <none>       6389/TCP    55s
    service/redis-operator   ClusterIP   10.52.13.217   <none>      9710/TCP    49m
    service/rfr-my-cluster   ClusterIP   None           <none>      9121/TCP    61s
    service/rfs-my-cluster   ClusterIP   10.52.15.197   <none>      26379/TCP   61s
    
    NAME                            READY   AGE
    statefulset.apps/rfr-my-cluster   3/3   61s
    
    NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/redis-operator   1/1    1           1           50m
    deployment.apps/rfs-my-cluster   3/3    3           3           62s
    
    NAME                                        MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    poddisruptionbudget.policy/rfr-my-cluster   2               N/A             1                   64s
    poddisruptionbudget.policy/rfs-my-cluster   2               N/A             1                   63s
    

O operador cria os seguintes recursos:

  • Um StatefulSet do Redis e uma implantação do Sentinel
  • Três réplicas de pods para o Redis
  • Três réplicas de pods para o Sentinel
  • Dois PodDisruptionBudgets, garantindo no mínimo duas réplicas disponíveis para a consistência do cluster
  • O serviço rfr-my-cluster, que expõe métricas do Redis
  • O serviço redis-my-cluster, que tem como destino o nó líder do cluster do Redis
  • O serviço rfs-my-cluster, que permite que os clientes se conectem ao cluster usando as Sentinels. O suporte ao Sentinel é necessário para bibliotecas de cliente.

Compartilhar credenciais do Redis

É possível compartilhar credenciais do Redis com clientes usando o método de autenticação legado do operador do Spotahome

Use uma senha do banco de dados com a configuração requirepass. Essa senha é usada por todos os clientes. Para gerenciar mais usuários, use os comandos da CLI do Redis.

apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
  name: my-cluster
spec:
  ...
  auth:
    secretPath: my-user

O compartilhamento de credenciais do Redis com clientes que usam esse método tem as seguintes limitações:

  • O Spotahome não oferece recursos personalizados para o gerenciamento de usuários. É possível armazenar credenciais em secrets e referenciá-los nas especificações auth.
  • Não há um método para proteger as conexões com a criptografia TLS usando o recurso personalizado.
  • Não há suporte para a atualização em tempo real de credenciais.

Conectar ao Redis

É possível implantar um cliente do Redis e autenticar usando uma senha armazenada em um secret do Kubernetes.

  1. Execute o pod cliente para interagir com o cluster do Redis:

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

    A variável de ambiente PASS recebe o secret my-user do Vault.

  2. Aguarde até que o pod esteja pronto e, em seguida, conecte-se a ele:

    kubectl wait pod redis-client --for=condition=Ready --timeout=300s -n redis
    kubectl exec -it redis-client -n redis -- /bin/bash
    
  3. Verifique se a conexão funciona:

    redis-cli -h redis-my-cluster -a $PASS --no-auth-warning SET my-key "testvalue"
    

    O resultado será assim:

    OK
    
  4. Acesse o valor de my-key:

    redis-cli -h redis-my-cluster -a $PASS --no-auth-warning GET my-key
    

    O resultado será assim:

    "testvalue"
    
  5. Saia do shell do pod

    exit
    

Entender como o Prometheus coleta métricas para seu cluster do Redis

No diagrama a seguir, mostramos como funciona a coleta de métricas do Prometheus:

No diagrama, um cluster particular do GKE contém os seguintes componentes:

  • Um pod Redis que coleta métricas no caminho / e na porta 9121.
  • Coletores baseados em Prometheus que processam as métricas do pod do Redis.
  • Um recurso de PodMonitoring que envia métricas ao Cloud Monitoring.

O Google Cloud Managed Service para Prometheus é compatível com a coleta de métricas no formato do Prometheus. O Cloud Monitoring usa um painel integrado para métricas do Redis.

O operador do Spotahome expõe as métricas de cluster no formato do Prometheus usando o redis_exporter como um arquivo secundário.

  1. Crie o recurso PodMonitoring para coletar métricas por labelSelector:

    kubectl apply -n redis -f manifests/03-prometheus-metrics/pod-monitoring.yaml
    
  2. No console do Google Cloud, acesse a página Painel de clusters do GKE.

    Acessar o painel de clusters do GKE

    O painel mostra uma taxa de ingestão de métricas diferente de zero.

  3. No console do Google Cloud, acesse a página Painéis.

    Ir para "Painéis"

  4. Abra o painel de informações gerais do Redis Prometheus. O painel mostra a quantidade de conexões e chaves. Pode levar vários minutos para que o painel seja provisionado automaticamente.

  5. Conecte-se ao pod cliente e prepare as variáveis:

    kubectl exec -it redis-client -n redis -- /bin/bash
    
  6. Use a ferramenta redis-cli para criar novas chaves:

    for i in {1..50}; do \
      redis-cli -h redis-my-cluster -a $PASS \
      --no-auth-warning SET mykey-$i "myvalue-$i"; \
    done
    
  7. Atualize a página e observe que os gráficos Comandos por segundo e Chaves foram atualizados para mostrar o estado real do banco de dados.

  8. Saia do shell do pod

    exit
    

Limpar

Exclua o projeto

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

Excluir recursos individuais

  1. Defina variáveis de ambiente.

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=redis
    export REGION=us-central1
    
  2. Execute o 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}
    

    Substitua FOLDER por gke-autopilot ou gke-standard.

    Quando solicitado, digite yes.

  3. Encontre todos os discos desanexados:

    export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
    
  4. Exclua os 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
    

A seguir