Skip to content

Ingress ​

概述 ​

Ingress 是 Kubernetes 中用于管理集群外部访问集群内服务的 API 对象,通常用于 HTTP 和 HTTPS 路由。它提供了负载均衡、SSL 终止和基于名称的虚拟主机等功能。

关键点内容
核心作用管理外部到集群内服务的 HTTP/HTTPS 访问
路由规则基于主机名和路径的路由
负载均衡七层负载均衡和流量分发
SSL/TLS支持 SSL 证书管理和 HTTPS 终止

Ingress 的本质 ​

设计理念 ​

  • 七层路由:在应用层(HTTP/HTTPS)进行流量路由
  • 统一入口:为多个服务提供统一的外部访问入口
  • 智能路由:基于域名、路径、请求头等进行路由决策
  • SSL 终止:在入口处处理 SSL/TLS 加密和解密

工作原理 ​

外部请求 → Ingress Controller → Ingress 规则匹配 → 后端 Service → Pod
    ↓              ↓                    ↓
  域名/路径     负载均衡器配置        路由规则

Ingress vs Service ​

特性ServiceIngress
网络层级四层(TCP/UDP)七层(HTTP/HTTPS)
路由能力端口路由域名、路径路由
SSL 支持需要应用处理原生支持 SSL 终止
负载均衡简单轮询高级负载均衡算法
成本每个服务一个 LoadBalancer多个服务共享一个入口

Ingress Controller ​

常见的 Ingress Controller ​

Controller特点适用场景
Nginx Ingress功能丰富,社区活跃通用场景,生产环境
Traefik自动服务发现,配置简单微服务架构,容器化环境
HAProxy Ingress高性能,企业级功能高并发,企业环境
Istio Gateway服务网格集成微服务治理,复杂路由
AWS ALB云原生,与 AWS 深度集成AWS 环境
GCE IngressGoogle Cloud 原生GCP 环境

Nginx Ingress Controller 安装 ​

bash
# 使用 Helm 安装
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx

# 或使用 kubectl 安装
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

基本配置 ​

简单的 HTTP Ingress ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

多路径路由 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-path-ingress
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /api/v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 80
      - path: /api/v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 80
      - path: /docs
        pathType: Prefix
        backend:
          service:
            name: docs-service
            port:
              number: 80

多域名路由 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  rules:
  - host: frontend.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 80

HTTPS 和 SSL 配置 ​

使用预定义证书 ​

yaml
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTi... # base64 编码的证书
  tls.key: LS0tLS1CRUdJTi... # base64 编码的私钥

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  tls:
  - hosts:
    - secure.example.com
    secretName: tls-secret
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-service
            port:
              number: 80

使用 cert-manager 自动证书 ​

yaml
# 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# ClusterIssuer 配置
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:
    - http01:
        ingress:
          class: nginx

---
# 自动证书 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auto-tls-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - auto.example.com
    secretName: auto-tls-secret
  rules:
  - host: auto.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

高级配置 ​

路径类型详解 ​

路径类型匹配规则示例
Exact精确匹配/api/v1 只匹配 /api/v1
Prefix前缀匹配/api 匹配 /api/v1, /api/users 等
ImplementationSpecific由 Ingress Controller 决定取决于具体实现
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-types-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api/v1/users
        pathType: Exact  # 精确匹配
        backend:
          service:
            name: users-service
            port:
              number: 80
      - path: /api
        pathType: Prefix  # 前缀匹配
        backend:
          service:
            name: api-service
            port:
              number: 80

重写和重定向 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    # URL 重写
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    # 永久重定向
    nginx.ingress.kubernetes.io/permanent-redirect: https://new.example.com
    # 临时重定向
    nginx.ingress.kubernetes.io/temporal-redirect: https://temp.example.com
    # 自定义重写
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

负载均衡配置 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: load-balancing-ingress
  annotations:
    # 负载均衡算法
    nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
    # 会话保持
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/affinity-mode: "persistent"
    nginx.ingress.kubernetes.io/session-cookie-name: "INGRESSCOOKIE"
    nginx.ingress.kubernetes.io/session-cookie-expires: "86400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "86400"
    # 权重分配
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

限流和安全 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: security-ingress
  annotations:
    # 限流配置
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
    nginx.ingress.kubernetes.io/rate-limit-connections: "10"
    
    # IP 白名单
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12"
    
    # 基本认证
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
    
    # CORS 配置
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent"
spec:
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-service
            port:
              number: 80

健康检查和超时 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: health-check-ingress
  annotations:
    # 后端健康检查
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/health-check-path: "/health"
    nginx.ingress.kubernetes.io/health-check-interval: "30s"
    
    # 超时配置
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    
    # 缓冲配置
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "4k"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

金丝雀部署 ​

基于权重的金丝雀部署 ​

