Redis は、主にキャッシュ用に使用されるオープンソースのインメモリ NoSQL データベースです。組み込みレプリケーション、Lua スクリプト、LRU エビクション、トランザクション、オンディスクの永続性、高可用性などを備えています。
このガイドは、Google Kubernetes Engine(GKE)での Redis クラスタのデプロイに関心のあるプラットフォーム管理者、クラウド アーキテクト、運用担当者を対象としています。
このガイドでは、Spotahome Redis オペレーターを使用して Redis クラスタをデプロイする方法について説明します。
オペレーターは Apache License 2.0 でライセンスされています。
Spotahome には次のようなメリットがあります。
- Kubernetes ネイティブの Redis クラスタ管理
- Redis Sentinel によって提供される高可用性
- シームレスな Prometheus 統合によるデータベースのオブザーバビリティ
- カスタム Redis 構成の設定のサポート
目標
- Redis 向けに GKE インフラストラクチャを計画して、デプロイする
- Spotahome Redis オペレーターをデプロイして構成する
- オペレーターを使用して Redis を構成して、可用性、セキュリティ、オブザーバビリティ、パフォーマンスを確保する
デプロイ アーキテクチャ
このチュートリアルでは、Spotahome Redis オペレーターを使用して、3 つのレプリカで構成される Redis Sentinel クラスタとともに、高可用性 Redis クラスタをリーダーノードと 2 つのリードレプリカのある GKE にデプロイして構成します。
Redis Sentinel は、オープンソースの Redis 用の高可用性およびモニタリング システムです。リーダーとそれに関連するレプリカなどの Redis インスタンスを継続的にモニタリングします。リーダーノードに障害が発生した場合、Sentinel は自動的にレプリカの 1 つを新しいリーダーに昇格させ、データの読み取りと書き込みに使用可能で動作しているリーダーノードが常に存在するようにします。Redis クラスタ内でリーダー障害やフェイルオーバー イベントなどの重大なイベントが発生した場合、Sentinel はメールやその他の通知メカニズムを通じて管理者や他のシステムに通知できます。
また、複数のアベイラビリティ ゾーンに複数の Kubernetes ノードを分散させ、高可用性のリージョンの Redis 用 GKE クラスタをデプロイします。この設定により、フォールト トレランス、スケーラビリティ、地理的冗長性を確保できます。稼働時間と可用性の SLA を提供しながら、ローリング アップデートとメンテナンスが可能になります。詳細については、リージョン クラスタをご覧ください。
次の図は、Redis クラスタが GKE クラスタ内の複数のノードとゾーンでどのように実行されるかを示しています。
この図では、Redis StatefulSet が 3 つの異なるゾーンの 3 つのノードにデプロイされています。GKE がノードとゾーンに StatefulSet をデプロイする方法を制御するには、Pod のアフィニティとトポロジの分散ルールを RedisFailover
カスタム リソース仕様に設定します。
1 つのゾーンに障害が発生した場合、GKE は推奨構成を使用して、新しいノードで Pod を再スケジュールします。
次の図は、3 つの異なるゾーンの 3 つのノードにスケジュールされている Sentinel Deployment を示しています。
費用
このドキュメントでは、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, Backup for GKE, and Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com gkebackup.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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Backup for GKE, and Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/storage.objectViewer, roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin, roles/gkebackup.admin, roles/monitoring.viewer
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、Helm、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-spotahome
クラスタ インフラストラクチャを作成する
このセクションでは、Terraform スクリプトを実行して、限定公開の高可用性リージョン GKE クラスタを作成します。次の手順では、コントロール プレーンへの公開アクセスを許可します。
オペレーターは、Standard または Autopilot クラスタを使用してインストールできます。
Standard
次の図は、3 つの異なるゾーンにデプロイされた限定公開のリージョン GKE Standard クラスタを示しています。
このインフラストラクチャをデプロイするには、Cloud Shell から次のコマンドを実行します。
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
プロンプトが表示されたら、「yes
」と入力します。このコマンドが完了し、クラスタが準備完了ステータスになるまでに数分かかることがあります。
Terraform が次のリソースを作成します。
- Kubernetes ノード用の VPC ネットワークとプライベート サブネット
- NAT 経由でインターネットにアクセスするためのルーター
us-central1
リージョンの限定公開 GKE クラスタ- 自動スケーリングが有効な 2 つのノードプール(ゾーンあたり 1~2 ノード、最小ゾーンあたり 1 ノード)
- ロギングとモニタリングの権限を持つ
ServiceAccount
- Backup for GKE(障害復旧用)
- Google Cloud Managed Service for Prometheus(クラスタ モニタリング用)
出力は次のようになります。
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...
Autopilot
次の図は、限定公開のリージョン GKE Autopilot クラスタを示しています。
このインフラストラクチャをデプロイするには、Cloud Shell から次のコマンドを実行します。
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
プロンプトが表示されたら、「yes
」と入力します。このコマンドが完了し、クラスタが準備完了ステータスになるまでに数分かかることがあります。
Terraform が次のリソースを作成します。
- Kubernetes ノードの VPC ネットワークとプライベート サブネット
- NAT 経由でインターネットにアクセスするためのルーター
us-central1
リージョンの限定公開 GKE クラスタ- ロギングとモニタリングの権限を持つ
ServiceAccount
- Google Cloud Managed Service for Prometheus(クラスタ モニタリング用)
出力は次のようになります。
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
...
クラスタに接続する
Cloud Shell を使用して、クラスタと通信するように kubectl
を構成します。
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION}
Spotahome オペレーターをクラスタにデプロイする
このセクションでは、Helm チャートを使用して Spotahome オペレーターを Kubernetes クラスタにデプロイしてから、Redis クラスタをデプロイします。
Spotahome Redis オペレーターの Helm チャート リポジトリを追加します。
helm repo add redis-operator https://spotahome.github.io/redis-operator
Spotahome オペレーターと Redis クラスタの Namespace を追加します。
kubectl create ns redis
Helm コマンドライン ツールを使用して Spotahome オペレーターをデプロイします。
helm install redis-operator redis-operator/redis-operator --version 3.2.9 -n redis
Helm を使用して Spotahome オペレーターのデプロイ ステータスを確認します。
helm ls -n redis
出力は次のようになります。
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION redis-operator redis 1 2023-09-12 13:21:48.179503 +0200 CEST deployed redis-operator-3.2.9 1.2.4
Redis をデプロイする
Redis クラスタ インスタンスの基本構成には、次のコンポーネントが含まれています。
- Redis ノードの 3 つのレプリカ: 1 つのリーダーと 2 つのリードレプリカ。
- クォーラムを形成する Sentinel ノードの 3 つのレプリカ。
- 1 個の CPU リクエストと 2 個の CPU 上限の CPU リソース割り当て(Redis の場合は 4 GB のメモリ リクエストと上限、Sentinel の場合は 100 m / 500 m の CPU と 500 MB)。
- toleration、
nodeAffinities
、topologySpreadConstraints
は各ワークロードに構成され、それぞれのノードプールと異なるアベイラビリティ ゾーンを利用して Kubernetes ノード間で適切に分散されます。
この構成は、本番環境に対応した Redis クラスタの作成に必要な最小限の設定を表しています。
基本的な Redis クラスタを作成する
ユーザー認証情報で Secret を作成します。
export PASSWORD=$(openssl rand -base64 12) kubectl create secret generic my-user -n redis \ --from-literal=password="$PASSWORD"
オペレーターには認証情報を生成する機能がないため、データベースのパスワードを事前に生成する必要があります。
基本構成を使用して新しい Redis クラスタを作成します。
kubectl apply -n redis -f manifests/01-basic-cluster/my-cluster.yaml
このコマンドは、CPU、メモリ リクエスト、上限を指定する Spotahome オペレーターの
RedisFailover
カスタム リソース、さらに、プロビジョニングされた Pod レプリカを Kubernetes ノードに分散するための taint とアフィニティを作成します。Kubernetes が必要なワークロードを開始するまで数分待ちます。
kubectl wait pods -l redisfailovers.databases.spotahome.com/name=my-cluster --for condition=Ready --timeout=300s -n redis
Redis ワークロードが作成されたことを確認します。
kubectl get pod,svc,statefulset,deploy,pdb -n redis
出力は次のようになります。
NAME READY STATUS RESTARTS AGE pod/redis-operator-5dc65cb7cc-krlcs 1/1 Running 0 49m pod/rfr-my-cluster-0 2/2 Running 0 60s pod/rfr-my-cluster-1 2/2 Running 0 60s pod/rfr-my-cluster-2 2/2 Running 0 60s pod/rfs-my-cluster-8475dfd96c-h5zvw 1/1 Running 0 60s pod/rfs-my-cluster-8475dfd96c-rmh6f 1/1 Running 0 60s pod/rfs-my-cluster-8475dfd96c-shzxh 1/1 Running 0 60s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/redis-my-cluster ClusterIP 10.52.14.87 <none> 6389/TCP 55s service/redis-operator ClusterIP 10.52.13.217 <none> 9710/TCP 49m service/rfr-my-cluster ClusterIP None <none> 9121/TCP 61s service/rfs-my-cluster ClusterIP 10.52.15.197 <none> 26379/TCP 61s NAME READY AGE statefulset.apps/rfr-my-cluster 3/3 61s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/redis-operator 1/1 1 1 50m deployment.apps/rfs-my-cluster 3/3 3 3 62s NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE poddisruptionbudget.policy/rfr-my-cluster 2 N/A 1 64s poddisruptionbudget.policy/rfs-my-cluster 2 N/A 1 63s
オペレーターが次のリソースを作成します。
- Redis StatefulSet と Sentinel Deployment
- Redis の 3 つの Pod レプリカ
- Sentinel の 3 つの Pod レプリカ
- 2 つの
PodDisruptionBudgets
。クラスタの整合性のために 2 つ以上の利用可能なレプリカを確保します。 rfr-my-cluster
Service。Redis の指標を公開します。- Redis クラスタのリーダーノードを対象とする
redis-my-cluster
Service - クライアントが Sentinels を通じてクラスタに接続できる
rfs-my-cluster
サービス。クライアント ライブラリには Sentinel サポートが必要です。
Redis 認証情報を共有する
Spotahome オペレーターの従来の認証方法を使用して、Redis 認証情報をクライアントと共有できます。
requirepass
設定を使用してデータベースのパスワードを使用する必要があります。このパスワードは、すべてのクライアントで使用されます。追加のユーザーを管理するには、Redis CLI コマンドを使用します。
apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
name: my-cluster
spec:
...
auth:
secretPath: my-user
この方法で Redis 認証情報をクライアントと共有する場合は、次の制限があります。
- Spotahome では、ユーザー管理用のカスタム リソースは提供されません。認証情報を Secret に保存し、
auth
仕様でそれらを参照できます。 - カスタム リソースを使用して TLS 暗号化で接続を保護する方法はありません。
- 認証情報のライブ更新はサポートされていません。
Redis に接続する
Redis クライアントをデプロイし、Kubernetes Secret に保存されているパスワードを使用して認証を行います。
クライアント Pod を実行して Redis クラスタとやり取りします。
kubectl apply -n redis -f manifests/02-auth/client-pod.yaml
PASS
環境変数は、Vault からmy-user
Secret を取得します。Pod の準備ができるまで待ってから、それに接続します。
kubectl wait pod redis-client --for=condition=Ready --timeout=300s -n redis kubectl exec -it redis-client -n redis -- /bin/bash
接続が機能することを確認します。
redis-cli -h redis-my-cluster -a $PASS --no-auth-warning SET my-key "testvalue"
出力は次のようになります。
OK
my-key
値を取得します。redis-cli -h redis-my-cluster -a $PASS --no-auth-warning GET my-key
出力は次のようになります。
"testvalue"
Pod のシェルを終了します。
exit
Prometheus が Redis クラスタの指標を収集する仕組み
次の図は、Prometheus が指標を収集する仕組みを示しています。
この図では、GKE 限定公開クラスタに次のものが存在します。
- パス
/
とポート9121
の指標を収集する Redis Pod - Redis Pod からの指標を処理する Prometheus ベースのコレクタ
- Cloud Monitoring に指標を送信する PodMonitoring リソース
Google Cloud Managed Service for Prometheus は、Prometheus 形式での指標の収集をサポートしています。Cloud Monitoring は、Redis 指標に対して統合ダッシュボードを使用します。
Spotahome オペレーターは、redis_exporter をサイドカーとして使用し、Prometheus 形式でクラスタ指標を公開します。
labelSelector で指標を収集する PodMonitoring リソースを作成します。
kubectl apply -n redis -f manifests/03-prometheus-metrics/pod-monitoring.yaml
Google Cloud コンソールで、GKE クラスタのダッシュボード ページに移動します。
ダッシュボードにゼロ以外の指標の取り込み率が表示されます。
Google Cloud コンソールで [ダッシュボード] ページに移動します。
Redis Prometheus の概要ダッシュボードを開きます。ダッシュボードには、接続数とキーが表示されます。ダッシュボードの自動プロビジョニングには数分かかる場合があります。
クライアント Pod に接続し、変数を準備します。
kubectl exec -it redis-client -n redis -- /bin/bash
redis-cli
ツールを使用して新しい鍵を作成します。for i in {1..50}; do \ redis-cli -h redis-my-cluster -a $PASS \ --no-auth-warning SET mykey-$i "myvalue-$i"; \ done
ページを更新し、コマンド/秒と鍵のグラフが更新されて実際のデータベース状態が表示されていることを確認します。
Pod のシェルを終了します。
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) terraform -chdir=terraform/FOLDER destroy -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
FOLDER
は、gke-autopilot
またはgke-standard
に置き換えます。プロンプトが表示されたら、「
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
次のステップ
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。