↓メインコンテンツへスキップ
  1. Blogs/

TerraformでGKEプライベートクラスタからMemorystore for Redisへ接続してみた

2 分
Terraform GoogleCloud GKE Redis
0222-nnn
著者
0222-nnn
猫が好き
目次
Terraform-GoogleCloud - この記事は連載の一部です
パート 24: この記事

概要
#

前回、コントロールプレーンも公開しないGKEプライベートクラスタと踏み台を作成しました。実際のアプリケーションでは、このクラスタからキャッシュやセッションストアへ接続する場面が多くあります。

Memorystore for RedisはVPCの外にあるマネージドサービスです。そのままではGKEのVPCから到達できません。Private Service Access(PSA)でVPCとサービス提供者側のネットワークをPeeringして、初めてPodから接続できます。

Terraformの基本操作と、前回のGKEプライベートクラスタ+踏み台構成は前提としています。

Redis Cluster(PSC接続)、Redisのレプリケーションや可用性設計は扱いません。これらは別記事で扱う予定です。

検証すること
#

  • Private Service AccessでGKE用VPCとRedisをPeeringできること
  • Memorystore for Redis(BASIC)を作成できること
  • PodからRedisへ実際に接続し、PING・SET・GETが成功すること(Instance作成の確認とは別)

前提環境
#

  • Google Cloud CLI、Terraform、Docker
  • Billingが有効な検証用Google Cloud Project
  • GKE、Compute Engine、IAM、Memorystoreを操作できるGoogleアカウント
  • 検証時のバージョン:Terraform 1.14.3、google 7.43.0

今回の構成
#

RedisはVPCの外にあるマネージドサービスです。Private Service AccessのPeering RangeとVPC Peering Connectionが、GKE用VPCとRedis側のネットワークをつなぐ経路です。

flowchart TB
    subgraph GCP["Google Cloud"]
        subgraph Project["Project"]
            subgraph Region["asia-northeast1"]
                subgraph VPC["VPC"]
                    subgraph GkeSubnet["GKE Subnet"]
                        Pod["Pod(redis-test)"]
                    end
                    PSA["PSA Peering Range
/24"] end end Redis["Memorystore for Redis
BASIC・authorized_network: GKE用VPC"] end end VPC -.->|"VPC Peering
servicenetworking.googleapis.com"| Redis Pod -->|"redis-cli
PING / SET / GET"| Redis

VPC Peeringが成立すると、authorized_networkに指定したVPC内のリソースはFirewall設定なしにRedisへ到達できます。

Podが接続するまでの流れは、次のとおりです。

sequenceDiagram
    participant Pod as Pod(redis-test)
    participant Redis as Memorystore for Redis

    Pod->>Redis: PING
    Redis-->>Pod: PONG
    Pod->>Redis: SET test-key "hello-from-pod"
    Redis-->>Pod: OK
    Pod->>Redis: GET test-key
    Redis-->>Pod: "hello-from-pod"

使用するTerraformコード
#

Private Service Access
#

resource "google_compute_global_address" "redis_psa_range" {
  name          = "${var.network_name}-redis-psa-range"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 24
  network       = google_compute_network.vpc.id
}

resource "google_service_networking_connection" "redis_psa" {
  network                 = google_compute_network.vpc.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.redis_psa_range.name]
}

Peering Rangeは、GKE用Subnet(10.40.0.0/24)やコントロールプレーンのCIDR(172.16.4.0/28)と重複しない/24を新たに確保します。このRangeをservicenetworking.googleapis.comとPeeringし、Google管理側のネットワークへの経路を作ります。

Memorystore for Redis
#

resource "google_redis_instance" "cache" {
  name               = "${var.cluster_name}-redis"
  region             = var.region
  tier               = "BASIC"
  memory_size_gb     = var.redis_memory_size_gb
  authorized_network = google_compute_network.vpc.id

  depends_on = [
    google_project_service.redis,
    google_service_networking_connection.redis_psa,
  ]
}

authorized_networkにGKE用VPCを指定するだけで、そのVPC内のリソースから到達できます。Redis側にFirewallの概念はなく、VPC Peeringが接続可否のすべてです。tier = "BASIC"はレプリカを持たない最小構成で、可用性が必要な場合はSTANDARD_HAを検討します。

設定と実行
#

cd Advanced-Examples/12-gke-bastion-redis-instance
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
iap_member = "user:you@example.com"
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply

前回のVPC・踏み台・GKEに加えてRedis関連のリソースが作成されます。合わせて30リソースです。GKE作成に約10分かかりました。

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

Outputs:

bastion_name = "tf-adv-gke-redis-vm"
cluster_name = "tf-adv-gke-redis"
redis_host = "10.38.41.83"
redis_port = 6379

Podから実際に接続できることを確認する
#

Redis Instanceが作成できたことと、Podから実際に接続できることは別です。テスト用Podをデプロイし、redis-cliでPING・SET・GETを実行します。

sed -e "s|__REDIS_HOST__|$(terraform output -raw redis_host)|" \
    -e "s|__REDIS_PORT__|$(terraform output -raw redis_port)|" \
  k8s/redis-test-deployment.yaml > /tmp/redis-test-deployment.yaml
gcloud compute scp /tmp/redis-test-deployment.yaml \
  "$(terraform output -raw bastion_name):/tmp/redis-test-deployment.yaml" \
  --zone="$(terraform output -raw zone)" --tunnel-through-iap \
  --project="$(terraform output -raw project_id)"
# 踏み台の中で実行
gcloud container clusters get-credentials "$(terraform output -raw cluster_name)" \
  --zone="$(terraform output -raw zone)" --project="$(terraform output -raw project_id)"
kubectl apply -f /tmp/redis-test-deployment.yaml
kubectl wait --for=condition=ready pod -l app=redis-test --timeout=90s
kubectl logs -l app=redis-test
Connecting to Redis at 10.38.41.83:6379 ...
PONG
OK
hello-from-pod
Redis test completed successfully.

PONG、OK、そして書き込んだhello-from-podがそのまま読み出せました。VPC Peering越しに、Podから実際にRedisへ読み書きできることを確認できました。

後片付け
#

terraform destroy
Destroy complete! Resources: 30 destroyed.

GKE ClusterとRedis Instanceは利用中に料金が発生します。検証後は必ずdestroyします。

まとめ
#

  • Private Service AccessでVPC外のマネージドサービスとPeeringできる
  • authorized_networkだけでRedisへの接続経路を用意できる
  • Instance作成の確認とは別に、Podからの実際の読み書きまで確認できる

参考資料
#

次回
#

この構成を土台に、Memorystore for Redis Cluster(PSC接続)を扱います。

Terraform-GoogleCloud - この記事は連載の一部です
パート 24: この記事

関連記事

TerraformでGKEプライベートクラスタからMemorystore for Redis Clusterへ接続してみた
3 分
Terraform GoogleCloud GKE Redis
TerraformでGKEプライベートクラスタと踏み台VMを作成してみた
3 分
Terraform GoogleCloud GKE IAP
TerraformでGKE Workload IdentityからCloud Storageへアクセスしてみた
2 分
Terraform GoogleCloud GKE WorkloadIdentity
Terraform StateをCloud Storage Remote Backendへ移行してみた
2 分
Terraform GoogleCloud CloudStorage
TerraformからGoogle Cloudへ接続してProject情報を取得してみた
3 分
Terraform GoogleCloud
TerraformでArtifact RegistryのDocker Repositoryを作成してみた
2 分
Terraform GoogleCloud Docker