如何获取kubernetes_ingress_v1创建的负载均衡器后端名称?
问题场景
我正在用Terraform在GCP的GKE集群上复刻本地基础设施:已经创建了运行容器化应用的Pods并关联到Kubernetes Service,同时通过kubernetes_ingress_v1资源创建了外部HTTP负载均衡器(代码如下)。现在需要基于GCP的loadbalancing.googleapis.com/https/backend_request_count指标实现自动扩缩容,但该指标需要通过代理名称、转发规则名称、后端目标名称或后端名称来过滤特定负载均衡器,而kubernetes_ingress_v1资源无法直接提供这些字段。
resource "kubernetes_ingress_v1" "external" { wait_for_load_balancer = true metadata { name = "${var.mode}-quokka-ingress" namespace = "quokka" annotations = { "kubernetes.io/ingress.class" = "gce" "kubernetes.io/ingress.global-static-ip-name" = "${var.mode}-server" } } spec { rule { http { path { backend { service { name = "quokka-service" port { number = 8080 } } } path = "/*" } } } } }
解决方案
1. 通过静态IP关联查询转发规则
因为已经通过kubernetes.io/ingress.global-static-ip-name指定了全局静态IP,可以用这个IP名称查询对应的转发规则,进而获取关联的后端服务信息:
data "google_compute_forwarding_rule" "ingress_fwd_rule" { name = "${var.mode}-server" }
可通过data.google_compute_forwarding_rule.ingress_fwd_rule.target拿到后端服务的完整链接,拆分后得到后端服务名称;也可以直接用该数据源的name属性作为指标过滤条件。
2. 用标签过滤查询后端服务
GKE自动创建的负载均衡相关资源会带有标准化标签,比如kubernetes.io/cluster/<集群名>(值为owned)、app.kubernetes.io/name(关联你的Service名称)。利用这些标签可以精准查询到对应的后端服务:
data "google_compute_backend_service" "ingress_backend" { filter = "labels.kubernetes.io/cluster/${var.gke_cluster_name} = 'owned' AND labels.app.kubernetes.io/name = 'quokka-service'" }
查询到的data.google_compute_backend_service.ingress_backend.name就是需要的后端服务名称,可直接用于指标过滤。
3. 解析Ingress资源的状态字段
kubernetes_ingress_v1资源的status.load_balancer.ingress[0].ip会返回负载均衡的公网IP,结合这个IP可以查询对应的GCP资源:
data "google_compute_forwarding_rule" "ingress_by_ip" { filter = "IPAddress = '${kubernetes_ingress_v1.external.status.0.load_balancer.0.ingress.0.ip}'" }
这种方式适合没有提前指定静态IP的场景,但需要依赖wait_for_load_balancer = true等待Ingress完全创建完成。
4. 手动控制GCP资源命名(推荐)
如果业务允许,可以放弃GKE自动创建后端服务的逻辑,手动创建google_compute_backend_service和对应的BackendConfig,然后通过Ingress的annotations关联。这样可以直接控制资源名称,后续无需额外查询:
# 手动创建后端服务 resource "google_compute_backend_service" "quokka_backend" { name = "${var.mode}-quokka-backend" protocol = "HTTP" timeout_sec = 30 backend { group = google_container_node_pool.quokka_node_pool.instance_group_urls[0] } health_checks = [google_compute_http_health_check.quokka_health.self_link] } # 创建BackendConfig关联后端服务 resource "kubernetes_backend_config_v1" "quokka_backend_config" { metadata { name = "${var.mode}-quokka-backend-config" namespace = "quokka" } spec { health_check { check_interval_sec = 5 timeout_sec = 5 healthy_threshold = 2 unhealthy_threshold = 2 } } } # 修改Ingress的annotations关联BackendConfig resource "kubernetes_ingress_v1" "external" { wait_for_load_balancer = true metadata { name = "${var.mode}-quokka-ingress" namespace = "quokka" annotations = { "kubernetes.io/ingress.class" = "gce" "kubernetes.io/ingress.global-static-ip-name" = "${var.mode}-server" "cloud.google.com/backend-config" = "{\"default\": \"${kubernetes_backend_config_v1.quokka_backend_config.metadata.0.name}\"}" } } # ... 其他spec配置保持不变 }
之后直接用google_compute_backend_service.quokka_backend.name作为指标过滤条件即可。
内容的提问来源于stack exchange,提问作者Guilherme Viveiros

