使用 Redis Enterprise 将 Redis 部署到 GKE


本指南介绍了如何将 Redis Enterprise 部署到 Google Kubernetes Engine (GKE) 集群。

Redis 是一个开源内存中 NoSQL 数据库,主要用于缓存。它具有内置的复制功能、Lua 脚本、LRU 逐出、事务、磁盘持久性和高可用性。

Redis Enterprise 是一种企业级解决方案,扩展了 Redis 开源并简化了管理,包括地理位置复制的数据分布、运营吞吐量的线性扩缩、数据分层、高级安全功能等。

Redis Enterprise 的每种部署选项(包括软件混合云和多云)都有不同的价格。

本指南适用于有意在 Google Kubernetes Engine (GKE) 上部署 Redis Enterprise 的平台管理员、云架构师和专业运营人员。

目标

  • 为 Redis 规划和部署 GKE 基础架构
  • 部署 Redis Enterprise Operator
  • 部署 Redis Enterprise 集群
  • 创建 Redis Enterprise 数据库
  • 演示数据库身份验证

优势

Redis Enterprise 具有以下优势:

  • 一种 Kubernetes 原生方法,用于管理 Redis Enterprise 集群 (REC) 生命周期和 Redis Enterprise 数据库 (REDB)
  • 在单个 Kubernetes Pod 中共置多个 Redis 数据库,提高资源利用率
  • 通过处理日常维护任务(例如修补和升级)降低运营开销
  • 支持来自私有容器注册表(例如 Artifact Registry)的 Redis 软件映像,以增强容器的安全性和可用性
  • 支持 Google Cloud Managed Service for Prometheus,用于数据库监控和可观测性
  • 增强的安全功能,例如加密、访问权限控制以及与 Kubernetes RBAC(基于角色的访问权限控制)的集成
  • 高级身份验证方法,包括 LDAP 和第三方凭据管理器(如 Vault)
  • 能够配置预定备份

部署架构

Redis Enterprise 管理以下 Kubernetes 资源:

  • StatefulSet 中的 Enterprise 集群及其配置。集群由安装了 Redis 软件包的 Redis 节点 (Pod) 组成。这些节点具有运行中的进程,以确保节点属于集群。每个节点都提供一个容器来运行多个数据库实例(分片)。虽然 Kubernetes 最佳做法声明 Pod 应代表一个具有一个容器的应用,但 Redis Enterprise 会将多个 Redis 数据库部署到单个容器。此方法可提供更好的资源利用率、性能和网络吞吐量。每个容器还具有一个零延迟代理,用于将流量路由到容器内的特定 Redis 数据库进程并进行管理。
  • RedisEnterpriseDatabase (REDB) 自定义资源,表示在 REC 内创建的 Redis 数据库实例
  • 将 REDB 实例用作数据库端点的 Kubernetes Service
  • 名为 Service Rigger 的控制器 Pod,可在创建或删除数据库时创建和删除数据库端点

在本教程中,您将 REC 部署到专用命名空间,并为应用部署使用单独的命名空间以创建一对多部署,从而实现更好的隔离。

下图介绍了 Redis Enterprise 组件及其互连方式:

图表显示了 Redis Enterprise 架构示例。
图 1:Redis Enterprise 架构示例。

在本教程中,您将对 Redis Enterprise 集群进行配置,使其具备高可用性。为完成此操作,REC 要求节点数为奇数,且至少有三个节点。您还可以设置亲和性、反亲和性规则和节点污点,以确保每个 Redis 节点都放置在不同的 Kubernetes 节点中,并且 Redis 节点均匀分布在 Kubernetes 集群中。

使用多个节点和可用区对于实现高可用性 GKE 集群至关重要,原因如下:

  • 容错性:多个节点在整个集群中分配工作负载,确保某个节点发生故障时,其他节点可以接管任务,从而防止产生停机时间和发生服务中断。
  • 可伸缩性:具有多个节点可以通过根据需要添加或删除节点进行水平扩缩,从而确保最佳资源分配并适应增加的流量或工作负载需求。
  • 高可用性:在区域内使用多个可用区可确保冗余,并最大限度地降低单点故障风险。如果整个可用区发生服务中断,则集群可以继续在其他可用区中运行,从而保持服务可用性。
  • 地理位置冗余:通过让节点跨越各个区域,集群的数据和服务可分布在不同地理位置,从而防范自然灾害、电力中断或可能影响单个可用区的其他本地中断。
  • 滚动更新和维护:通过使用多个节点,您可以对各个节点执行滚动更新和维护,而不会影响集群的整体可用性。这样可确保服务不中断,同时您能够执行必要的更新并无缝应用补丁。
  • 服务等级协议 (SLA):Google Cloud 为多可用区部署提供服务等级协议,保证最低级别的正常运行时间和可用性。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  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. 确保您的 Google Cloud 项目已启用结算功能

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

    gcloud services enable compute.googleapis.com iam.googleapis.com container.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. 确保您的 Google Cloud 项目已启用结算功能

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

    gcloud services enable compute.googleapis.com iam.googleapis.com container.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/compute.securityAdmin, roles/compute.viewer, roles/container.clusterAdmin, roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser

    gcloud projects add-iam-policy-binding PROJECT_ID --member="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.

