如何基于 Nginx 控制器搭建 Kubernetes Ingress?

来源:Vuejs教程作者:广州GEO公司头衔:草根站长
导读:本期聚焦于广州GEO公司创作的《如何基于 Nginx 控制器搭建 Kubernetes Ingress?》,敬请观看详情。在 Kubernetes 集群中,仅靠 NodePort 或 LoadBalancer 暴露服务会面临端口分散、缺乏统一流量入口、难以实现基于域名和路径的路由等问题。Ingress 资源定义了七层转发规则,但真正执行这些规则的是 Ingress 控制器。Nginx 控制器,即社区维护的 ingress-nginx,会把 Ingress 对象中的 host 和 path 规则转换成 Nginx 的 server 和 location 配置,并通过监听 API Server 的变化动态重载。本文从 Ingress 的工作机制出发,介绍如何通过 Helm 或清单文件部署 ingress-nginx 控制器,随后给出多服务路径路由、路径重写、TLS 证书配置等常见场景的完整 YAML 示例,并说明各注解的含义。最后针对部署后容易出现的后端不可达、证书错误等问题提供排查思路,帮助读者顺利完成从安装到生产使用的落地。

Kubernetes 将服务暴露给外部访问时,NodePort 方式需要为每个 Service 分配独立端口,LoadBalancer 又依赖云厂商且成本较高,而 Ingress 提供了统一的七层入口和基于域名、路径的流量分发能力。不过,Ingress 资源本身只是一组路由规则,真正解析并执行这些规则的是 Ingress 控制器。在众多实现中,基于 Nginx 的 ingress-nginx 控制器使用广泛、配置灵活,适合作为集群入口的首选方案。本文围绕它的部署与配置展开,帮助读者快速构建一个可用的 Kubernetes Ingress。

如何基于 Nginx 控制器搭建 Kubernetes Ingress?

一、Ingress 与 Nginx 控制器的协作原理

Kubernetes 中的 Ingress 资源定义了从集群外部访问内部 Service 的一组 HTTP 或 HTTPS 路由规则,例如将访问 api.ippipp.com 的请求转发到后端 api 服务,将 shop.ippipp.com 的请求转发到 shop 服务。这些规则不会直接被 kube-proxy 或 kubelet 处理,而是由 Ingress 控制器读取。控制器通常以 Pod 形式部署在集群中,通过 watch 机制监听 Ingress、Service、Endpoints 等资源的变化。

ingress-nginx 控制器内部运行着一个定制化的 Nginx 进程。当用户创建或修改 Ingress 对象时,控制器会从 API Server 获取最新的规则,生成对应的 nginx.conf 配置文件,然后执行 Nginx 的平滑重载,使新配置生效。这个过程的延迟通常很短,但对频繁变更的大规模集群来说,重载频率是需要关注的性能点。控制器还会根据 Service 对应的 Endpoints 动态更新 upstream 服务器列表,从而避免请求被转发到已经终止的 Pod。

从数据流角度看,外部请求首先到达控制器所在的节点或负载均衡器,Nginx 根据请求的 Host 头和 URL 路径匹配 Ingress 规则,选择对应的后端 Service,再通过 Service 的 ClusterIP 或直接通过 Pod IP 进行转发。默认情况下,ingress-nginx 会使用 Service 的 ClusterIP 作为代理目标,但部分配置下也会直接连接 Pod,以绕过 kube-proxy 的额外转发。

二、安装与部署 ingress-nginx 控制器

部署 ingress-nginx 有多种方式,最直接的是使用官方维护的 YAML 清单,一条命令即可完成安装。对于需要自定义镜像仓库、副本数、资源限制或启用监控等场景,推荐使用 Helm Chart。以下示例采用 Helm 方式,因为它便于后续升级和参数管理。

首先添加 ingress-nginx 的 Helm 仓库并更新索引,然后创建一个独立的命名空间,最后安装控制器。执行命令如下:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
kubectl create namespace ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx

安装完成后,可以查看控制器 Pod 是否正常运行:

kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

在云环境中,Service 通常会自动获得一个 LoadBalancer 类型的公网或内网地址。在裸金属或本地集群中,可以使用 NodePort 方式或通过 MetalLB 提供负载均衡地址。对于 NodePort 方式,控制器 Service 会暴露一个高位端口,访问时需要使用该端口,生产环境一般会在前面再挂一层硬件或软件负载均衡器。如果使用 kubectl apply 方式安装,可以执行官方仓库中的 deploy.yaml 文件,但需要留意版本与 Kubernetes 集群的兼容性。

