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 클러스터와 함께 리더 노드와 2개의 읽기 복제본을 사용해서 GKE에 고가용성 Redis 클러스터를 배포 및 구성합니다.
Redis Sentinel은 오픈소스 Redis를 위한 고가용성 모니터링 시스템입니다. 리더 및 연결된 복제본을 포함하여 Redis 인스턴스를 지속적으로 모니터링합니다. 리더 노드가 실패하면 Sentinel이 복제본 중 하나를 새 리더로 자동 승격하여 작동하는 리더 노드를 데이터 읽기 및 쓰기에 항상 사용할 수 있도록 보장합니다. 리더 장애 또는 장애 조치 이벤트와 같은 중요한 이벤트가 Redis 클러스터에서 발생할 때 Sentinel은 이메일 또는 기타 알림 메커니즘을 통해 관리자 또는 다른 시스템에 알림을 제공할 수 있습니다.
또한 여러 가용성 영역에 분산된 Kubernetes 노드와 함께 Redis를 위한 고가용성 리전 GKE 클러스터를 배포합니다. 이 설정은 내결함성, 확장성, 지리적 중복성을 보장하는 데 도움이 됩니다. 업타임 및 가용성을 위한 SLA를 제공하면서 순차적 업데이트 및 유지보수를 가능하게 해줍니다. 자세한 내용은 리전 클러스터를 참조하세요.
다음 다이어그램은 여러 노드 및 GKE 클러스터의 영역에서 Redis 클러스터가 실행되는 방식을 보여줍니다.
다이어그램에서 Redis StatefulSet는 서로 다른 3개 영역의 노드 3개에 배포되어 있습니다. RedisFailover
커스텀 리소스 사양에 포드 어피니티 및 토폴로지 분산 규칙을 설정하여 GKE가 노드 및 영역에 StatefulSet를 배포하는 방식을 제어합니다.
한 영역에 장애가 발생하면 GKE가 권장 구성을 사용해서 새 노드에 포드를 다시 예약합니다.
다음 다이어그램은 서로 다른 3개 영역에 있는 3개 노드에 걸쳐서 예약된 Sentinel 배포를 보여줍니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 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: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 클러스터를 사용하여 연산자를 설치할 수 있습니다.
표준
다음 다이어그램에서는 서로 다른 영역 3개에 배포된 비공개 리전 Standard GKE 클러스터를 보여줍니다.
이 인프라를 배포하려면 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
다음 다이어그램에서는 비공개 리전 Autopilot GKE 클러스터를 보여줍니다.
인프라를 배포하려면 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 차트를 사용해서 Kubernetes 클러스터에 Spotahome 연산자를 배포한 후 Redis 클러스터를 배포합니다.
Spotahome Redis 연산자 Helm 차트 저장소를 추가합니다.
helm repo add redis-operator https://spotahome.github.io/redis-operator
Spotahome 연산자 및 Redis 클러스터의 네임스페이스를 추가합니다.
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개
- CPU 요청 1개 및 CPU 한도 2개의 CPU 리소스 할당(Redis의 경우 4GB 메모리 요청 및 한도 지원, Sentinel의 경우 100m/500m CPU 및 500MB 지원)
- Kubernetes 노드 간 적절한 배포를 보장하고 해당 노드 풀 및 서로 다른 가용성 영역을 활용하는 각 워크로드에 구성된 톨러레이션(toleration),
nodeAffinities
,topologySpreadConstraints
이 구성은 프로덕션에 사용 가능한 Redis 클러스터를 만드는 데 필요한 최소 설정을 나타냅니다.
기본 Redis 클러스터 만들기
사용자 인증 정보로 보안 비밀을 만듭니다.
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
커스텀 리소스를 만들고, 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 배포
- Redis용 포드 복제본 3개
- Sentinel용 포드 복제본 3개
- 클러스터 일관성을 위해 복제본 2개의 최소 가용성을 보장하는
PodDisruptionBudgets
2개 - Redis 측정항목을 노출하는
rfr-my-cluster
서비스 - Redis 클러스터 리더 노드를 대상으로 하는
redis-my-cluster
서비스 - 클라이언트가 Sentinel을 통해 클러스터에 연결할 수 있게 해주는
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은 사용자 관리를 위한 커스텀 리소스를 제공하지 않습니다. 보안 비밀에 사용자 인증 정보를 저장하고
auth
사양에서 이를 참조할 수 있습니다. - 커스텀 리소스를 사용하여 TLS 암호화로 연결을 보호할 수 있는 방법이 없습니다.
- 사용자 인증 정보의 실시간 업데이트가 지원되지 않습니다.
Redis에 연결
Redis 클라이언트를 배포하고 Kubernetes 보안 비밀에 저장된 비밀번호를 사용하여 인증할 수 있습니다.
클라이언트 포드를 실행하여 Redis 클러스터와 상호 작용합니다.
kubectl apply -n redis -f manifests/02-auth/client-pod.yaml
PASS
환경 변수는 저장소에서my-user
보안 비밀을 가져옵니다.포드가 준비될 때까지 기다린 후 연결합니다.
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"
포드 셸을 종료합니다.
exit
Prometheus가 Redis 클러스터에 대해 측정항목을 수집하는 방법 이해
다음 다이어그램은 Prometheus 측정항목 수집의 작동 방식을 보여줍니다.
다이어그램에서 GKE 비공개 클러스터에는 다음이 포함됩니다.
/
경로 및9121
포트로 측정항목을 수집하는 Redis 포드- Redis 포드의 측정항목을 처리하는 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 클러스터 대시보드 페이지로 이동합니다.
대시보드에 0이 아닌 측정항목 수집 비율이 표시됩니다.
Google Cloud 콘솔에서 대시보드 페이지로 이동합니다.
Redis Prometheus 개요 대시보드를 엽니다. 대시보드에 연결 및 키의 양이 표시됩니다. 대시보드가 자동 프로비저닝되는 데 몇 분 정도 걸릴 수 있습니다.
클라이언트 포드에 연결하고 변수를 준비합니다.
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
페이지를 새로고침하고 초당 명령어 및 키 그래프가 실제 데이터베이스 상태를 표시하도록 업데이트되었는지 확인합니다.
포드 셸을 종료합니다.
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 아키텍처 센터를 살펴보세요.