yaml
# 生产版本 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: production-ingress
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-production
            port:
              number: 80

---
# 金丝雀版本 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-ingress
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"  # 10% 流量
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-canary
            port:
              number: 80

基于请求头的金丝雀部署 ​

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: header-canary-ingress
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "true"
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-canary
            port:
              number: 80

监控和调试 ​

常用命令 ​

bash
# 查看 Ingress 列表
kubectl get ingress

# 查看 Ingress 详细信息
kubectl describe ingress my-ingress

# 查看 Ingress Controller 日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# 查看 Ingress Controller 配置
kubectl get configmap -n ingress-nginx ingress-nginx-controller -o yaml

# 测试 Ingress 规则
curl -H "Host: example.com" http://<INGRESS_IP>/

调试技巧 ​

bash
# 查看 Nginx 配置
kubectl exec -n ingress-nginx <nginx-controller-pod> -- cat /etc/nginx/nginx.conf

# 实时查看访问日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f

# 检查证书状态
kubectl describe certificate <certificate-name>

# 验证 DNS 解析
nslookup example.com

# 测试 SSL 证书
openssl s_client -connect example.com:443 -servername example.com

故障排查 ​

常见问题 ​

问题可能原因解决方案
404 Not Found路径匹配错误检查 path 和 pathType 配置
502 Bad Gateway后端服务不可用检查 Service 和 Pod 状态
503 Service UnavailableIngress Controller 问题检查 Controller 状态和资源
SSL 证书错误证书配置问题检查 TLS Secret 和证书有效性
域名无法访问DNS 解析问题检查 DNS 配置和 Ingress IP

诊断步骤 ​

  1. 检查 Ingress 配置
bash
kubectl get ingress -o yaml
kubectl describe ingress my-ingress
  1. 检查后端服务
bash
kubectl get service
kubectl get endpoints
  1. 检查 Ingress Controller
bash
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
  1. 测试网络连通性
bash
# 直接测试服务
kubectl port-forward service/my-service 8080:80
curl http://localhost:8080

# 测试 Ingress
curl -H "Host: example.com" http://<INGRESS_IP>/

性能优化 ​

Nginx 配置优化 ​

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  # 工作进程数
  worker-processes: "auto"
  
  # 连接数限制
  max-worker-connections: "16384"
  
  # 缓冲区大小
  proxy-buffer-size: "16k"
  proxy-buffers-number: "8"
  
  # 压缩配置
  enable-gzip: "true"
  gzip-level: "6"
  gzip-types: "text/plain text/css application/json application/javascript text/xml application/xml"
  
  # 保持连接
  upstream-keepalive-connections: "100"
  upstream-keepalive-timeout: "60"
  
  # SSL 优化
  ssl-protocols: "TLSv1.2 TLSv1.3"
  ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"

资源限制 ​

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  template:
    spec:
      containers:
      - name: controller
        resources:
          requests:
            cpu: 100m
            memory: 90Mi
          limits:
            cpu: 1000m
            memory: 1Gi

最佳实践 ​

1. 域名和路径设计 ​

yaml
# 推荐的域名结构
metadata:
  name: well-designed-ingress
spec:
  rules:
  # 环境隔离
  - host: api-dev.example.com
  - host: api-staging.example.com
  - host: api.example.com  # 生产环境
  
  # 服务分离
  - host: frontend.example.com
  - host: api.example.com
  - host: admin.example.com

2. 安全配置 ​

yaml
metadata:
  annotations:
    # 强制 HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    
    # 安全头
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

3. 监控集成 ​

yaml
metadata:
  annotations:
    # Prometheus 监控
    nginx.ingress.kubernetes.io/enable-metrics: "true"
    
    # 访问日志格式
    nginx.ingress.kubernetes.io/log-format-escape-json: "true"
    nginx.ingress.kubernetes.io/log-format-upstream: |
      {"time": "$time_iso8601", "remote_addr": "$proxy_protocol_addr", "x_forwarded_for": "$proxy_add_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"}

4. 高可用配置 ​

yaml
# Ingress Controller 高可用部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
spec:
  replicas: 3  # 多副本
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app.kubernetes.io/name: ingress-nginx
            topologyKey: kubernetes.io/hostname

总结 ​

Ingress 是 Kubernetes 中实现七层负载均衡和 HTTP/HTTPS 路由的核心组件。通过合理配置 Ingress 规则和选择合适的 Ingress Controller,可以构建高性能、高可用的应用入口。

关键要点:

  • 选择合适的 Ingress Controller(推荐 Nginx Ingress)
  • 合理设计域名和路径路由规则
  • 配置 SSL/TLS 证书实现 HTTPS 访问
  • 实施安全策略和访问控制
  • 建立监控和日志收集机制
  • 优化性能和资源配置
  • 实现高可用和故障恢复能力
别急,先让缓存热一下。