设置您的环境

在本教程中,您将使用 Cloud Shell 来管理 Google Cloud 上托管的资源。Cloud Shell 预安装了本教程所需的软件,包括 kubectlgcloud CLITerraform

如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:

  1. 点击 Google Cloud 控制台中的 Cloud Shell 激活图标 激活 Cloud Shell,从 Google Cloud 控制台启动 Cloud Shell 会话。此操作会在 Google Cloud 控制台的底部窗格中启动会话。

  2. 设置环境变量:

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

    替换 PROJECT_ID:您的 Google Cloud 项目 ID

  3. 克隆 GitHub 代码库:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. 切换到工作目录:

    cd kubernetes-engine-samples/databases/redis-enterprise-operator
    

创建集群基础架构

在本部分中,您将运行 Terraform 脚本以创建高可用性专用区域级 GKE 集群和 VPC。

下图显示了部署在三个不同可用区中的专用区域级 Standard GKE 集群:

若要部署此基础架构,请从 Cloud Shell 运行以下命令:

  cd terraform/gke-standard
  export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
  terraform init
  terraform apply -var project_id=${PROJECT_ID}   \
    -var region=${REGION}  \
    -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}

出现提示时,请输入 yes。完成此命令并使集群显示就绪状态可能需要几分钟时间。

Terraform 会创建以下资源:

  • Kubernetes 节点的 VPC 网络和专用子网
  • 用于通过 NAT 访问互联网的路由器
  • 专用 GKE 集群(在 us-central1 区域中)
  • 一个启用了自动扩缩的节点池(每个可用区一个到两个节点,每个可用区最少一个节点)

输出类似于以下内容:

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

连接到集群

使用 Cloud Shell,配置 kubectl 以与集群通信:

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

将 Redis Enterprise Operator 部署到您的集群

在本部分中,您需要将 Redis Enterprise Operator 部署到 Kubernetes 集群。

  1. 为 REC 及其应用创建命名空间:

    kubectl create namespace rec-ns
    kubectl create namespace application
    
  2. 为命名空间添加标签:

    kubectl label namespace rec-ns connection=redis
    kubectl label namespace application connection=redis
    
  3. 获取最新版本的 Redis Enterprise Operator 软件包:

    VERSION=`curl --silent https://api.github.com/repos/RedisLabs/redis-enterprise-k8s-docs/releases/latest | grep tag_name | awk -F'"' '{print $4}'`
    
  4. 安装 Redis Enterprise Operator:

    kubectl apply -n rec-ns -f https://raw.githubusercontent.com/RedisLabs/redis-enterprise-k8s-docs/$VERSION/bundle.yaml
    

    输出类似于以下内容:

    role.rbac.authorization.k8s.io/redis-enterprise-operator created
    rolebinding.rbac.authorization.k8s.io/redis-enterprise-operator created
    serviceaccount/redis-enterprise-operator created
    service/admission created
    customresourcedefinition.apiextensions.k8s.io/redisenterpriseclusters.app.redislabs.com created
    customresourcedefinition.apiextensions.k8s.io/redisenterprisedatabases.app.redislabs.com created
    customresourcedefinition.apiextensions.k8s.io/redisenterpriseremoteclusters.app.redislabs.com created
    customresourcedefinition.apiextensions.k8s.io/redisenterpriseactiveactivedatabases.app.redislabs.com created
    deployment.apps/redis-enterprise-operator created
    

部署 Redis Enterprise 集群

  1. 将清单应用到您的集群:

    kubectl apply -n rec-ns -f manifests/01-basic-cluster/rec.yaml
    

    此命令可能需要几分钟才能完成。

  2. 检查 REC 部署的状态:

    kubectl get rec -n rec-ns
    

    输出类似于以下内容:

    NAME      NODES   VERSION    STATE     SPEC STATUS   LICENSE STATE   SHARDS LIMIT   LICENSE EXPIRATION DATE   AGE
    gke-rec   3       7.2.4-52   Running   Valid         Valid           4              2023-09-29T20:15:32Z      4m7s
    

    STATERUNNING 时,表示集群已准备就绪。

可选:配置准入控制器

