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 Cluster をデプロイする
  • Redis Enterprise Database を作成する
  • データベース認証のデモを行う

利点

Redis Enterprise には次の利点があります。

  • Kubernetes ネイティブの方法での Redis Enterprise Cluster(REC)ライフサイクルと Redis Enterprise Database(REDB)の管理
  • 単一の Kubernetes Pod 内に複数の Redis データベースを配置することによるリソース使用率の向上
  • パッチ適用やアップグレードなどの定期的なメンテナンス タスクによる運用上のオーバーヘッドの削減
  • Artifact Registry などのプライベート コンテナ レジストリでの Redis ソフトウェア イメージのサポートにより、コンテナのセキュリティと可用性を強化
  • データベースのモニタリングとオブザーバビリティのための Google Cloud Managed Service for Prometheus のサポート
  • 暗号化、アクセス制御、Kubernetes RBAC(ロールベース アクセス制御)との統合などの高度なセキュリティ機能
  • LDAP やサードパーティの認証情報マネージャー(Vault など)を含む高度な認証方法
  • スケジュール バックアップの構成機能

Deployment のアーキテクチャ

Redis Enterprise は、次の Kubernetes リソースを管理します。

  • StatefulSet 内の Enterprise クラスタとその構成。クラスタは、Redis パッケージがインストールされた Redis ノード(Pod)で構成されています。これらのノードには、ノードがクラスタの一部であることを確認するための実行中のプロセスがあります。各ノードは、複数のデータベース インスタンス(シャード)を実行するためのコンテナを提供します。Kubernetes のベスト プラクティスでは、Pod は 1 つのコンテナを持つ 1 つのアプリケーションを表すとされていますが、Redis Enterprise は複数の Redis データベースを単一のコンテナにデプロイします。このアプローチにより、リソースの使用率、パフォーマンス、ネットワーク スループットが向上します。各コンテナには、コンテナ内の特定の Redis データベース プロセスにトラフィックを転送して管理するゼロレイテンシのプロキシもあります。
  • REC 内に作成された Redis データベース インスタンスを表す RedisEnterpriseDatabase(REDB)カスタム リソース
  • REDB インスタンスをデータベース エンドポイントとして提供する Kubernetes Service
  • データベースの作成時または削除時にデータベース エンドポイントを作成および削除する Service Rigger というコントローラ Pod

このチュートリアルでは、REC を専用の Namespace にデプロイし、アプリケーションのデプロイに別の Namespace を使用して分離を強化することで、1 対多の Deployment を作成します。

次の図は、Redis Enterprise コンポーネントとそれらの関係を示しています。

この図は、Redis Enterprise アーキテクチャの例を示しています。
図 1: Redis Enterprise アーキテクチャの例。

このチュートリアルでは、高可用性となるように Redis Enterprise Cluster を構成します。これを実現するには、REC に奇数個のノードが必要です(少なくとも 3 個)。また、各 Redis ノードが異なる Kubernetes ノードに配置され、Redis ノードが Kubernetes クラスタ全体に均等に分散されるように、アフィニティ、反アフィニティ ルール、Node Taints も設定します。

高可用性 GKE クラスタを実現するには、次の理由から複数のノードとゾーンを使用することが重要になります。

  • フォールト トレランス: 複数のノードを使用してクラスタ全体にワークロードを分散します。これにより、1 つのノードで障害が発生しても、他のノードがタスクを引き継ぐことができるため、ダウンタイムとサービス中断を防ぐことができます。
  • スケーラビリティ: 複数のノードを使用すると、必要に応じてノードを追加または削除することで、水平方向のスケーリングが可能になります。これにより、最適なリソース割り当てが確保され、増加したトラフィックやワークロードの需要に対応できます。
  • 高可用性: 1 つのリージョン内で複数のゾーンを使用することで、冗長性を確保し、単一障害点のリスクを最小限に抑えることができます。アベイラビリティ ゾーン全体が停止した場合でも、クラスタは他のゾーンで稼働を継続し、サービスの可用性を維持できます。
  • 地理的冗長性: 複数のリージョンにまたがってノードを配置することで、クラスタのデータとサービスが地理的に分散されます。これにより、単一ゾーンに影響を及ぼす可能性のある自然災害、停電、その他のローカルな障害に対する復元力が確保されます。
  • ローリング アップデートとメンテナンス: 複数のノードを使用することで、クラスタ全体の可用性に影響を与えることなく、個々のノードでローリング アップデートとメンテナンスを実施できます。これにより、サービスを継続しながら、必要な更新を行い、パッチをシームレスに適用できます。
  • サービスレベル契約(SLA): Google Cloud は、マルチゾーン デプロイの SLA を提示し、最低レベルの稼働時間と可用性を保証します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  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. 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. Make sure that billing is enabled for your Google Cloud project.

  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. Make sure that billing is enabled for your Google Cloud project.

  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 を作成します。

