概要 #
前回、コントロールプレーンも公開しない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からの実際の読み書きまで確認できる