您可以选择性地在部署时为数据库验证配置基础设施。

  1. 设置准入控制器并检查是否存在准入 TLS Secret:

    kubectl get secret admission-tls -n rec-ns
    
  2. 获取证书:

    export CERT=$(kubectl get secret admission-tls -n rec-ns -o jsonpath='{.data.cert}')
    
  3. 将证书复制到 webhook.yaml 文件中:

    sed -i -e 's/CRT/'$CERT'/g' manifests/01-basic-cluster/webhook.yaml
    
  4. 部署验证 webhook:

    sed -i -e 's/CRT/'$CERT'/g' manifests/01-basic-cluster/webhook.yaml
    

    准入控制器会在已加标签的命名空间上验证数据库语法。

  5. 通过创建非功能性数据库来验证准入控制器:

    kubectl apply -n rec-ns -f - << EOF
    apiVersion: app.redislabs.com/v1alpha1
    kind: RedisEnterpriseDatabase
    metadata:
      name: redis-enterprise-database
    spec:
      evictionPolicy: illegal
    EOF
    

    输出类似于以下内容:

    Error from server: error when creating "STDIN": admission webhook "redisenterprise.admission.redislabs" denied the request: 'illegal' is an invalid value for 'eviction_policy'. Possible values are ['volatile-lru', 'volatile-ttl', 'volatile-random', 'allkeys-lru', 'allkeys-random', 'noeviction', 'volatile-lfu', 'allkeys-lfu']
    

创建命名空间

默认情况下,Redis Enterprise Operator 无权在其自己的命名空间之外执行操作。如需允许 Redis Enterprise Operator 在其他命名空间中创建 REDB 和数据库端点,您必须配置 RBAC。

  1. 在应用命名空间中应用相应的角色和角色绑定:

    kubectl apply -f manifests/01-basic-cluster/role.yaml -n application
    kubectl apply -f manifests/01-basic-cluster/role-binding.yaml -n application
    
  2. rec-ns 命名空间中创建集群角色和集群角色绑定:

    kubectl apply -n rec-ns -f manifests/01-basic-cluster/cluster_role.yaml 
    kubectl apply -n rec-ns -f manifests/01-basic-cluster/cluster_role_binding.yaml
    
  3. 修改 REC ConfigMap 以添加对应用命名空间的控制:

    kubectl patch ConfigMap/operator-environment-config --type merge -p '{"data": {"REDB_NAMESPACES_LABEL": "connection=redis"}}' -n rec-ns
    

    系统会修补标记为 ConfigMap 的每个命名空间。

  4. 检查 rec-ns 命名空间的 Redis 基础设施中的资源的状态:

    kubectl get pod,deploy,svc,rec,statefulset,cm,secrets -n rec-ns
    

    输出类似于以下内容:

    NAME                                             READY   STATUS    RESTARTS        AGE
    pod/gke-rec-0                                    2/2     Running   0               172m
    pod/gke-rec-1                                    2/2     Running   0               171m
    pod/gke-rec-2                                    2/2     Running   0               168m
    pod/gke-rec-services-rigger-5f885f59dc-gc79g     1/1     Running   0               172m
    pod/redis-enterprise-operator-6668ccd8dc-kx29z   2/2     Running   2 (5m58s ago)   5h
    
    NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/gke-rec-services-rigger     1/1     1            1           172m
    deployment.apps/redis-enterprise-operator   1/1     1            1           5h
    
    NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
    service/admission      ClusterIP   10.52.11.13   <none>        443/TCP             5h
    service/gke-rec        ClusterIP   10.52.5.44    <none>        9443/TCP,8001/TCP   172m
    service/gke-rec-prom   ClusterIP   None          <none>        8070/TCP            172m
    service/gke-rec-ui     ClusterIP   10.52.3.29    <none>        8443/TCP            172m
    
    NAME                                               NODES   VERSION    STATE     SPEC STATUS   LICENSE STATE   SHARDS LIMIT   LICENSE EXPIRATION DATE   AGE
    redisenterprisecluster.app.redislabs.com/gke-rec   3       7.2.4-52   Running   Valid         Valid           4              2023-10-05T11:07:20Z      172m
    
    NAME                       READY   AGE
    statefulset.apps/gke-rec   3/3     172m
    
    NAME                                    DATA   AGE
    configmap/gke-rec-bulletin-board        1      172m
    configmap/gke-rec-health-check          5      172m
    configmap/kube-root-ca.crt              1      5h2m
    configmap/operator-environment-config   1      5h
    
    NAME                   TYPE     DATA   AGE
    secret/admission-tls   Opaque   2      5h
    secret/gke-rec         Opaque   2      172m
    

