Skip to content

Ingress

概述

Ingress是Kubernetes中管理外部访问集群内服务的API对象,提供HTTP和HTTPS路由功能。它作为七层负载均衡器,可以根据URL路径、域名等规则将流量路由到不同的Service。

Ingress核心功能

1. 七层负载均衡

  • 基于HTTP/HTTPS协议的路由
  • 支持URL路径和域名路由
  • 提供高级路由功能

2. TLS/SSL终止

  • 集中管理TLS证书
  • 自动HTTPS重定向
  • 支持多个证书

3. 虚拟主机路由

  • 基于域名的路由
  • 支持多租户架构
  • 灵活的路由规则

Ingress架构

┌─────────────────────────────────────────────────────────┐
│                     Internet                             │
└────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│              Ingress Controller (负载均衡器)              │
│  ┌──────────────────────────────────────────────────┐  │
│  │  Nginx / Traefik / HAProxy / Kong / Istio        │  │
│  └──────────────────────────────────────────────────┘  │
└────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│                    Ingress Rules                         │
│  ┌──────────────────────────────────────────────────┐  │
│  │  api.example.com → api-service:8080              │  │
│  │  web.example.com → web-service:80                │  │
│  │  example.com/api → api-service:8080              │  │
│  └──────────────────────────────────────────────────┘  │
└────────────────────┬────────────────────────────────────┘

        ┌────────────┼────────────┐
        │            │            │
        ▼            ▼            ▼
   ┌─────────┐  ┌─────────┐  ┌─────────┐
   │ Service │  │ Service │  │ Service │
   │   API   │  │   Web   │  │  Admin  │
   └─────────┘  └─────────┘  └─────────┘

Ingress Controller部署

Nginx Ingress Controller

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
      - name: nginx-ingress-controller
        image: k8s.gcr.io/ingress-nginx/controller:v1.8.1
        args:
        - /nginx-ingress-controller
        - --configmap=$(POD_NAMESPACE)/nginx-configuration
        - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
        - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
        - --publish-service=$(POD_NAMESPACE)/ingress-nginx
        - --annotations-prefix=nginx.ingress.kubernetes.io
        - --enable-ssl-passthrough
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 3
        securityContext:
          runAsNonRoot: false
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
          allowPrivilegeEscalation: true
---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
  - name: https
    port: 443
    targetPort: 443
    protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

Ingress资源配置

1. 基本Ingress配置

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

2. 基于路径的路由

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 8080
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 8080
      - path: /metrics
        pathType: Prefix
        backend:
          service:
            name: metrics-service
            port:
              number: 9090

3. 基于域名的虚拟主机

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-based-virtual-hosting
  namespace: default
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 8080

4. TLS配置

yaml
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
  namespace: default
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURwekNDQW8rZ0F3SUJBZ0lVYjBzWUF4cDRQdWxPV2NZa0RQNDA2NVpKTEw0d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lqRUxNQWtHQTFVRUJoTUNWVk14Q3pBSkJnTlZCQWdNQWtOQk1SSXdFQVlEVlFRSERBbFRZVzRnUm5KaApibU54TVJVd0V3WURWUVFLREFsRmVHRnRjR3hsSUVOdk1Sc3dHUVlEVlFRRERCSmhjSEF1WlhoaGJYQnNaUzVqCmIyMHdIaGNOTWpRd01UQXhNREF3TURBd1doY05NalV3TVRBeE1EQXdNREF3V2pCaU1Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhFakFRQmdOVkJBY01DVk5oYmlCR2NtRnVZMmt4RlRBVEJnTlZCQW9NREVWNApZVzF3YkdVZ1EyOXRNUnN3R1FZRFZRUUREQkpoY0hBdVpYaGhiWEJzWlM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzZqbjhQSXZBSGFFY0RTVXBpWklSSG9IYUlMQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  tls.key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IUUNBUUVFSUdZVzVKOWl4T0hwRHRJOXRoRmZiK0FXVUtaYk05d1FlS3ZjdkpXTU40YnpvQWNHQlN1QkJBQUsKb1VRRFFnQUVScE5lSzFsTmRPNlFyRjZKUjFxZ3BjMzNqSXZPdnZiSlZjVXpFb3V5QmEvRnFvPS0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0K
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    - web.example.com
    secretName: tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

