You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

非云环境下Kubernetes Ingress Controller无LoadBalancer时的配置与访问问题求助

非云环境下Ingress-Nginx正常运行解决方案

嗨,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段内的地址。

步骤大概是:

  1. 用Helm或者YAML安装MetalLB到集群
  2. 配置MetalLB的IP地址池(指定一段集群内可用的、未被占用的IP范围)
  3. 重新部署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

火山引擎 最新活动