Azure AKS中使用Terraform获取Nginx Ingress Controller负载均衡IP失败如何解决?
问题原因分析
这个不是AKS独有的已知限制,是Terraform Kubernetes Provider的通用行为,所有需要异步分配LB IP的K8s集群都会遇到相同问题,核心原因有两个:
- 你查询到为空的
load_balancer_ip字段,对应的是Service Spec中的spec.loadBalancerIP字段,也就是手动指定LB IP时才会填充的字段,而你通过kubectl拿到的IP存储在Service Status的status.loadBalancer.ingress[].ip字段,旧版本(<2.10.0)的Terraform Kubernetes Provider默认不会导出status字段下的负载均衡IP信息。 depends_on = [helm_release.ingress]只会保证helm release执行完成,不会等待AKS底层完成LB资源创建、IP分配并同步到Service Status的整个异步流程,查询时IP还未完成分配,自然拿不到结果。
可行解决方案(优先级从高到低)
- 方案1:升级Kubernetes Provider到2.10.0及以上版本
新版本已支持读取Service Status字段,获取IP的写法调整为:# 确保provider版本 >=2.10.0 data "kubernetes_service" "nginx_service" { metadata { name = "${local.ingress_name}-ingress-nginx-controller" namespace = local.ingress_ns } depends_on = [helm_release.ingress, time_sleep.wait_for_lb] } # 增加等待时间,确保IP分配完成,可根据实际情况调整时长 resource "time_sleep" "wait_for_lb" { create_duration = "90s" depends_on = [helm_release.ingress] } # 获取LB IP output "nginx_lb_ip" { value = data.kubernetes_service.nginx_service.status[0].load_balancer[0].ingress[0].ip } - 方案2:使用AzureRM Provider直接查询LB IP(AKS场景更稳定)
AKS创建的LoadBalancer类型Service对应的LB资源存放在AKS节点资源组(名称通常为MC_<集群资源组>_<集群名>_<区域>)中,可通过标签匹配直接查询Azure侧的IP资源,无需依赖K8s API:data "azurerm_lb" "nginx_lb" { name = "kubernetes-internal" # 公网LB默认名称为kubernetes resource_group_name = local.aks_node_resource_group depends_on = [helm_release.ingress] } data "azurerm_lb_frontend_ip_configuration" "nginx_lb_ip" { loadbalancer_id = data.azurerm_lb.nginx_lb.id name = "${local.ingress_name}-ingress-nginx-controller" # 和Service名称一致 } output "nginx_lb_ip" { value = data.azurerm_lb_frontend_ip_configuration.nginx_lb_ip.private_ip_address } - 方案3:local-exec方案(兜底可选)
仅在上述方案都不适用时使用,添加重试逻辑可以避免异步问题:resource "null_resource" "get_lb_ip" { provisioner "local-exec" { command = <<EOT until kubectl get svc ${local.ingress_name}-ingress-nginx-controller -n ${local.ingress_ns} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' > lb_ip.txt; do sleep 10 done EOT } depends_on = [helm_release.ingress] }
local-exec不是唯一选择,优先推荐前两种方案,更符合Terraform的声明式规范。
内容的提问来源于stack exchange,提问作者Gerb
相关产品推荐
相关产品推荐