5. 完整生产环境配置

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: production-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "15"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
    nginx.ingress.kubernetes.io/limit-connections: "100"
    nginx.ingress.kubernetes.io/limit-rps: "50"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "X-Frame-Options: SAMEORIGIN";
      more_set_headers "X-Content-Type-Options: nosniff";
      more_set_headers "X-XSS-Protection: 1; mode=block";
      more_set_headers "Referrer-Policy: strict-origin-when-cross-origin";
    nginx.ingress.kubernetes.io/server-snippets: |
      location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
      }
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    - web.example.com
    - admin.example.com
    secretName: wildcard-tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 8080
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 8080
      - path: /graphql
        pathType: Prefix
        backend:
          service:
            name: graphql-service
            port:
              number: 8080
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 8080

TLS证书管理

1. 使用Cert-Manager自动管理证书

yaml
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
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-cert
  namespace: default
spec:
  secretName: example-com-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - api.example.com
  - web.example.com
  - admin.example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cert-manager-ingress
  namespace: default
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    - web.example.com
    secretName: example-com-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

2. Wildcard证书

yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-dns
    solvers:
    - dns01:
        cloudflare:
          email: admin@example.com
          apiTokenSecretRef:
            name: cloudflare-api-token
            key: api-token
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example-com
  namespace: default
spec:
  secretName: wildcard-example-com-tls
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
  dnsNames:
  - example.com
  - '*.example.com'

Ingress注解详解

常用Nginx Ingress注解

yaml
metadata:
  annotations:
    # 重定向配置
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.example.com
    nginx.ingress.kubernetes.io/permanent-redirect-code: "301"
    
    # 代理配置
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "15"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
    
    # 限流配置
    nginx.ingress.kubernetes.io/limit-connections: "100"
    nginx.ingress.kubernetes.io/limit-rps: "50"
    nginx.ingress.kubernetes.io/limit-whitelist: "10.0.0.0/8,192.168.0.0/16"
    
    # CORS配置
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    
    # 认证配置
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
    
    # 白名单配置
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,192.168.0.0/16"
    
    # 重写配置
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    
    # 自定义配置片段
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "X-Frame-Options: SAMEORIGIN";
      more_set_headers "X-Content-Type-Options: nosniff";
    
    nginx.ingress.kubernetes.io/server-snippets: |
      location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
      }

操作命令

安装Ingress Controller

bash
# 安装Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

# 使用Helm安装
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.service.type=LoadBalancer

管理Ingress资源

bash
# 查看Ingress
kubectl get ingress
kubectl get ing

# 查看详细信息
kubectl describe ingress <ingress-name>

# 查看YAML格式
kubectl get ingress <ingress-name> -o yaml

# 创建Ingress
kubectl apply -f ingress.yaml

# 删除Ingress
kubectl delete ingress <ingress-name>

# 编辑Ingress
kubectl edit ingress <ingress-name>

查看Ingress Controller状态

bash
# 查看Ingress Controller Pod
kubectl get pods -n ingress-nginx

# 查看Ingress Controller Service
kubectl get svc -n ingress-nginx

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

# 查看Ingress Controller配置
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- cat /etc/nginx/nginx.conf

# 测试Ingress配置
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- nginx -t

证书管理

bash
# 创建TLS Secret
kubectl create secret tls tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

# 查看证书Secret
kubectl get secret tls-secret -o yaml

# 查看证书详情
kubectl get secret tls-secret -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout

# 使用Cert-Manager
kubectl get certificates
kubectl describe certificate <cert-name>
kubectl get issuers
kubectl describe issuer <issuer-name>

测试Ingress

bash
# 获取Ingress地址
kubectl get ingress

# 测试HTTP访问
curl -H "Host: api.example.com" http://<ingress-ip>

# 测试HTTPS访问
curl -k -H "Host: api.example.com" https://<ingress-ip>

# 测试路径路由
curl -H "Host: api.example.com" http://<ingress-ip>/v1/users

# 测试域名路由
curl -H "Host: web.example.com" http://<ingress-ip>

实践示例

