Terraform配置中Ingress未在LoadBalancer中显示的问题排查
我用Terraform配置了Ingress和LoadBalancer,但在Kubernetes仪表盘中,预期的Ingress资源没显示在LoadBalancer上,已经确认标签和选择器没问题,我是Terraform和K8s新手,求帮忙找配置错误。
提供的Terraform代码:
module "cert_manager" { source = "terraform-iaac/cert-manager/kubernetes" cluster_issuer_email = "t@gmail.com" cluster_issuer_name = "cert-manager-global" cluster_issuer_private_key_secret_name = "cert-manager-private-key" create_namespace = false namespace_name = kubernetes_namespace.cmprimg.metadata[0].name } resource "kubernetes_ingress_v1" "my-app-ingress" { metadata { name = "ingress" namespace = kubernetes_namespace.cmprimg.metadata[0].name annotations = { "cert-manager.io/cluster-issuer" = module.cert_manager.cluster_issuer_name # "kubernetes.io/ingress.class" = "nginx" "nginx.ingress.kubernetes.io/ssl-redirect" = "true" # "nginx.ingress.kubernetes.io/ssl-passthrough" = "true" } labels = { "service" = "ingress-controller" } } wait_for_load_balancer = true spec { tls { hosts = [ "api.mywebsite.xyz" ] secret_name = module.cert_manager.cluster_issuer_private_key_name } ingress_class_name = "nginx" rule { host = "api.cmprimg.io" http { path { path = "/loader" backend { service { name = kubernetes_service.httploader_service.metadata[0].name port { name = kubernetes_service.httploader_service.spec[0].port[0].name } } } } } } } } resource "kubernetes_service" "ingress_loadbalancer" { metadata { name = "ingressservice" namespace = kubernetes_namespace.cmprimg.metadata[0].name labels = { service = "ingress-controller" } } spec { type = "LoadBalancer" selector = { app = "ingress" } port { app_protocol = "both" port = 443 # target_port = 443 name = kubernetes_service.http_service.spec[0].port[0].name } } }
问题截图:
错误点分析及修正方案
手动创建LoadBalancer服务完全多余
Ingress Controller(比如nginx-ingress)在安装时会自动创建自己的LoadBalancer服务,你手动写的kubernetes_service.ingress_loadbalancer完全没用,而且它的选择器app=ingress根本对应不到Ingress Controller的Pod(通常Ingress Controller Pod的标签是app=nginx-ingress或类似),直接删掉这个资源即可。Ingress的TLS配置错误
secret_name你填的是Cluster Issuer的私钥Secret,这不对。cert-manager会自动为你的Ingress生成证书Secret,你只需要指定一个自定义名字,比如api-mywebsite-tls,不要用Cluster Issuer的私钥。Ingress规则的Host与TLS Host不匹配
TLS配置里的host是api.mywebsite.xyz,但Ingress规则的host是api.cmprimg.io,两者必须一致,否则cert-manager无法签发证书,Ingress也无法正确匹配流量。可选补充:明确Path Type
K8s 1.21+版本要求Ingress的path必须指定path_type,建议加上path_type = "Prefix"(根据你的需求选择合适类型)。
修正后的Ingress代码示例
resource "kubernetes_ingress_v1" "my-app-ingress" { metadata { name = "ingress" namespace = kubernetes_namespace.cmprimg.metadata[0].name annotations = { "cert-manager.io/cluster-issuer" = module.cert_manager.cluster_issuer_name "nginx.ingress.kubernetes.io/ssl-redirect" = "true" } labels = { "service" = "ingress-controller" } } wait_for_load_balancer = true spec { tls { hosts = [ "api.cmprimg.io" ] # 和下面的rule host保持一致 secret_name = "api-cmprimg-tls" # 自定义证书Secret名字,cert-manager会自动创建 } ingress_class_name = "nginx" rule { host = "api.cmprimg.io" http { path { path = "/loader" path_type = "Prefix" # 明确指定路径类型 backend { service { name = kubernetes_service.httploader_service.metadata[0].name port { name = kubernetes_service.httploader_service.spec[0].port[0].name } } } } } } } }
另外,要确保你已经正确安装了nginx-ingress控制器,否则Ingress资源根本无法生效。
内容的提问来源于stack exchange,提问作者Dan

