本指南介绍了如何将 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 和第三方凭据管理器(例如保险柜)
- 能够配置预定备份
部署架构
Redis Enterprise 管理以下 Kubernetes 资源:
- Enterprise 集群及其配置(在 StatefulSet 中)。集群由安装了 Redis 软件包的 Redis 节点 (Pod) 组成。这些节点具有运行中的进程,以确保节点属于集群。每个节点都提供一个容器来运行多个数据库实例(分片)。虽然 Kubernetes 最佳做法声明 Pod 应代表一个具有一个容器的应用,但 Redis Enterprise 会将多个 Redis 数据库部署到单个容器。此方法可提供更好的资源利用率、性能和网络吞吐量。每个容器还具有一个零延迟代理,用于将流量路由到容器内的特定 Redis 数据库进程并进行管理。
RedisEnterpriseDatabase
(REDB) 自定义资源,表示在 REC 内创建的 Redis 数据库实例- 将 REDB 实例用作数据库端点的 Kubernetes Service
- 一个名为 Service Rigger 的控制器 Pod,用于在创建或删除数据库时创建和删除数据库端点
在本教程中,您将 REC 部署到专用命名空间,并为应用部署使用单独的命名空间以创建一对多部署,从而实现更好的隔离。
下图介绍了 Redis Enterprise 组件及其互连方式:
在本教程中,您将对 Redis Enterprise 集群进行配置,使其具备高可用性。为完成此操作,REC 要求节点数为奇数,且至少有三个节点。您还可以设置亲和性、反亲和性规则和节点污点,以确保每个 Redis 节点都位于不同的 Kubernetes 节点中,并且 Redis 节点在 Kubernetes 集群中均匀分布。
使用多个节点和可用区对于实现高可用性 GKE 集群至关重要,原因如下:
- 容错性:多个节点在整个集群中分配工作负载,确保某个节点发生故障时,其他节点可以接管任务,从而防止产生停机时间和发生服务中断。
- 可伸缩性:具有多个节点可以通过根据需要添加或删除节点进行水平扩缩,从而确保最佳资源分配并适应增加的流量或工作负载需求。
- 高可用性:在区域内使用多个可用区可确保冗余,并最大限度地降低单点故障风险。如果整个可用区发生服务中断,则集群可以继续在其他可用区中运行,从而保持服务可用性。
- 地理位置冗余:通过让节点跨越各个区域,集群的数据和服务可分布在不同地理位置,从而防范自然灾害、电力中断或可能影响单个可用区的其他本地中断。
- 滚动更新和维护:通过使用多个节点,您可以在个别节点上执行滚动更新和维护,而不会影响集群的整体可用性。这样可确保服务不中断,同时您能够执行必要的更新并无缝应用补丁。
- 服务等级协议 (SLA): Google Cloud 为多可用区部署提供服务等级协议,保证最低级别的正常运行时间和可用性。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- 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.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
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 -
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: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.
- Replace
设置环境
在本教程中,您将使用 Cloud Shell 来管理Google Cloud上托管的资源。Cloud Shell 预安装了本教程所需的软件,包括 kubectl
、gcloud CLI 和 Terraform。
如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:
点击 Google Cloud 控制台中的
激活 Cloud Shell,从 Google Cloud 控制台启动 Cloud Shell 会话。此操作会在 Google Cloud 控制台的底部窗格中启动会话。
设置环境变量:
export PROJECT_ID=
PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=redis export REGION=us-central1将
PROJECT_ID
替换为您的 Google Cloud 项目 ID。克隆 GitHub 代码库:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
切换到工作目录:
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 集群。
为 REC 及其应用创建命名空间:
kubectl create namespace rec-ns kubectl create namespace application
为命名空间添加标签:
kubectl label namespace rec-ns connection=redis kubectl label namespace application connection=redis
获取最新版本的 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}'`
安装 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 集群
将清单应用到您的集群:
kubectl apply -n rec-ns -f manifests/01-basic-cluster/rec.yaml
此命令可能需要几分钟才能完成。
检查 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
当
STATE
为RUNNING
时,表示集群已准备就绪。
可选:配置准入控制器
您可以选择性地在部署时为数据库验证配置基础设施。
设置准入控制器,并检查是否存在准入 tls Secret:
kubectl get secret admission-tls -n rec-ns
获取证书:
export CERT=$(kubectl get secret admission-tls -n rec-ns -o jsonpath='{.data.cert}')
将证书复制到
webhook.yaml
文件中:sed -i -e 's/CRT/'$CERT'/g' manifests/01-basic-cluster/webhook.yaml
部署验证 webhook:
sed -i -e 's/CRT/'$CERT'/g' manifests/01-basic-cluster/webhook.yaml
准入控制器会在已加标签的命名空间上验证数据库语法。
通过创建非功能性数据库来验证准入控制器:
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。
在应用命名空间中应用相应的角色和角色绑定:
kubectl apply -f manifests/01-basic-cluster/role.yaml -n application kubectl apply -f manifests/01-basic-cluster/role-binding.yaml -n application
在
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
修改 REC ConfigMap 以添加对应用命名空间的控制:
kubectl patch ConfigMap/operator-environment-config --type merge -p '{"data": {"REDB_NAMESPACES_LABEL": "connection=redis"}}' -n rec-ns
系统会修补标记为 ConfigMap 的每个命名空间。
检查
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 数据库
在应用命名空间中创建 Redis Enterprise 数据库:
kubectl apply -f manifests/01-basic-cluster/a-rdb.yaml -n application
检查 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
验证每个 REDB 的 Service 是否正在运行:
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
验证是否已创建 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 的密码身份验证。
创建客户端 Pod:
kubectl apply -n application -f manifests/03-auth/client_pod.yaml
连接到客户端 Pod:
kubectl exec -n application -i -t redis-client -c redis-client -- /bin/sh
连接到数据库:
redis-cli -h $SERVICE -p $PORT --pass $PASS
创建密钥:
SET mykey "Hello World"
输出类似于以下内容:
OK
获取密钥:
GET mykey
输出类似于以下内容:
"Hello World"
退出 Pod shell
exit
了解 Prometheus 如何收集 Redis 集群的指标
下图展示了 Prometheus 指标收集的工作原理:
在该图中,GKE 专用集群包含:
- Redis Pod,用于收集路径
/
和端口8070
的指标 - 基于 Prometheus 的收集器,用于处理 Redis Pod 中的指标
- 将指标发送到 Cloud Monitoring 的
PodMonitoring
资源
Redis Enterprise Operator 以 Prometheus 格式公开集群指标。
创建指标-代理部署:
kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/metrics-proxy.yaml
由于该 Operator 仅提供具有自签名证书的 HTTPS 端点,并且
PodMonitoring
资源不支持停用 TLS 证书验证,因此您可以将metrics-proxy
Pod 用作此端点的反向代理,以在 HTTP 端口上公开指标。创建 PodMonitoring 资源,以按
labelSelector
爬取指标:kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/pod-monitoring.yaml
在 Google Cloud 控制台中,转到 GKE 集群信息中心页面。
信息中心显示非零指标提取率。
创建信息中心
您可以通过创建信息中心来查看指标。
创建信息中心:
gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file monitoring/dashboard.json
输出类似于以下内容:
Created [f4efbe4e-2605-46b4-9910-54b13d29b3be].
在 Google Cloud 控制台中,转到信息中心页面。
打开 Redis Enterprise 集群信息中心。信息中心可能需要几分钟时间才能完成自动预配。
验证导出的指标
如需验证指标,请创建新数据库并检查指标。
打开 Redis Enterprise 集群信息中心。
创建一个额外的 Redis 数据库:
kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/c-rdb.yaml
信息中心上的数据库计数应会更新。
创建客户端 Pod 以连接到新数据库:
kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/client_pod.yaml
连接到客户端 Pod 并准备变量:
kubectl exec -it redis-client-c -n rec-ns -- /bin/bash
使用
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
刷新页面,您会观察到图表已更新为显示实际数据库状态。
退出 Pod shell
exit
清理
删除项目
Delete a Google Cloud project:
gcloud projects deletePROJECT_ID
删除各个资源
设置环境变量。
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=redis export REGION=us-central1
运行
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
。查找所有未挂接的磁盘:
export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
删除磁盘:
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
删除 GitHub 代码库:
rm -r ~/kubernetes-engine-samples/
后续步骤
- 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud 架构中心。