示例1:微服务API网关

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-gateway
  namespace: microservices
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /users(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 8080
      - path: /orders(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 8080
      - path: /products(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: product-service
            port:
              number: 8080
      - path: /payments(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: payment-service
            port:
              number: 8080
      - path: /notifications(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: notification-service
            port:
              number: 8080

示例2:多环境部署

yaml
# 开发环境
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dev-ingress
  namespace: development
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: dev.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
---
# 测试环境
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: staging-ingress
  namespace: staging
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Staging Environment'
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - staging.example.com
    secretName: staging-tls
  rules:
  - host: staging.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
---
# 生产环境
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prod-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/limit-connections: "200"
    nginx.ingress.kubernetes.io/limit-rps: "100"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "X-Frame-Options: SAMEORIGIN";
      more_set_headers "X-Content-Type-Options: nosniff";
      more_set_headers "X-XSS-Protection: 1; mode=block";
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - www.example.com
    - example.com
    secretName: prod-tls
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

示例3:蓝绿部署和金丝雀发布

yaml
# 蓝绿部署 - 蓝色环境
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: blue-green-blue
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/canary: "false"
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-blue-service
            port:
              number: 80
---
# 金丝雀发布 - 10%流量到新版本
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-canary-service
            port:
              number: 80
---
# 金丝雀发布 - 基于Header
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-header-ingress
  namespace: production
  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:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-canary-service
            port:
              number: 80

示例4:WebSocket和长连接支持

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: websocket-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-streaming: "true"
    nginx.ingress.kubernetes.io/websocket-services: "chat-service"
spec:
  ingressClassName: nginx
  rules:
  - host: chat.example.com
    http:
      paths:
      - path: /ws
        pathType: Prefix
        backend:
          service:
            name: chat-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: chat-web-service
            port:
              number: 80

故障排查

常见问题

1. Ingress无法访问

bash
# 检查Ingress Controller状态
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# 检查Ingress资源
kubectl get ingress
kubectl describe ingress <ingress-name>

# 检查Service和Endpoint
kubectl get svc
kubectl get endpoints

# 检查Ingress Controller Service
kubectl get svc -n ingress-nginx
kubectl describe svc -n ingress-nginx

# 检查防火墙规则
sudo iptables -L -n

2. TLS证书问题

bash
# 检查证书Secret
kubectl get secret <tls-secret-name> -o yaml

# 验证证书内容
kubectl get secret <tls-secret-name> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout

# 检查证书过期时间
kubectl get secret <tls-secret-name> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -enddate -noout

# Cert-Manager问题排查
kubectl get certificates
kubectl describe certificate <cert-name>
kubectl get certificaterequests
kubectl describe certificaterequest <request-name>
kubectl logs -n cert-manager -l app=cert-manager

3. 路由规则不生效

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

# 测试Nginx配置
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- nginx -t

# 重新加载Nginx配置
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- nginx -s reload

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

# 检查Ingress注解
kubectl get ingress <ingress-name> -o yaml | grep annotations -A 20

4. 502/504错误

bash
# 检查后端Service
kubectl get svc <service-name>
kubectl describe svc <service-name>

# 检查后端Pod
kubectl get pods -l app=<app-name>
kubectl describe pod <pod-name>

# 检查Pod健康状态
kubectl get pods -l app=<app-name> -o wide

# 测试Service连接
kubectl run test --image=busybox --rm -it --restart=Never -- wget -O- http://<service-name>:<port>

# 查看Pod日志
kubectl logs <pod-name>

# 检查超时配置
kubectl get ingress <ingress-name> -o yaml | grep timeout

5. 性能问题

bash
# 查看Ingress Controller资源使用
kubectl top pods -n ingress-nginx

# 查看Ingress Controller Pod数量
kubectl get pods -n ingress-nginx

# 查看连接数
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- netstat -an | grep ESTABLISHED | wc -l

# 查看Nginx状态
kubectl exec -n ingress-nginx -it <nginx-ingress-pod> -- curl http://localhost:10254/nginx_status

# 调整副本数
kubectl scale deployment -n ingress-nginx nginx-ingress-controller --replicas=3

最佳实践

1. 架构设计

  • 使用专门的Ingress命名空间
  • 分离Ingress Controller和应用
  • 使用高可用部署模式
  • 合理规划域名和路径

2. 安全配置

  • 强制HTTPS重定向
  • 配置TLS证书
  • 使用网络策略限制访问
  • 启用认证和授权
  • 配置安全Headers

3. 性能优化

  • 启用HTTP/2
  • 配置合理的超时时间
  • 启用Gzip压缩
  • 配置缓存策略
  • 使用CDN加速

4. 高可用部署

  • 部署多个Ingress Controller副本
  • 使用Pod反亲和性
  • 配置资源限制
  • 启用健康检查
  • 配置自动扩缩容

5. 监控和日志

  • 收集访问日志
  • 监控性能指标
  • 设置告警规则
  • 定期审计配置

6. 证书管理

  • 使用Cert-Manager自动管理
  • 配置证书自动续期
  • 监控证书过期时间
  • 使用通配符证书

7. 配置管理

  • 使用ConfigMap管理全局配置
  • 版本控制Ingress配置
  • 使用命名空间隔离环境
  • 文档化路由规则

总结

Ingress是Kubernetes中实现七层负载均衡的核心组件,提供了强大的HTTP/HTTPS路由功能。通过合理配置Ingress,可以实现灵活的流量管理、TLS终止和虚拟主机路由。

下一步学习