次の図は、3 つの異なるゾーンにデプロイされた限定公開のリージョン GKE Standard クラスタを示しています。

このインフラストラクチャをデプロイするには、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 経由でインターネットにアクセスするためのルーター
  • us-central1 リージョンの限定公開 GKE クラスタ
  • 自動スケーリングが有効な 1 つのノードプール(ゾーンあたり 1~2 ノード、最小ゾーンあたり 1 ノード)

出力は次のようになります。

...
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 とそのアプリケーションの Namespace を作成します。

    kubectl create namespace rec-ns
    kubectl create namespace application
    
  2. Namespace にラベルを付けます。

    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 Cluster をデプロイする

  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
    

    アドミッション コントローラが、ラベル付き Namespace でデータベース構文を検証します。

  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']
    

Namespace を作成する

デフォルトでは、Redis Enterprise Operator には自身の Namespace の外部でアクションを実行する権限はありません。Redis Enterprise Operator が他の Namespace に REDB とデータベース エンドポイントを作成できるようにするには、RBAC を構成する必要があります。

  1. アプリケーションの Namespace で、対応するロールとロール バインディングを適用します。

    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 Namespace にクラスタロールとクラスタロール バインディングを作成します。

    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 を編集して、アプリケーションの Namespace に対する制御を追加します。

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

    ConfigMap としてラベル付けされている各 Namespace にパッチが適用されます。

  4. rec-ns Namespace の 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 Databases をデプロイする

  1. アプリケーションの Namespace に 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 の 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
    
  4. Secret が作成されたことを確認します。

    kubectl get secrets -n application
    

    出力は次のようになります。

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

パスワードを使用して認証する

アプリケーションの Namespace に redis-cli を含む Pod を使用して、REDB に接続できます。クライアント Pod は、アプリケーションの Namespace(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 のシェルを終了します。

    exit
    

Prometheus が Redis クラスタの指標を収集する仕組み

次の図は、Prometheus が指標を収集する仕組みを示しています。

この図では、GKE 限定公開クラスタに次のものが存在します。

  • パス / とポート 8070 の指標を収集する Redis Pod
  • Redis Pod から取得した指標を処理する Prometheus ベースのコレクタ
  • Cloud Monitoring に指標を送信する PodMonitoring リソース

Redis Enterprise Operator は、クラスタ指標を Prometheus 形式で公開します。

  1. metrics-proxy Deployment を作成します。

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

    オペレーターは自己署名証明書を使用して HTTPS エンドポイントのみを提供し、PodMonitoring リソースは TLS 証明書の検証の無効化に対応していません。このため、metrics-proxy Pod をこのエンドポイントのリバース プロキシとして使用して、HTTP ポートで指標を公開します。

  2. labelSelector で指標を収集する PodMonitoring リソースを作成します。

    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 Cluster ダッシュボードを開きます。ダッシュボードの自動プロビジョニングには数分かかる場合があります。

エクスポートされた指標を検証する

指標を検証するには、新しいデータベースを作成して指標を調べます。

  1. Redis Enterprise Cluster ダッシュボードを開きます。

  2. 追加の Redis データベースを作成します。

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

    ダッシュボードの [Database Count] が更新されます。

  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
    

クリーンアップ

プロジェクトを削除する

    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/
    

次のステップ