Ingress 详解:HTTP 路由与外部流量管理

摘要:Ingress 提供 HTTP/HTTPS 层的路由能力,支持基于域名和路径的流量转发,是将集群内服务暴露到外部的标准方式。本文详解 Ingress Controller 选型、路由规则、pathType、TLS 配置、Annotations、Ingress Class、Gateway API 及常见问题排查。

一、为什么需要 Ingress?

使用 NodePort 或 LoadBalancer 时,每个 Service 需要独立的负载均衡器和公网 IP,导致成本高、无法基于路径路由、TLS 需分别配置。Ingress 通过统一入口解决上述问题。
有 Ingress
app-a.com
Ingress
app-b.com
Service-A
Service-B
无 Ingress
app-a.com
LB-1
app-b.com
LB-2
Service-A
Service-B

上图为无 Ingress 与有 Ingress 的架构对比。无 Ingress 时每个域名对应一个 LoadBalancer;有 Ingress 后多个域名共享同一入口,由 Ingress 根据规则分发。

1.1 无 Ingress 的局限

  • 每个 Service 一个 LoadBalancer,对应一个公网 IP,云资源成本高
  • 无法基于 URL 路径路由(如 /api/admin
  • TLS 证书需在每个 Service 分别配置

1.2 Ingress 的优势

  • 统一入口,节省 LoadBalancer 成本
  • 支持基于域名和路径的灵活路由
  • 支持在入口层统一进行 TLS 终结

二、Ingress 架构

Ingress 定义 HTTP 路由规则,实际执行路由的是 Ingress Controller。流量经负载均衡器到达 Ingress Controller,由 Controller 按 Ingress 规则将请求转发到对应 Service 和 Pod。
互联网用户
Load Balancer
Ingress Controller
shop-svc
api-svc
admin-svc
Pod
Pod
Pod

Load Balancer 将流量转发到 Ingress Controller,Controller 根据 Ingress 规则(如 shop.example.com → shop-svc、api.example.com → api-svc)将请求路由到对应 Service。

重要概念 :Ingress 本身只是路由规则的定义 ,实际执行路由的是 Ingress Controller。使用 Ingress 前必须先安装并配置 Ingress Controller。

三、Ingress Controller 选型对比

Controller 特点 适用场景
Nginx Ingress Controller 使用广泛,功能全,Annotations 丰富 通用场景,需细粒度控制
Traefik 云原生设计,自动服务发现,配置简单 动态环境,快速部署
HAProxy Ingress 高性能,适合高流量 高并发、低延迟
云厂商 ALB / ELB 与云平台集成,自动创建 LB 云上生产环境
Istio Gateway 服务网格入口,功能多 已有服务网格

Ingress Controller 选型
Nginx Ingress
Traefik
HAProxy
云厂商 ALB

Nginx 和 Traefik 常用于通用场景;HAProxy 适合对性能要求高的场景;云上环境可考虑云厂商 ALB。

四、Ingress 规则配置

4.1 基于域名路由(host-based)

通过 host 字段将不同域名路由到不同 Service。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: shop.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: shop-svc
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 8080
字段 说明
spec.ingressClassName 指定 Ingress Controller,K8s 1.18+
spec.rules[].host 匹配的域名
spec.rules[].http.paths[].path URL 路径
spec.rules[].http.paths[].pathType Prefix / Exact / ImplementationSpecific
backend.service 转发的 Service 及端口

4.2 基于路径路由(path-based)

同一域名下,通过 path 将不同路径转发到不同 Service。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 8080
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: admin-svc
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-svc
            port:
              number: 80

/api 前缀到 api-svc,/admin 前缀到 admin-svc,根路径 / 到 frontend-svc。路径匹配顺序通常由 Ingress Controller 决定(多为最长前缀优先)。

4.3 pathType 区别

pathType 说明
Prefix 前缀匹配。/api 匹配 /api/api//api/users
Exact 精确匹配。/api 只匹配 /api,不匹配 /api/
ImplementationSpecific 由 Ingress Controller 自行实现

4.4 TLS 终止配置完整示例

在 Ingress 层配置 TLS 终结,可将 HTTPS 在入口处解密,内部使用 HTTP 访问后端。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls-secret
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80
字段 说明
spec.tls[].hosts 使用该证书的域名
spec.tls[].secretName 存放证书和私钥的 Secret 名称

创建 TLS Secret:

bash 复制代码
kubectl create secret tls app-tls-secret \
  --cert=tls.crt \
  --key=tls.key

HTTPS
TLS 终结
用户
Ingress Controller
HTTP
Pod

五、Annotations 常用配置

Nginx Ingress Controller 支持通过 Annotations 扩展行为:

Annotation 说明
nginx.ingress.kubernetes.io/ssl-redirect 强制 HTTPS 重定向
nginx.ingress.kubernetes.io/rewrite-target URL 重写
nginx.ingress.kubernetes.io/limit-rps 限流(每秒请求数)
nginx.ingress.kubernetes.io/proxy-body-size 上传大小限制
nginx.ingress.kubernetes.io/proxy-read-timeout 读超时
nginx.ingress.kubernetes.io/proxy-send-timeout 写超时
nginx.ingress.kubernetes.io/enable-cors 启用 CORS
nginx.ingress.kubernetes.io/custom-http-errors 自定义错误页
yaml 复制代码
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/limit-rps: "10"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/enable-cors: "true"

六、Ingress Class 机制

K8s 1.18+ 通过 IngressClass 资源区分不同 Ingress Controller,替代已废弃的 kubernetes.io/ingress.class Annotation。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

Ingress 通过 spec.ingressClassName: nginx 指定使用该 IngressClass。集群可存在多个 Ingress Controller,通过 IngressClass 路由到不同 Controller。

七、Gateway API 简介

Gateway API 是 Kubernetes 社区推荐的下一代 Ingress 规范,提供更丰富的路由与角色分离能力。

对比项 Ingress Gateway API
角色分离 支持集群管理员 / 应用开发者分离
高级路由 依赖 Annotations 标准化 Header 匹配、流量分割
协议支持 主要为 HTTP/HTTPS HTTP、gRPC、TCP、UDP

Gateway API
标准化路由
角色分离
跨协议支持
Ingress
规则定义
高级功能依赖 Annotations

八、实践与部署

8.1 安装 Nginx Ingress Controller

bash 复制代码
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

# 或使用 Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx

8.2 验证 Ingress 状态

bash 复制代码
kubectl get ingress
kubectl describe ingress <ingress-name>
kubectl get pods -n ingress-nginx

8.3 完整部署示例

yaml 复制代码
# 1. 部署后端应用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:alpine
        ports:
        - containerPort: 80
---
# 2. 创建 Service
apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  selector:
    app: web
  ports:
  - port: 80
---
# 3. 创建 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80

8.4 常见问题排查表

问题 排查方向
404 或路由不到后端 确认 Ingress Controller 已安装;检查 ingressClassName;核对 Service 名称与端口
TLS 证书错误 确认 Secret 类型为 kubernetes.io/tls;检查证书有效期
超时 调整 proxy-read-timeout、proxy-send-timeout
502 Bad Gateway 检查后端 Pod 是否就绪;检查 Service 的 endpoints

九、生产环境建议

  1. Ingress Controller 高可用:多副本部署,配合 PodDisruptionBudget
  2. TLS 证书:使用 cert-manager 自动签发 Let's Encrypt 证书
  3. 限流与防护:通过 Annotations 或 WAF 配置限流、防 DDoS
  4. 监控:监控 Ingress Controller 的请求量、延迟、错误率
  5. 资源限制:为 Ingress Controller 设置合理的 resources requests/limits

十、FAQ

Q1:Ingress 404 排查思路?

确认 Ingress Controller 已安装;检查 ingressClassName 是否与集群 IngressClass 一致;核对 Service 名称、端口与 selector;确认后端 Pod 就绪;查看 Ingress Controller 日志。

Q2:多 Ingress Controller 共存如何配置?

为每个 Controller 创建 IngressClass;创建 Ingress 时指定对应的 ingressClassName;不同 Controller 可监听不同端口或通过 LB 区分。

Q3:如何配置 HTTPS 重定向?

Nginx Ingress 设置 nginx.ingress.kubernetes.io/ssl-redirect: "true";同时配置 TLS 的 hosts 与 secretName。

Q4:502 Bad Gateway 如何排查?

检查后端 Pod 是否就绪;检查 Service 的 endpoints;确认 Pod 端口与 Service 端口一致;查看 Ingress Controller 日志。

十一、总结

Ingress 负责定义 HTTP 层路由规则,Ingress Controller 负责实际执行路由。核心能力包括:基于域名的路由、基于路径的路由、TLS 终结。使用前需先安装并配置 Ingress Controller,高级功能可通过 Annotations 或 Gateway API 实现。

能力 说明
域名路由 host 字段匹配
路径路由 path + pathType
TLS spec.tls 配置
扩展 Annotations / Gateway API

11.1 路由匹配优先级

多数 Ingress Controller 按以下优先级匹配:精确 host + 最长 path 优先。配置时注意将更具体的路径放在更通用的路径之前。

11.2 rewrite-target 使用示例

当后端应用期望的路径与外部路径不同时,可使用 rewrite-target:

yaml 复制代码
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-svc
            port:
              number: 8080

/api/users 会被重写为 /users 转发到后端。

11.3 多 Ingress Controller 共存

同一集群可部署多个 Ingress Controller,通过 IngressClass 区分。创建 Ingress 时指定 ingressClassName 即可路由到对应 Controller。不同 Controller 可监听不同 NodePort 或通过不同 LoadBalancer 暴露。

相关推荐
小二·14 分钟前
Go 语言系统编程与云原生开发实战(第34篇)
大数据·云原生·golang
小二·2 小时前
Go 语言系统编程与云原生开发实战(第35篇)
开发语言·云原生·golang
sanyii3131312 小时前
k8s工作负载-ReplicaSet控制器
java·git·kubernetes
自在极意功。2 小时前
k8s实战
云原生·容器·kubernetes
j200103223 小时前
K8s——安全机制
安全·容器·kubernetes
@土豆4 小时前
Kafka on Kubernetes 有状态应用部署文档(KRaft 模式)
分布式·kafka·kubernetes
码luffyliu4 小时前
K8s 核心知识点详解:Pod、NAT 与 Osim 隔离环境的实际应用
云原生·容器·kubernetes
十月南城5 小时前
电商案例复盘:从单体到微服务的取舍账本——以业务增长阶段为主线复盘架构演进与决策依据
微服务·云原生·架构
匀泪5 小时前
云原生(Mysql-MHA高可用集群)
mysql·云原生
Meta395 小时前
SpringBoot通过kt-connect+kubectl进行本地调试k8s服务
spring boot·后端·kubernetes