全部產品
Search
文件中心

Container Service for Kubernetes:Nginx Ingress Controller使用建議

更新時間:Jun 19, 2024

Nginx Ingress Controller是部署於叢集內部的Ingress控制器,可以為您提供效能更好且定製性更高的使用方式。在社區版本的基礎上,ACK叢集提供的Nginx Ingress Controller整合了阿里雲產品的一系列功能,提供更加便捷的使用體驗。由於Nginx Ingress Controller部署在叢集內部,因此它的穩定性與使用時的配置、當前叢集狀態密切相關。本文介紹Nginx Ingress Controller的使用建議,您可以參考以下使用建議,對叢集內的Ingress Controller進行配置,獲得最佳的使用效果。

索引

提升Nginx Ingress Controller的效能和穩定性

使用合適的副本數和資源限制

預設情況下,通過叢集建立或從組件中心安裝的Nginx Ingress Controller的副本數為2,您可以根據業務的實際需要進行調整。

在部署Nginx Ingress Controller時,請確保Nginx Ingress Controller分布在不同的節點上,避免不同Nginx Ingress Controller之間資源的搶佔和單點故障。您也可以為其使用獨佔節點來保證效能與穩定性,具體操作,請參見使用獨佔節點保證Nginx Ingress效能與穩定性。同時建議您不要為Nginx Ingress Controller設定資源限制,避免OOM所帶來的流量中斷。如果確實有限制的需要,建議資源限制CPU不低於1000 Milicore(YAML配置裡格式為1000m)和記憶體不低於2 GiB。

使用獨佔節點來提升Nginx Ingress效能與穩定性

最佳化Nginx Ingress效能

Nginx Ingress Controller效能調優主要分為系統參數調優和Nginx參數調優:

  • 系統參數調優:阿里雲上的作業系統已經預設最佳化了一些常見參數,其他還需要調優的系統參數主要包括系統最大Backlog數和可用連接埠的最大範圍。系統參數調優後可以保證Nginx處理高並發請求的能力,以及在串連後端時不會因為連接埠耗盡而失敗。

  • Nginx參數調優:

    • 調整單個Worker的最大串連數:Nginx參數主要可以調整單個Worker的最大串連數來保證Nginx Ingress Controller處理高並發請求的能力。

    • 增加連線逾時時間:Nginx Ingress Controller與Nginx預設表現不同,會使用長串連對後端業務Pod發起請求,因此Nginx參數還需要增加連線逾時時間來讓單條串連能夠處理更多的請求,減少串連建立時的開銷。

    • 設定長連線逾時時間:請您確保後端的業務長串連的逾時時間不低於Nginx Ingress Controller的連線逾時時間( ACK叢集中預設為900s)。

Nginx Ingress組件預設已經置入了相關的調優項,在一般情境中能夠達到較優的表現。如果您有特殊需要,可以通過ConfigMap中的相關欄位進一步最佳化系統參數和Nginx參數。關於ConfigMap的更多資訊,請參見ConfigMaps

對Nginx Ingress Controller配置HPA進行自動擴容

一般情況下,Nginx Ingress Controller已經有足夠的能力應對業務的突發流量。如果在高負載情況下仍不滿足您的要求,也可以配置HPA對Nginx Ingress Controller進行擴容。具體操作,請參見容器水平伸縮(HPA)

重要

在Pod擴縮容時可能會導致部分Business Connectivity的中斷情況,請謹慎配置。

配置的YAML樣本如下所示:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-ingress-controller-hpa
  namespace: kube-system
spec:
   scaleTargetRef:
     apiVersion: apps/v1
     kind: Deployment
     name: nginx-ingress-controller
   minReplicas: 2
   maxReplicas: 5
   metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 50

為後端服務配置合理的preStop Hook

在後端服務變換時,Nginx ingress Controller會將正在終止的Pod的端點摘除,同時保持還在處理的請求的串連。如果後端服務Pod在收到結束訊號後立即退出,就可能會導致正在處理的請求失敗,或者由於時序問題,部分流量仍被轉寄到已經退出的Pod中,導致部分流量產生損失。

為瞭解決變換時流量產生損失的情況,推薦在後端服務的Pod中配置preStop Hook,在端點被摘除後仍繼續工作一段時間,解決流量中斷的情況。

在Pod模板的容器配置中加入:

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: app
        lifecycle:
          # 配置preStop Hook,等待30秒後退出。
          # 需要容器中存在sleep命令。
          preStop:
            exec:
              command:
              - sleep
              - 30

提升Nginx Ingress Controller的可觀測性

使用SLS和阿里雲Prometheus服務提升可觀測性

