Implementa Redis en GKE con Spotahome


Redis es una base de datos NoSQL en la memoria de código abierto que se usa principalmente para el almacenamiento en caché. Tiene replicación integrada, secuencias de comandos de Lua, expulsión de LRU, transacciones, persistencia en el disco y alta disponibilidad.

Esta guía está dirigida a administradores de plataformas, arquitectos de nube y profesionales de operaciones interesados en implementar clústeres de Redis en Google Kubernetes Engine (GKE).

En la guía, se muestra cómo usar el operador de Spotahome Redis para implementar clústeres de Redis.

El operador está sujeto a licencia en virtud de la licencia Apache 2.0.

Spotahome ofrece los siguientes beneficios:

  • Administración nativa de Kubernetes de clústeres de Redis
  • Alta disponibilidad proporcionada por Redis Sentinel
  • Integración perfecta de Prometheus para la observabilidad de la base de datos
  • Compatibilidad con la configuración personalizada de Redis

Objetivos

  • Planificar y, además, implementar la infraestructura de GKE para Redis
  • Implementar y configurar el operador de Spotahome Redis
  • Configurar Redis con el operador para garantizar la disponibilidad, la seguridad, la observabilidad y el rendimiento

Arquitectura de implementación

En este instructivo, usarás el operador de Redis Spotahome para implementar y configurar un clúster de Redis con alta disponibilidad en GKE con un nodo líder y dos réplicas de lectura, junto con el clúster de Redis Sentinel que consta de tres réplicas.

Redis Sentinel es un sistema de supervisión y alta disponibilidad para Redis de código abierto. Supervisa continuamente las instancias de Redis, incluido el líder y sus réplicas asociadas. Si el nodo líder falla, Sentinel puede promover de forma automática una de las réplicas para que se convierta en el nuevo líder, para garantizar que siempre haya un nodo líder que funcione y disponible para lecturas y escrituras de datos. Cuando se producen eventos significativos en un clúster de Redis, como una falla del líder o un evento de conmutación por error, Sentinel puede notificar a los administradores o a otros sistemas por correo electrónico, o mediante otros mecanismos de notificación.

También implementarás un clúster de GKE regional con alta disponibilidad para Redis, con varios nodos de Kubernetes distribuidos en varias zonas de disponibilidad. Esta configuración ayuda a garantizar la tolerancia a errores, la escalabilidad y la redundancia geográfica. Permite realizar actualizaciones y mantenimiento progresivos, a la vez que proporciona ANS de tiempo de actividad y disponibilidad. Para obtener más información, consulta Clústeres regionales.

En el siguiente diagrama, se muestra cómo se ejecuta un clúster de Redis en varios nodos y zonas en un clúster de GKE:

En el diagrama, el StatefulSet de Redis se implementa en tres nodos en tres zonas diferentes. Para controlar cómo GKE implementa StatefulSet en nodos y zonas, configura las reglas de afinidad y distribución de topología de pods en la especificación de recursos personalizados RedisFailover.

Si una zona falla, mediante la configuración recomendada, GKE reprograma los Pods en nodos nuevos.

En el siguiente diagrama, se muestra una implementación de Sentinel programada en tres nodos de tres zonas diferentes:

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios de Google Cloud nuevos cumplan con los requisitos para acceder a una prueba gratuita.

Cuando completes las tareas que se describen en este documento, podrás borrar los recursos que creaste para evitar que se te siga facturando. Para obtener más información, consulta Realiza una limpieza.