三、编写 Ingress 资源实现路由转发

部署好控制器后,就可以创建 Ingress 资源来定义转发规则。假设集群中已经有两个服务:一个名为 web-service,负责前端页面;另一个名为 api-service,负责 REST 接口。我们希望将 ippipp.com 的根路径 / 转发到 web-service,将 /api 路径转发到 api-service。对应的 YAML 如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: default
spec:
  ingressClassName: nginx
  rules:
    - host: ippipp.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

这里的 ingressClassName 字段很重要,它指定由哪个 Ingress 控制器处理该资源。在较新的 Kubernetes 版本中,如果集群中存在多个控制器,必须通过该字段显式声明。pathType 控制路径匹配方式,Prefix 表示前缀匹配,例如 /api 会匹配 /api、/api/v1、/api/v1/users 等路径;Exact 表示精确匹配;ImplementationSpecific 则由具体控制器决定匹配逻辑,通常不推荐在跨控制器场景中使用。

创建该 Ingress 后,可以通过 kubectl describe ingress 查看规则是否被正确解析,也可以通过访问 ippipp.com/api/v1/health 验证请求是否到达 api-service。如果后端 Service 的端口是命名端口,在 YAML 中也可以使用 port.name 字段替代数字端口,但需要确保 Service 定义中存在对应名称。

四、进阶配置:TLS、路径重写与常用注解

生产环境通常需要启用 HTTPS,Kubernetes 通过 Secret 保存 TLS 证书和私钥,然后在 Ingress 的 tls 字段中引用。先使用 kubectl create secret tls 命令创建 Secret,再修改 Ingress 配置。示例:

kubectl create secret tls example-tls --cert=server.crt --key=server.key -n default
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: default
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - ippipp.com
      secretName: example-tls
  rules:
    - host: ippipp.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

路径重写是另一个常见需求。例如后端服务期望的路径不包含 /api 前缀,而我们对外暴露为 /api。可以通过注解 nginx.ingress.kubernetes.io/rewrite-target 实现。以下配置会把 /api/users 重写为 /users 后再转发给后端:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
    - host: ippipp.com
      http:
        paths:
          - path: /api(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: api-service
                port:
                  number: 8080

这里使用了正则捕获组,/api(/|$)(.*) 会匹配以 /api 开头的路径,并将 /api 之后的部分作为第二个捕获组,重写目标 /$2 表示只保留后面的路径。需要注意 pathType 必须设为 ImplementationSpecific,因为正则匹配不属于 Prefix 或 Exact。除了重写,ingress-nginx 还支持大量注解,例如 nginx.ingress.kubernetes.io/ssl-redirect 控制 HTTP 跳转 HTTPS,nginx.ingress.kubernetes.io/proxy-body-size 设置上传文件大小限制,nginx.ingress.kubernetes.io/cors-enable 开启跨域支持等。使用注解时,建议查阅对应版本的 ingress-nginx 文档,避免因版本差异导致注解无效。

五、常见问题与排障思路

Ingress 配置不生效时,首先应确认控制器是否正常运行。使用 kubectl get pods -n ingress-nginx 查看 Pod 状态,如果 Pod 未就绪或反复重启,可以通过 kubectl logs -n ingress-nginx deployment/ingress-nginx-controller 查看日志。常见原因包括镜像拉取失败、资源不足或与 API Server 的连接异常。

其次,检查 Ingress 对象是否被控制器正确加载。执行 kubectl describe ingress app-ingress,如果 Address 字段为空,可能说明控制器没有成功分配入口地址,或者 Service 类型不支持 LoadBalancer。此时应查看 Service 的状态,确认 external-ip 或 NodePort 是否正常分配。同时确认 Ingress 中指定的 ingressClassName 与实际部署的控制器名称一致,否则规则会被忽略。

请求返回 503 或 502 通常表示后端服务不可达。需要检查后端 Service 是否存在、端口是否正确,以及对应的 Endpoints 是否有就绪的 Pod。使用 kubectl get endpoints 查看地址列表,如果为空,说明 Service 的选择器没有匹配到任何 Pod,或者 Pod 就绪探针未通过。TLS 相关错误则要检查 Secret 是否存在于同一命名空间,证书和私钥是否匹配,以及域名是否与证书的 CN 或 SAN 一致。通过以上步骤,大多数 Ingress 问题都能定位到具体原因并进行修复。

Kubernetes IngressNginx 控制器Ingress 配置修改时间:2026-08-26 14:44:25

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。