使用 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 運算子
  • 部署 Redis Enterprise 叢集
  • 建立 Redis Enterprise 資料庫
  • 示範資料庫驗證

優點

Redis Enterprise 具有下列優勢:

  • 以 Kubernetes 原生方式管理 Redis Enterprise Cluster (REC) 生命週期和 Redis Enterprise Databases (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 資料庫部署至單一容器。這種做法可提高資源使用率、效能和網路輸送量,每個容器也都有零延遲 Proxy,可將流量傳送至容器內的特定 Redis 資料庫程序,並管理這些流量。
  • 代表在 REC 中建立的 Redis 資料庫執行個體的 RedisEnterpriseDatabase (REDB) 自訂資源
  • 做為資料庫端點的 REDB 執行個體所使用的 Kubernetes 服務
  • 名為 Service Rigger 的控制器 Pod,會在建立或刪除資料庫時,建立及刪除資料庫端點

在本教學課程中,您會將 REC 部署到專屬命名空間,並為應用程式部署作業使用不同的命名空間,以提高隔離效果,藉此建立「一對多」部署作業。

下圖說明 Redis Enterprise 元件,以及這些元件的互連方式:

圖表:顯示 Redis Enterprise 架構範例。
圖 1:Redis Enterprise 架構範例。

在本教學課程中,您會將 Redis Enterprise Cluster 設定為高可用性。為此,REC 需要奇數個節點,且至少要有三個節點。您也可以設定親和性、反親和性規則和節點汙點,確保每個 Redis 節點都放置在不同的 Kubernetes 節點中,且 Redis 節點平均分布在 Kubernetes 叢集中。

使用多個節點和可用區,對於實現高可用性 GKE 叢集至關重要,原因如下:

  • 容錯能力:多個節點會在叢集中分配工作負載,確保其中一個節點故障時,其他節點可以接管工作,避免停機和服務中斷。
  • 擴充性:多個節點可視需要新增或移除節點,進行水平擴充,確保資源分配達到最佳狀態,並因應流量或工作負載需求增加的情況。
  • 高可用性:在區域內使用多個可用區可確保備援,並將單一故障點的風險降至最低。如果整個可用區發生中斷,叢集仍可在其他區域繼續運作,維持服務可用性。
  • 地理位置備援:將節點分散至各個區域,叢集的資料和服務也會分散至各地,可防範天災、停電或其他可能影響單一可用區的區域性服務中斷。
  • 輪流更新和維護:使用多個節點時,您可以對個別節點執行輪流更新和維護作業,而不會影響叢集的整體可用性。確保服務不中斷,同時讓您順暢地執行必要更新及套用修補程式。
  • 服務水準協議 (SLA): Google Cloud 為多區域部署作業提供 SLA,保證最低運作時間和可用性。

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用 Compute Engine、IAM、GKE 和 Resource Manager API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用 Compute Engine、IAM、GKE 和 Resource Manager API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com
  14. 將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令: 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

    更改下列內容:

    • PROJECT_ID:專案 ID。
    • USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com
    • ROLE:授予使用者帳戶的 IAM 角色。

設定環境

在本教學課程中,您將使用 Cloud Shell 管理Google Cloud上託管的資源。Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectlgcloud CLITerraform

如要使用 Cloud Shell 設定環境,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,按一下Cloud Shell 啟用圖示Google Cloud 控制台中的「啟用 Cloud Shell」,啟動 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。

下圖顯示部署在三個不同可用區的私有區域標準 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 節點的虛擬私有雲網路和私有子網路
  • 透過 NAT 存取網際網路的路由器
  • us-central1 區域的私人 GKE 叢集
  • 啟用自動調整資源配置的節點集區 (每個可用區一到兩個節點,每個可用區至少一個節點)

輸出結果會與下列內容相似:

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

連線至叢集

使用 Cloud Shell 設定 kubectl 與叢集通訊:

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

將 Redis Enterprise 運算子部署至叢集

在本節中,您會將 Redis Enterprise 運算子部署至 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 運算子:

    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
    

    STATE 變成 RUNNING,叢集就準備就緒。

選用:設定許可控制器

您可以視需要設定基礎架構,在部署時驗證資料庫。

  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. 確認密鑰是否已建立:

    kubectl get secrets -n application
    

    輸出結果會與下列內容相似:

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

使用密碼驗證

您可以使用應用程式命名空間中的 redis-cli,透過 Pod 連線至 REDB。用戶端 Pod 會使用應用程式命名空間 (REDB) 中的可用密鑰建立連線。

使用自訂資源 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 殼層

    exit
    

瞭解 Prometheus 如何收集 Redis 叢集的指標

下圖顯示 Prometheus 指標的收集方式:

在圖表中,GKE 私人叢集包含:

  • Redis Pod,會收集路徑 / 和通訊埠 8070 的指標
  • 以 Prometheus 為基礎的收集器,可處理 Redis Pod 的指標
  • 將指標傳送至 Cloud Monitoring 的 PodMonitoring 資源

Redis Enterprise 運算子會以 Prometheus 格式公開叢集指標。

  1. 建立 metrics-proxy Deployment:

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

    由於運算子只提供具有自行簽署憑證的 HTTPS 端點,且 PodMonitoring 資源不支援停用 TLS 憑證驗證,因此您可以使用 metrics-proxy Pod 做為這個端點的反向 Proxy,在 HTTP 連接埠上公開指標。

  2. 建立 PodMonitoring 資源,透過 labelSelector 抓取指標:

    kubectl apply -n rec-ns -f manifests/02-prometheus-metrics/pod-monitoring.yaml
    
  3. 前往 Google Cloud 控制台的「GKE Clusters Dashboard」(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 控制台的「Dashboards」(資訊主頁) 頁面。

    前往資訊主頁

  3. 開啟 Redis Enterprise Cluster 資訊主頁。自動佈建資訊主頁可能需要幾分鐘的時間。

驗證匯出的指標

如要驗證指標,請建立新資料庫並檢查指標。

  1. 開啟 Redis Enterprise Cluster 資訊主頁

  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 殼層

    exit
    

清除所用資源

刪除專案

    刪除 Google Cloud 專案:

    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/
    

後續步驟