本指南介绍了如何将 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 集群进行配置,使其具备高可用性。为完成此操作,REC 要求节点数为奇数,且至少有三个节点。您还可以设置亲和性、反亲和性规则和节点污点,以确保每个 Redis 节点都放置在不同的 Kubernetes 节点中,并且 Redis 节点均匀分布在 Kubernetes 集群中。
使用多个节点和可用区对于实现高可用性 GKE 集群至关重要,原因如下:
- 容错性:多个节点在整个集群中分配工作负载,确保某个节点发生故障时,其他节点可以接管任务,从而防止产生停机时间和发生服务中断。
- 可伸缩性:具有多个节点可以通过根据需要添加或删除节点进行水平扩缩,从而确保最佳资源分配并适应增加的流量或工作负载需求。
- 高可用性:在区域内使用多个可用区可确保冗余,并最大限度地降低单点故障风险。如果整个可用区发生服务中断,则集群可以继续在其他可用区中运行,从而保持服务可用性。
- 地理位置冗余:通过让节点跨越各个区域,集群的数据和服务可分布在不同地理位置,从而防范自然灾害、电力中断或可能影响单个可用区的其他本地中断。
- 滚动更新和维护:通过使用多个节点,您可以对各个节点执行滚动更新和维护,而不会影响集群的整体可用性。这样可确保服务不中断,同时您能够执行必要的更新并无缝应用补丁。
- 服务等级协议 (SLA):Google Cloud 为多可用区部署提供服务等级协议,保证最低级别的正常运行时间和可用性。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
- 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.
-
-
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 - 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.
-
-
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_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 的服务是否正在运行:
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 格式公开集群指标。
创建 metrics-proxy 部署:
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 delete PROJECT_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 架构中心。