部署 Redis Enterprise 数据库

  1. 在应用命名空间中创建 Redis Enterprise 数据库:

    kubectl apply -f manifests/01-basic-cluster/a-rdb.yaml -n application
    
  2. 检查 REDB 状态:

    kubectl get redb --all-namespaces
    

    输出类似于以下内容:

    NAMESPACE       NAME       VERSION   PORT    CLUSTER   SHARDS   STATUS   SPEC STATUS   AGE
    application   app-db   7.2.0     12999   gke-rec   1        active   Valid         15s
    
  3. 验证每个 REDB 的服务是否正在运行:

    kubectl get svc --all-namespaces
    

    输出类似于以下内容:

    NAMESPACE      NAME      TYPE          CLUSTER-IP   EXTERNAL-IP                           PORT(S)    AGE
    application  app-db  ExternalName  <none>       redis-12999.rec-ns.svc.cluster.local  12999/TCP  72m
    
  4. 验证是否已创建 Secret:

    kubectl get secrets -n application
    

    输出类似于以下内容:

    NAME            TYPE     DATA   AGE
    redb-app-db   Opaque   3      96m
    

使用密码进行身份验证

您可以在应用命名空间中使用具有 redis-cli 的 Pod 连接到 REDB。客户端 Pod 使用应用命名空间 (REDB) 中可用的 Secret 来建立连接。

使用自定义资源 REDB 创建的数据库仅支持不使用 ACL 的密码身份验证

  1. 创建客户端 Pod:

    kubectl apply -n application -f manifests/03-auth/client_pod.yaml
    
  2. 连接到客户端 Pod:

    kubectl exec -n application -i -t redis-client -c redis-client -- /bin/sh
    
  3. 连接到数据库:

    redis-cli -h $SERVICE -p $PORT --pass $PASS
    
  4. 创建密钥:

    SET mykey "Hello World"
    

    输出类似于以下内容:

    OK
    
  5. 获取密钥:

    GET mykey
    

    输出类似于以下内容:

    "Hello World"
    
  6. 退出 Pod shell

    exit
    

了解 Prometheus 如何收集 Redis 集群的指标

下图展示了 Prometheus 指标收集的工作原理:

在该图中,GKE 专用集群包含:

  • Redis Pod,用于收集路径 / 和端口 8070 的指标
  • 基于 Prometheus 的收集器,用于处理 Redis Pod 中的指标
  • 将指标发送到 Cloud Monitoring 的 PodMonitoring 资源

Redis Enterprise Operator 以 Prometheus 格式公开集群指标。

  1. 创建 metrics-proxy 部署:

    kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/metrics-proxy.yaml
    

    由于该 Operator 仅提供具有自签名证书的 HTTPS 端点,并且 PodMonitoring 资源不支持停用 TLS 证书验证,因此您可以将 metrics-proxy Pod 用作此端点的反向代理,以在 HTTP 端口上公开指标。

  2. 创建 PodMonitoring 资源,以按 labelSelector 爬取指标:

    kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/pod-monitoring.yaml
    
  3. 在 Google Cloud 控制台中,转到 GKE 集群信息中心页面。

    转到 GKE 集群信息中心

    信息中心显示非零指标提取率。

创建信息中心

您可以通过创建信息中心来查看指标。

  1. 创建信息中心:

    gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file monitoring/dashboard.json
    

    输出类似于以下内容:

    Created [f4efbe4e-2605-46b4-9910-54b13d29b3be].
    
  2. 在 Google Cloud 控制台中,转到信息中心页面。

    转到“信息中心”

  3. 打开 Redis Enterprise 集群信息中心。信息中心可能需要几分钟时间才能完成自动预配。

验证导出的指标

如需验证指标,请创建新数据库并检查指标。

  1. 打开 Redis Enterprise 集群信息中心

  2. 创建一个额外的 Redis 数据库:

    kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/c-rdb.yaml
    

    信息中心上的数据库计数应会更新。

  3. 创建客户端 Pod 以连接到新数据库:

    kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/client_pod.yaml
    
  4. 连接到客户端 Pod 并准备变量:

    kubectl exec -it redis-client-c -n rec-ns -- /bin/bash
    
  5. 使用 redis-cli 工具创建新密钥:

    for i in {1..50}; do \
      redis-cli -h $SERVICE -p $PORT -a $PASS \
      --no-auth-warning SET mykey-$i "myvalue-$i"; \
    done
    
  6. 刷新页面,您会观察到图表已更新为显示实际数据库状态。

  7. 退出 Pod shell

    exit
    

清理

删除项目

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

删除各个资源

  1. 设置环境变量。

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=redis
    export REGION=us-central1
    
  2. 运行 terraform destroy 命令:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    cd terraform/gke-standard
    terraform destroy -var project_id=${PROJECT_ID}   \
      -var region=${REGION}  \
      -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    出现提示时,请输入 yes

  3. 查找所有未挂接的磁盘:

    export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
    
  4. 删除磁盘:

    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
    
  5. 删除 GitHub 代码库:

    rm -r ~/kubernetes-engine-samples/
    

后续步骤

  • 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud 架构中心