概念解析

Ingress是Kubernetes中用於管理外部訪問集羣服務的API對象,它提供HTTP和HTTPS路由規則,將外部請求路由到集羣內的Service。Ingress控制器負責實現這些路由規則。

核心概念

  1. HTTP/HTTPS路由:基於主機名和路徑將請求路由到後端服務
  2. 負載均衡:在多個服務實例間分發流量
  3. SSL/TLS終止:處理SSL/TLS證書和加密通信
  4. 虛擬主機:支持基於域名的虛擬主機配置
  5. 路徑匹配:支持精確路徑、前綴路徑和正則表達式匹配

Ingress與相關組件的關係

  1. Ingress資源:定義路由規則的Kubernetes資源
  2. Ingress控制器:實現Ingress規則的實際組件(如Nginx、Traefik等)
  3. Service:Ingress路由的目標服務
  4. Pod:實際處理請求的應用程序實例

核心特性

  1. HTTP路由:基於主機和路徑的路由規則
  2. TLS/SSL支持:自動處理HTTPS證書
  3. 負載均衡:在後端服務間分發流量
  4. 虛擬主機:支持多個域名指向不同服務
  5. 路徑重寫:支持路徑重寫和重定向
  6. 認證和授權:集成認證和授權機制
  7. 速率限制:控制請求速率防止過載
  8. 灰度發佈:支持基於權重的流量分割

實踐教程

安裝Nginx Ingress Controller

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

# 或使用YAML文件安裝
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml

創建基本Ingress

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

配置TLS

apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: <base64 encoded cert>
  tls.key: <base64 encoded key>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  tls:
  - hosts:
    - example.com
    secretName: tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

真實案例

案例:多租户Web應用平台

某公司需要為多個客户提供Web應用託管服務,每個客户有自己的域名。使用Ingress可以實現統一的入口管理:

# 客户A的應用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: customer-a-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: customer-a-app
  template:
    metadata:
      labels:
        app: customer-a-app
    spec:
      containers:
      - name: app
        image: customer-a/web-app:1.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: customer-a-service
spec:
  selector:
    app: customer-a-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
---
# 客户B的應用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: customer-b-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: customer-b-app
  template:
    metadata:
      labels:
        app: customer-b-app
    spec:
      containers:
      - name: app
        image: customer-b/web-app:1.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: customer-b-service
spec:
  selector:
    app: customer-b-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
---
# 統一Ingress配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-tenant-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: customer-a.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: customer-a-service
            port:
              number: 80
  - host: customer-b.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: customer-b-service
            port:
              number: 80
  tls:
  - hosts:
    - customer-a.example.com
    - customer-b.example.com
    secretName: wildcard-tls-secret

這種配置的優勢:

  • 統一入口管理,降低運維複雜度
  • 支持多個域名和應用
  • 集中處理SSL證書
  • 可以輕鬆添加新客户

配置詳解

路徑重寫配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api/v1(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-service
            port:
              number: 80

負載均衡配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: load-balancer-ingress
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

速率限制配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rate-limit-ingress
  annotations:
    nginx.ingress.kubernetes.io/rate-limit-connections: "10"
    nginx.ingress.kubernetes.io/rate-limit-rps: "5"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

故障排除

常見問題及解決方案

  1. Ingress規則不生效

    # 檢查Ingress配置
    kubectl describe ingress <ingress-name>
    
    # 檢查Ingress控制器狀態
    kubectl get pods -n ingress-nginx
    
    # 查看Ingress控制器日誌
    kubectl logs -n ingress-nginx <controller-pod-name>
    
  2. SSL證書問題

    # 檢查證書Secret
    kubectl describe secret <tls-secret-name>
    
    # 驗證證書內容
    kubectl get secret <tls-secret-name> -o yaml
    
    # 測試HTTPS連接
    curl -v https://<domain-name>
    
  3. 502/503錯誤

    # 檢查後端服務狀態
    kubectl get services
    
    # 檢查Endpoints
    kubectl get endpoints <service-name>
    
    # 檢查Pod狀態
    kubectl get pods -l <selector-labels>
    
  4. 域名解析問題

    # 檢查DNS配置
    nslookup <domain-name>
    
    # 檢查Ingress規則中的主機名
    kubectl get ingress <ingress-name> -o yaml
    

最佳實踐

  1. 命名規範

    • 使用有意義的Ingress名稱
    • 為不同環境使用不同的Ingress資源
  2. TLS管理

    • 使用Let's Encrypt自動管理證書
    • 為所有生產環境啓用HTTPS
  3. 路由規則

    • 使用明確的路徑匹配規則
    • 合理組織主機和路徑規則
  4. 監控和日誌

    • 啓用Ingress控制器的訪問日誌
    • 集成監控系統監控Ingress性能
  5. 安全配置

    • 限制不必要的HTTP方法
    • 配置適當的CORS策略
    • 啓用安全頭信息
  6. 性能優化

    • 合理配置連接池和超時設置
    • 使用緩存減少後端負載

安全考慮

安全的Ingress配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
  annotations:
    # 啓用HSTS
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains";
    # 隱藏服務器版本信息
    nginx.ingress.kubernetes.io/server-snippet: |
      server_tokens off;
    # 限制請求大小
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  tls:
  - hosts:
    - example.com
    secretName: tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

使用網絡策略限制訪問

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ingress-controller-policy
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
  - ports:
    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443

命令速查

命令 描述
kubectl get ingress 查看Ingress列表
kubectl describe ingress <name> 查看Ingress詳細信息
kubectl apply -f <ingress.yaml> 創建或更新Ingress
kubectl delete ingress <name> 刪除Ingress
kubectl get ingress -o wide 查看Ingress詳細信息
kubectl get ingressclass 查看Ingress類
kubectl logs -n ingress-nginx <controller-pod> 查看Ingress控制器日誌
kubectl get secret <tls-secret> 查看TLS證書Secret
kubectl create secret tls <name> --cert=<cert-file> --key=<key-file> 創建TLS證書Secret
curl -v https://<domain-name> 測試HTTPS連接

總結

Ingress是Kubernetes中管理外部訪問的核心組件,它提供了強大的HTTP/HTTPS路由能力和豐富的功能特性。通過本文檔的學習,你應該能夠:

  • 理解Ingress的概念和工作機制
  • 安裝和配置Ingress控制器
  • 創建和管理Ingress資源
  • 配置TLS證書和安全策略
  • 排查常見的Ingress問題
  • 遵循Ingress的最佳實踐和安全考慮

在下一文檔中,我們將學習ConfigMap和Secret配置管理,它們是管理應用程序配置和敏感信息的重要工具。