You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes公网节点IP的80/443端口暴露nginx-ingress服务?

嘿,我完全懂你的困扰——不想为每个集群额外开销云负载均衡器的成本,但又得把80、443这些标准端口直接对外,方便把域名A记录指向服务。既然你已经装了ingress-nginx,这里有几个实用的方案能解决你的问题:

方案1:给NodePort服务做主机端口转发(iptables)

如果已经用了NodePort类型的ingress-nginx-controller服务,你可以在集群的每个节点上设置iptables规则,把主机的80/443端口转发到NodePort对应的端口上。步骤如下:

  • 先找到你的ingress-nginx-controller的NodePort端口:
    kubectl get svc -n ingress-nginx
    
    假设输出里HTTP的NodePort是30080,HTTPS是30443
  • 在每个节点上执行以下命令(需要sudo权限):
    # 转发主机80端口到NodePort的HTTP端口
    sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 30080
    # 转发主机443端口到NodePort的HTTPS端口
    sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 30443
    
  • 注意:这种iptables规则重启节点后会消失,所以你需要做规则持久化。比如Debian/Ubuntu可以用netfilter-persistent服务,CentOS/RHEL可以用firewalld的规则保存命令。
方案2:直接使用HostPort部署ingress-nginx

这种方式让ingress-nginx的Pod直接绑定节点的80和443端口,不需要额外的NodePort服务。操作步骤:

  • 编辑ingress-nginx-controller的Deployment:
    kubectl edit deployment -n ingress-nginx ingress-nginx-controller
    
  • 在容器的ports部分添加hostPort字段,修改后类似这样:
    ports:
      - name: http
        containerPort: 80
        hostPort: 80
        protocol: TCP
      - name: https
        containerPort: 443
        hostPort: 443
        protocol: TCP
    
  • 保存退出后,Deployment会滚动更新Pod。之后需要注意:
    • 确保节点上没有其他进程占用80/443端口(比如本地的Nginx、Apache)
    • 如果是多节点集群,建议给Pod添加节点亲和性,让它们只调度到特定节点,然后把域名A记录指向这些节点的IP
    • 小提示:HostPort在Kubernetes里不算最推荐的生产级方案,因为会限制Pod的调度灵活性,但对于小规模集群或测试环境非常好用。
方案3:用MetalLB实现裸机LoadBalancer(推荐生产环境)

如果你不想用云厂商的LoadBalancer,但又想要LoadBalancer类型服务的便利性,MetalLB是绝佳选择。它能在裸机或非云环境中提供LoadBalancer服务,支持二层(ARP广播)和BGP两种模式,适合不同规模的集群。

操作步骤大概是:

  1. 安装MetalLB:你可以从MetalLB的官方发布页面获取最新的部署清单,执行以下命令完成安装:
    kubectl apply -f <metallb-manifest-file-path>
    
  2. 配置地址池:创建一个ConfigMap,指定MetalLB可以分配的IP范围(这些IP要在集群所在的网络内,并且能被你的域名解析到):
    apiVersion: v1
    kind: ConfigMap
    metadata:
      namespace: metallb-system
      name: config
    data:
      config: |
        address-pools:
        - name: default
          protocol: layer2
          addresses:
          - 192.168.1.100-192.168.1.200 # 替换成你的可用IP段
    
    执行kubectl apply -f <configmap-file.yaml>应用配置。
  3. 把ingress-nginx-controller的服务类型改回LoadBalancer:
    kubectl patch svc -n ingress-nginx ingress-nginx-controller -p '{"spec":{"type":"LoadBalancer"}}'
    
  4. 等待几分钟,MetalLB会给服务分配一个外部IP,之后把域名A记录指向这个IP就可以了。

根据你的集群规模和使用场景选合适的方案就行——测试环境用方案1或2,生产环境优先方案3。

内容的提问来源于stack exchange,提问作者Rotareti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:33:51