Nginx Ingress Controller提供了基於SLS日誌以及Prometheus的監控大盤,協助您更好地瞭解業務的流量情況。

  • SLS日誌:

  • 阿里雲Prometheus監控:阿里雲Prometheus監控可以在建立叢集時選擇安裝,或者在建立叢集後通過營運管理 > Prometheus監控安裝或查看。具體操作,請參見阿里雲Prometheus監控

    說明

    使用阿里雲Prometheus監控時,請為叢集中的Ingress資源添加host欄位,否則在預設情況下,該Ingress的部分metrics將會缺失。您也可以通過在Nginx Ingress Controller的Deployment中修改controller啟動參數,加入--metrics-per-host=false來解決該問題。

Nginx Ingress Controller進階功能

使用多套Nginx Ingress Controller

在應用中,您可能會因為內外網隔離等需要,在叢集中部署多套Nginx Ingress Controller。具體操作,請參見部署多個Ingress Controller

在叢集內部訪問Nginx Ingress Controller

在叢集中,LoadBalancer Service的外部地址(Nginx Ingress Controller的公網 IP)通常會被Iptables或IPVS攔截並轉寄。當externalTrafficPolicyLocal,且節點上沒有對應Nginx Ingress Pod時,會發生網路不通的問題。ACK叢集中的Nginx Ingress Controller預設使用了Local模式的LoadBalancer Service,因此在叢集內訪問Nginx Ingress Controller綁定的CLB地址時,可能會出現網路不通的情況。

建議您在叢集內部有訪問Nginx Ingress Controller(通過公網IP或綁定公網IP的網域名稱)的需要時,使用Service ClusterIP或內部網域名稱(nginx-ingress-lb.kube-system)訪問。同時請避免在Nginx Ingress Controller中對自身進行訪問,也可能會因為Hairpin問題導致網路不通。關於該問題的解決方案,請參見Kubernetes叢集中訪問LoadBalancer暴露出去的SLB地址不通

使用WAF或透明WAF

為了阻擋惡意請求,您可以在Web Application Firewall控制台應用型負載平衡ALB控制台為叢集Nginx Ingress Controller所使用的CLB開啟WAF或透明WAF功能。在開啟HTTPS連接埠上的WAF或透明WAF功能時,需要在控制台上配置所使用的認證。這種情況下,可能會出現以下問題:

  • TLS請求會在WAF或透明WAF上進行截斷,因此叢集內通過Secret配置的認證將不會被暴露在公網出口上。

  • 在叢集內通過CLB IP或Service ClusterIP訪問443連接埠可能不會經過WAF或透明WAF,導致認證返回錯誤。

  • 在開啟WAF或透明WAF的情況下,Nginx Ingress Controller將預設無法獲得真實的用戶端IP。您可以通過在ConfigMap中 ( 通過組件管理安裝的Nginx Ingress Controller預設為kube-system命名空間下的nginx-configuration)添加以下內容,配置啟用Nginx的Realip模組,使用X-Forwarded-For頭作為真實用戶端地址。

    use-forwarded-headers: "true" # 0.30.0及更舊版本使用該選項。
    enable-real-ip: "true" # 0.44.0及更新版本使用該選項。
    proxy-real-ip-cidr: <您從WAF擷取到的回源IP段>

通過Nginx Ingress Controller進行應用的藍綠或灰階發布

您可以通過Container Service管理主控台的灰階發布或手動添加Annotation的方式來使用Nginx Ingress Controller提供的灰階功能,具體操作,請參見通過Nginx Ingress實現灰階發布和藍綠髮布

重要

請確保需要灰階所使用的服務(包括原服務和灰階服務)沒有同時被灰階Ingress以外的Ingress資源引用。否則,可能會出現灰階規則的衝突,從而引發流量路由錯誤。

通過Nginx Ingress Controller代理非HTTP請求

Nginx Ingress Controller預設使用HTTP協議串連到後端服務,但同時提供了對多種後端協議的支援,其中比較常用的協議有WebSocket、HTTPS和gRPC。關於支援的後端協議具體類型,請參見Backend Protocol

  • WebSocket:Nginx Ingress Controller提供了對WebSocket的原生支援,您不需要進行任何配置即可轉寄WebSocket串連。如果您有持續較長的WebSocket串連,可以通過Annotation適當地調整後端串連的逾時時間,防止業務因為逾時而斷連。關於調整的具體操作,請參見Custom timeouts

  • HTTPS:針對使用HTTPS的後端服務,您可以在Ingress中添加nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"的Annotation切換為HTTPS串連。

  • gRPC:gRPC僅支援通過TLS連接埠訪問。因此,請確保您的業務通過Nginx Ingress Controller訪問gRPC服務時,使用的是加密的TLS連接埠。關於配置gRPC的具體操作,請參見通過Ingress Controller實現gRPC服務訪問