非云环境下Kubernetes Ingress Controller无LoadBalancer时的配置与访问问题求助
嗨,Andrew!我来帮你搞定这个Ingress的问题~
首先,你遇到的情况很典型:在没有云厂商LoadBalancer支持的环境里,Ingress Controller的LoadBalancer类型Service会一直卡在<pending>状态,但其实它已经默认通过NodePort暴露了端口(就是你看到的80:30731/TCP)。访问出现404是因为Ingress规则是基于Host头匹配的,我们先解决这个眼前的问题,再给你几个长期的方案。
一、先解决404:正确携带Host头访问
你的test-ingress规则是匹配host: test.cluster.local的请求,所以访问时必须确保请求携带正确的Host头。试试这个命令:
curl -I http://<你的集群节点IP>:30731/ -H "Host: test.cluster.local"
如果返回200,说明Ingress规则已经生效了——之前的请求可能因为Host头传递的问题导致匹配失败。另外要确认你的本地机器已经把test.cluster.local映射到了集群节点IP(你已经做了这一步,没问题)。
二、长期方案:三种适合非云环境的暴露方式
1. 继续用默认NodePort(最简单,无需额外组件)
Ingress-nginx默认安装时,即使Service是LoadBalancer类型,也会自动分配NodePort,你不需要额外创建my-service3这个Service,直接用默认的30731/32413端口就行。
需要注意:
- 确保集群节点的30731、32413端口对外开放(防火墙/安全组要允许外部访问)
- 所有Ingress的Host都需要在客户端映射到集群节点IP,或者用内部DNS指向节点IP
2. 开启HostNetwork模式(直接用节点80/443端口)
如果不想用高位的NodePort,想直接用80/443端口访问,可以修改Ingress-nginx的Helm配置,开启HostNetwork:
先找到你的Helm release名称(用helm list -n dev查看),然后执行升级命令:
helm upgrade <你的release名称> ingress-nginx/ingress-nginx -n dev \ --set controller.hostNetwork=true \ --set controller.service.type=ClusterIP
这样Ingress Controller的Pod会直接使用节点的80和443端口,之后你就可以直接通过http://test.cluster.local/访问(只要域名映射到节点IP),不用带NodePort了。
⚠️ 注意:每个节点只能运行一个Ingress Controller Pod(因为端口冲突),所以要调整controller的副本数,或者设置节点调度策略避免冲突。
3. 部署MetalLB(模拟LoadBalancer,获取稳定外部IP)
如果想让Ingress Controller的Service拿到稳定的外部IP,推荐部署MetalLB——它是专门给非云环境提供LoadBalancer实现的组件,可以给Service分配你指定的IP段内的地址。
步骤大概是:
- 用Helm或者YAML安装MetalLB到集群
- 配置MetalLB的IP地址池(指定一段集群内可用的、未被占用的IP范围)
- 重新部署Ingress-nginx的Service为LoadBalancer类型,MetalLB会自动分配IP给它,之后你看
kubectl get ingress -A的时候,ADDRESS字段就会显示这个IP,直接用这个IP访问就行。
三、优化Ingress配置(避免版本兼容问题)
你的Ingress用的是extensions/v1beta1版本,这个版本在Kubernetes 1.22+已经被弃用了,建议换成networking.k8s.io/v1版本,并且指定IngressClass,确保和Ingress Controller正确关联:
修改后的test-ingress配置:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress namespace: dev spec: ingressClassName: nginx # 必须指定,和Ingress Controller的class对应 rules: - host: test.cluster.local http: paths: - path: / pathType: Prefix # v1版本要求必须指定pathType backend: service: name: hello-service port: number: 80
应用这个配置:
kubectl apply -f test-ingress.yaml -n dev
这样调整后,Ingress和Controller的匹配会更可靠,也能避免后续Kubernetes版本升级带来的兼容问题。
内容的提问来源于stack exchange,提问作者Andrew Kaa