Antes de comenzar

  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 usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

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

    gcloud init
  5. 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.

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

  7. 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
  8. Install the Google Cloud CLI.

  9. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

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

    gcloud init
  11. 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.

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

  13. 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
  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 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.
  15. Configura tu entorno

    En este instructivo, usarás Cloud Shell para administrar recursos alojados enGoogle Cloud. Cloud Shell tiene preinstalado el software que necesitarás para este instructivo, incluido kubectl, la CLI de gcloud, Helm y Terraform.

    Para configurar tu entorno con Cloud Shell, sigue estos pasos:

    1. Para iniciar una sesión de Cloud Shell desde la Google Cloud consola, haz clic en Ícono de activación de Cloud Shell Activar Cloud Shell en la Google Cloud consola. Esto inicia una sesión en el panel inferior de la consola de Google Cloud .

    2. Establece las variables de entorno:

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

      Reemplaza PROJECT_ID por tu Google Cloud ID del proyecto.

    3. Clona el repositorio de GitHub:

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

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

    Crea la infraestructura del clúster

    En esta sección, debes ejecutar una secuencia de comandos de Terraform para crear un clúster de GKE privado y con alta disponibilidad. Los siguientes pasos permiten el acceso público al plano de control.

    Puedes instalar el operador mediante un clúster de Standard o Autopilot.

    Estándar

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

    Para implementar esta infraestructura, ejecuta los siguientes comandos desde 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}
    

    Cuando se te solicite, escribe yes. Es posible que este comando tarde varios minutos en completarse y que el clúster muestre un estado de preparación.

    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
    • Dos grupos de nodos con ajuste de escala automático habilitado (de uno a dos nodos por zona y un nodo por zona como mínimo)
    • Un ServiceAccount con permisos de registro y supervisión
    • Copia de seguridad para GKE para la recuperación ante desastres
    • Google Cloud Managed Service para Prometheus para la supervisión de clústeres

    El resultado es similar al siguiente:

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

    Autopilot

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

    Para implementar la infraestructura, ejecuta los siguientes comandos desde 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}
    

    Cuando se te solicite, escribe yes. Es posible que este comando tarde varios minutos en completarse y que el clúster muestre un estado de preparación.

    Terraform crea los siguientes recursos:

    • La red de VPC y la 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 supervisión
    • Google Cloud Managed Service para Prometheus para la supervisión de clústeres

    El resultado es similar al siguiente:

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

    Conéctate al clúster

    Usantod Cloud Shell, configura kubectl para que se comunique con el clúster:

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

    Implementa el operador de Spotahome en tu clúster

    En esta sección, implementarás el operador de Spotahome en tu clúster de Kubernetes con un gráfico de Helm y, luego, implementarás un clúster de Redis.

    1. Agrega el repositorio de gráficos de Helm para operadores de Spotahome Redis:

      helm repo add redis-operator https://spotahome.github.io/redis-operator
      
    2. Agrega un espacio de nombres para el operador de Spotahome y el clúster de Redis:

      kubectl create ns redis
      
    3. Implementa el operador de Spotahome con la herramienta de línea de comandos de Helm:

      helm install redis-operator redis-operator/redis-operator --version 3.2.9 -n redis
      
    4. Verifica el estado de implementación del operador de Spotahome con Helm:

      helm ls -n redis
      

      El resultado es similar al siguiente:

      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
      

    Implementa Redis

    La configuración básica de la instancia de clústeres de Redis incluye los siguientes componentes:

    • Tres réplicas de nodos de Redis: una réplica líder y dos réplicas de lectura.
    • Tres réplicas de los nodos de Sentinel, que forman un quórum.
    • Asignación de recursos de CPU de una solicitud de CPU y dos límites de CPU, con requisitos de memoria y límites de 4 GB para Redis, y CPU de 100 m/500 m y 500 MB para Sentinel.
    • Tolerancias, nodeAffinities y topologySpreadConstraints configuradas para cada carga de trabajo, lo que garantiza una distribución adecuada entre los nodos de Kubernetes, con sus respectivos grupos de nodos y zonas de disponibilidad diferentes.

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

    Crea un clúster básico de Redis

    1. Crea un Secret con credenciales de usuario:

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

      El operador no tiene una función para generar credenciales, y la contraseña de la base de datos debe generarse previamente.

    2. Crea un clúster de Redis nuevo mediante la configuración básica:

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

      Este comando crea un recurso personalizado RedisFailover del operador Spotahome que especifica los límites de CPU, memoria y límites; y taints y afinidades para distribuir las réplicas de Pods aprovisionadas en nodos de Kubernetes.

    3. Espera unos minutos mientras Kubernetes inicia las cargas de trabajo requeridas:

      kubectl wait pods -l redisfailovers.databases.spotahome.com/name=my-cluster --for condition=Ready --timeout=300s -n redis
      
    4. Verifica que se hayan creado las cargas de trabajo de Redis:

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

      El resultado es similar al siguiente:

      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
      

    El operador crea los siguientes recursos:

    • Un StatefulSet de Redis y una implementación de Sentinel
    • Tres réplicas de Pod para Redis
    • Tres réplicas de Pod para Sentinel
    • Dos PodDisruptionBudgets, lo que garantiza un mínimo de dos réplicas disponibles para la coherencia del clúster
    • El servicio rfr-my-cluster, que expone las métricas de Redis
    • El servicio redis-my-cluster, que se orienta al nodo líder del clúster de Redis
    • El servicio rfs-my-cluster, que permite a los clientes conectarse al clúster a través de los centinelas. Se requiere compatibilidad con Sentinel para las bibliotecas cliente.

    Comparte las credenciales de Redis

    Puedes compartir credenciales de Redis con clientes usando el método de autenticación heredado del operador Spotahome.

    Debes usar una contraseña de base de datos con el parámetro de configuración requirepass. Luego, todos los clientes usan esta contraseña. Para administrar usuarios adicionales, usa los comandos de la CLI de Redis.

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

    Compartir credenciales de Redis con clientes a través de este método tiene las siguientes limitaciones:

    • Spotahome no proporciona recursos personalizados para la administración de usuarios. Puedes almacenar credenciales en Secrets y hacer referencia a ellas en especificaciones auth.
    • No hay un método para proteger las conexiones con la encriptación TLS con el recurso personalizado.
    • No se admite la actualización en tiempo real de las credenciales.

    Conéctate a Redis

    Puedes implementar un cliente de Redis y autenticarte con una contraseña almacenada en un Secret de Kubernetes.

    1. Ejecuta el Pod de cliente para interactuar con tu clúster de Redis:

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

      La variable de entorno PASS toma el Secret my-user de la bóveda.

    2. Espera a que el Pod esté listo y, luego, conéctate a él:

      kubectl wait pod redis-client --for=condition=Ready --timeout=300s -n redis
      kubectl exec -it redis-client -n redis -- /bin/bash
      
    3. Verifica que la conexión funcione:

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

      El resultado es similar al siguiente:

      OK
      
    4. Obtén el valor de my-key:

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

      El resultado es similar al siguiente:

      "testvalue"
      
    5. Sal de la shell del Pod

      exit
      

    Comprende cómo Prometheus recopila métricas para tu clúster de Redis

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

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

    • Un Pod de Redis que recopila métricas en la ruta de acceso / y el puerto 9121
    • Recopiladores basados en Prometheus que procesan las métricas del Pod de Redis
    • Un recurso PodMonitoring que envía las métricas a Cloud Monitoring

    Google Cloud Managed Service para Prometheus admite la recopilación de métricas en el formato de Prometheus. Cloud Monitoring usa un panel integrado para las métricas de Redis.

    El operador de Spotahome expone las métricas del clúster en formato de Prometheus con redis_exporter como sidecar.

    1. Crea el recurso PodMonitoring para extraer métricas mediante labelSelector:

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

      Ir al Panel de clústeres de GKE

      En el panel, se muestra una tasa de transferencia de métricas distinta de cero.

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

      Ir a Paneles

    4. Abre el panel de Redis Prometheus Overview. En el panel, se muestra la cantidad de conexiones y claves. El panel puede tardar varios minutos en aprovisionarse de forma automática.

    5. Conéctate al Pod de cliente y prepara las variables:

      kubectl exec -it redis-client -n redis -- /bin/bash
      
    6. Usa la herramienta de redis-cli para crear claves nuevas:

      for i in {1..50}; do \
        redis-cli -h redis-my-cluster -a $PASS \
        --no-auth-warning SET mykey-$i "myvalue-$i"; \
      done
      
    7. Actualiza la página y observa que los gráficos Comandos por segundo y Claves se actualizaron para mostrar el estado real de la base de datos.

    8. Sal de la shell del Pod

      exit
      

    Realiza una limpieza

    Borra el proyecto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Borra los recursos individuales

    1. Configurar variables de entorno

      export PROJECT_ID=${PROJECT_ID}
      export KUBERNETES_CLUSTER_PREFIX=redis
      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}
      

      Reemplaza FOLDER por gke-autopilot o gke-standard.

      Cuando se te solicite, escribe yes.

    3. Busca todos los discos no conectados:

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

    ¿Qué sigue?

    • Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.