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 暴露。

相关推荐
予枫的编程笔记1 小时前
【Docker高级篇】吃透容器编排:Swarm vs K8s 核心差异,为后续K8s学习打牢基础
docker·云原生·kubernetes·linux内核·容器编排·容器技术·运维技术
hrhcode3 小时前
【云原生】六.Kubernetes存储与配置管理:ConfigMap、Secret与持久化存储
云原生·kubernetes·k8s
@hdd11 小时前
RBAC 详解:基于角色的访问控制与集群安全
网络·云原生·容器·kubernetes
认真的薛薛12 小时前
6.k8s中Jobs-CronJobs-configmap-备份etcd
容器·kubernetes·etcd
志栋智能13 小时前
AI驱动的系统自动化巡检:重塑IT基石的智慧“守护神”
大数据·运维·人工智能·云原生·自动化
人间打气筒(Ada)16 小时前
Kubernetes核心技术-namespace & label
云原生·kubernetes·云计算·k8s·devops·namespace·label
小义_19 小时前
【Docker】知识八
linux·docker·云原生
开开心心_Every19 小时前
CDR版本转换工具,支持多版本互转免升级软件
linux·运维·服务器·云原生·edge·pdf·serverless
匀泪21 小时前
云原生(TOMCAT概述)
云原生·tomcat