基于Nginx Ingress Controller的Kubernetes多域名路由实战指南

在微服务架构盛行的今天,单个Kubernetes集群往往需要承载数十甚至上百个服务。如何优雅地对外暴露这些服务,同时保证路由规则的清晰可维护,成为每个K8s运维人员必须面对的挑战。本文将深入探讨如何利用Nginx Ingress Controller实现精细化的多域名、多路径路由管理,彻底告别"一个host走天下"的初级配置模式。

1. 生产级Ingress架构设计原则

在开始具体配置前,我们需要建立正确的架构认知。与简单的单域名配置不同,生产环境中的Ingress需要遵循几个核心原则:

  • 领域驱动设计:按照业务功能而非技术层级划分域名。例如电商系统可能包含:

    • shop.example.com - 面向消费者的购物门户
    • api.example.com - 后端REST API服务
    • admin.example.com - 内部管理系统
  • 环境隔离:通过不同子域名区分环境,如:

    • dev.api.example.com - 开发环境
    • staging.api.example.com - 预发环境
    • api.example.com - 生产环境
  • 版本控制:在路径中体现API版本,例如:

    paths:
    - path: /v1/products
      backend: service-v1
    - path: /v2/products  
      backend: service-v2
    

以下是一个典型的多域名Ingress资源结构示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-domain-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
  - hosts:
    - shop.example.com
    - api.example.com
    secretName: example-tls
  rules:
  - host: shop.example.com
    http:
      paths:
      - path: /static(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: static-service
            port: 80
  - host: api.example.com
    http:
      paths:
      - path: /v1(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port: 8080

2. 高级路由配置技巧

2.1 路径重写与正则匹配

Nginx Ingress提供了强大的路径重写能力,这是处理微服务路由的关键。考虑以下场景:前端应用需要访问/api路径,而后端服务实际部署在/backend-service路径下。

annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /$2
  nginx.ingress.kubernetes.io/use-regex: "true"
rules:
- host: app.example.com
  http:
    paths:
    - path: /api(/|$)(.*)
      pathType: Prefix
      backend:
        service:
          name: backend-service
          port: 8080

注意:启用正则表达式会增加Nginx配置复杂度,建议仅在必要时使用

2.2 基于Header的路由

在某些场景下,我们需要根据请求头信息进行路由。例如实现A/B测试:

annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-header: "X-Experiment-Version"
  nginx.ingress.kubernetes.io/canary-by-header-value: "v2"

对应的Ingress规则:

- host: app.example.com
  http:
    paths:
    - path: /
      backend:
        service:
          name: main-service
          port: 80
    - path: /
      backend:
        service:
          name: experiment-service
          port: 80

2.3 流量切分与灰度发布

通过权重配置实现渐进式发布:

annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "30"

3. TLS证书管理最佳实践

多域名环境下的证书管理是个复杂问题。我们有以下几种方案可选:

方案 优点 缺点 适用场景
单个通配符证书 管理简单 安全风险集中 子域名较少且可控
多证书合并 灵活度高 更新维护复杂 域名来源多样
Let's Encrypt自动续期 自动化程度高 有速率限制 公开服务

推荐使用Cert-Manager实现自动化证书管理:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - selector:
        dnsZones:
          - "example.com"
      dns01:
        route53:
          region: us-west-2
          hostedZoneID: Z1PA6795UKMFR9

4. 性能优化与监控

4.1 Ingress Controller调优

修改Nginx Ingress的ConfigMap提升性能:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  keep-alive: "75"
  keep-alive-requests: "10000"
  upstream-keepalive-connections: "1000"
  upstream-keepalive-timeout: "60"
  upstream-keepalive-requests: "10000"

4.2 监控指标收集

通过Prometheus监控关键指标:

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "10254"

重要监控指标包括:

  • nginx_ingress_controller_requests - 请求量统计
  • nginx_ingress_controller_request_duration_seconds - 请求延迟
  • nginx_ingress_controller_nginx_process_connections - Nginx连接数

4.3 日志分析配置

结构化日志输出配置示例:

data:
  log-format-upstream: '{"time": "$time_iso8601", "remote_addr": "$remote_addr",
    "x-forward-for": "$http_x_forwarded_for", "request_id": "$req_id", "remote_user":
    "$remote_user", "bytes_sent": $bytes_sent, "request_time": $request_time, "status":
    $status, "vhost": "$host", "request_proto": "$server_protocol", "path": "$uri",
    "request_query": "$args", "request_length": $request_length, "duration": $request_time,
    "method": "$request_method", "http_referrer": "$http_referer", "http_user_agent":
    "$http_user_agent"}'

5. 疑难问题排查指南

5.1 常见错误与解决方案

错误现象 可能原因 解决方案
503 Service Unavailable 后端服务无可用Endpoint 检查Service selector与Pod标签匹配
404 Not Found 路径配置错误 检查Ingress path与后端服务路径
证书警告 证书过期或域名不匹配 检查Secret中的证书有效期和域名

5.2 诊断命令大全

获取Ingress详细状态:

kubectl describe ingress <ingress-name>

查看Nginx实际配置:

kubectl exec -n ingress-nginx <ingress-pod> -- cat /etc/nginx/nginx.conf

实时监控日志:

kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=100 -f

5.3 性能问题排查流程

  1. 检查Ingress Controller资源使用率
  2. 分析Nginx worker进程状态
  3. 检查后端服务响应时间
  4. 评估网络延迟情况
  5. 检查keepalive配置是否合理

更多推荐