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. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. Instale a CLI do Google Cloud.
  3. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  4. Crie ou selecione um projeto do Google Cloud.

    • Crie um projeto do Google Cloud:

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto do Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud.

  5. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  6. Ative as APIs Compute Engine, IAM, GKE, Backup for GKE, and Resource Manager:

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com
  7. Instale a CLI do Google Cloud.
  8. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  9. Crie ou selecione um projeto do Google Cloud.

    • Crie um projeto do Google Cloud:

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto do Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud.

  10. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  11. Ative as APIs Compute Engine, IAM, GKE, Backup for GKE, and Resource Manager:

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com
  12. Atribua os papéis à sua Conta do Google. Execute uma vez o seguinte comando para cada um dos seguintes papéis do IAM: 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:EMAIL_ADDRESS" --role=ROLE
    • Substitua PROJECT_ID pela ID do seu projeto.
    • Substitua EMAIL_ADDRESS pelo seu endereço de e-mail.
    • Substitua ROLE por cada papel individual.

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

Excluir o projeto

    Exclua um projeto do Google Cloud:

    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