全部產品
Search
文件中心

Container Service for Kubernetes:部署高負載情境的Nginx Ingress Controller

更新時間:May 22, 2025

如果您的Nginx Ingress Controller經常面臨高負載,可以從叢集網路外掛程式、節點規格和Controller配置等方面進行調整以提高效能。本文介紹如何配置高效能Nginx Ingress Controller。

重要

本文中的配置方法僅供您參考思路,具體是否使用某個配置,以及各項參數與規格的選擇,請您實際結合Controller負載進行選擇。

容器網路外掛程式

叢集的容器網路外掛程式(CNI Plugin)配置會影響叢集內網路通訊效能,進而影響Nginx Ingress Controller的效能表現。推薦您使用Terway作為容器網路外掛程式。如果您對網路效能有更高要求,可以考慮使用Terway獨佔ENI模式,但該模式會導致單節點Pod上限較少。關於Terway的更多資訊,請參見使用Terway網路外掛程式

節點規格選擇

Nginx Ingress Controller所屬Pod的網路效能受節點規格限制。例如,節點PPS為30萬時,Controller單Pod的PPS上限即為30萬。建議選擇以下高效能ECS規格:

  • 計算型執行個體:ecs.c6e.8xlarge(32核64GB,600萬PPS)

  • 網路型執行個體:ecs.g6e.8xlarge(32核128GB,600萬PPS)

關於ECS執行個體規格的更多資訊,請參見執行個體規格類型系列

Nginx Ingress Controller組件配置

Server Load Balancer執行個體規格

Nginx Ingress Controller使用一個CLB執行個體對外接收請求,CLB執行個體的規格會影響Controller的效能。您可在Nginx Ingress Controller所屬的Service中使用Annotations指定CLB規格。

編輯Server Load Balancer執行個體規格

  1. 執行以下命令,編輯Nginx Ingress Controller所屬Service。

    kubectl edit service -n kube-system nginx-ingress-lb
  2. 在Service中添加service.beta.kubernetes.io/alibaba-cloud-loadbalancer-specAnnotation。

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        ...
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: "slb.s3.large" # 指定CLB規格
      name: nginx-ingress-lb
      namespace: kube-system
      ...
    spec:
      ...
    
    重要

    CLB規格的效能與計費,請參見執行個體規格。更高規格的執行個體會產生更多費用。

Pod獨佔節點

由於Nginx的基礎開銷,在資源總量相同的情況下,單個高規格Pod(例如32核)的效能表現優於多個低規格Pod(例如兩個16核的Pod)。因此,在保證高可用的前提下,您可使用少量高規格Pod而不是多個更低規格的Pod。

例如,您可建立一個高規格但僅有少量節點的節點池,並通過汙點與容忍度配置使其中的每個節點被單個Controller Pod獨佔。這樣的部署方式可以使Nginx Ingress Controller最大化利用資源,並且不受叢集內其他應用的影響。

配置Controller Pod獨佔節點樣本

  1. 在叢集中建立一個新的節點池,並為節點池選擇下列配置。具體操作,請參見建立和管理節點池

    • 選擇期望節點數為3。

    • 選擇作業系統Alibaba Cloud Linux 3

    • 配置節點標籤汙點(Taints)

      • 汙點(Taints)中添加ingress-podyesEffectNoExecute

      • 節點標籤中添加ingress-nodeyes

    • 選擇CPU PolicyStatic

  2. 執行以下命令,編輯Controller所屬的Deployment。

    kubectl edit deploy nginx-ingress-controller -n kube-system
  3. 對Deployment進行如下更改:

    1. 設定replicas為3,與節點池的節點數相同。

      spec:
        replicas: 3
    2. nginx-ingress-controller container的requestslimits進行修改,設定CPU為32核,記憶體為64G。

      containers:
        - args:
          ...
          resources:
            limits:
              cpu: "32"
              memory: 64Gi
            requests:
              cpu: "32"
              memory: 64Gi
    3. 設定節點親和性和容忍性,使Pod只會調度到擁有ingress-node:yes標籤的節點上,並可以容忍ingress-pod:yes汙點。

      nodeSelector:
        kubernetes.io/os: linux
        ingress-node: "yes"
      tolerations:
      - effect: NoExecute
        key: ingress-pod
        operator: Equal
        value: "yes"
    4. 請確保Deployment中有以下反親和性配置,該配置保證每個節點最多有一個Nginx Ingress Controller Pod。

      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
            operator: In
            values:
            - ingress-nginx
         topologyKey: kubernetes.io/hostname

關閉指標採集

Nginx Ingress Controller預設採集指標供其他組件使用,但採集消耗一定的CPU資源,如果不需要擷取指標,建議關閉採集。通過在Nginx啟動參數中添加--enable-metrics=false,即可關閉所有指標採集。

v1.9.3以上版本的Nginx Ingress Controller還添加了一些自訂指標採集參數。例如,添加--exclude-socket-metrics後,即可停止採集Socket相關指標。關於啟動參數的更多資訊,請參見cli-arguments

關閉Metrics採集

  1. 執行以下命令,編輯Controller所屬的Deployment。

    kubectl edit deploy nginx-ingress-controller -n kube-system
  2. 在容器配置部分添加--enable-metrics=false配置,即可關閉所有指標採集。--exclude-socket-metrics則可以停止Socket相關指標採集。

    containers:
    - args:
      - ...
      - --enable-metrics=false
      - --exclude-socket-metrics # 在--enable-metrics=true時有效

調整逾時策略

您可通過減少FIN_WAIT2與TIME_WAIT狀態的逾時時間,使Nginx Ingress Controller更快地關閉已完成資料發送的串連,降低資源佔用。

在Nginx Ingress Controller中,相關的配置為:

  • net.ipv4.tcp_fin_timeout:FIN_WAIT2狀態的逾時時間,預設為60秒。

  • net.netfilter.nf_conntrack_tcp_timeout_time_wait:TIME_WAIT狀態下的串連保持時間,預設為60秒。

重要

FIN_WAIT2與TIME_WAIT是容器核心的配置,修改後會顯著影響Nginx Ingress Controller的表現。如果您需要對此進行修改,請確保您已經瞭解TCP串連相關原理,並在修改後持續觀察串連狀態和資源使用方式,確保調整安全有效。

調整逾時策略

  1. 執行以下命令,編輯Controller所屬的Deployment。

    kubectl edit deploy nginx-ingress-controller -n kube-system
  2. initContainers中新增sysctl -w net.ipv4.tcp_fin_timeoutsysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait

    initContainers:
          - command:  
            - /bin/sh
            - -c
            - |
              if [ "$POD_IP" != "$HOST_IP" ]; then
              mount -o remount rw /proc/sys
              sysctl -w net.core.somaxconn=65535
              sysctl -w net.ipv4.ip_local_port_range="1024 65535"
              sysctl -w kernel.core_uses_pid=0
              sysctl -w net.ipv4.tcp_fin_timeout=15 # FIN_WAIT2狀態上限設定為15秒
              sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30 # TIME_WAIT狀態上限設定為30秒
              fi

ConfigMap配置

Nginx Ingress Controller的全域配置儲存在ConfigMap中。您可執行以下命令,編輯ConfigMap。

kubectl edit cm -n kube-system nginx-configuration

配置項說明

ConfigMap中的關鍵配置項說明如下。

配置項

配置參數

描述

下遊keepalive

keep-alive: "60"

下遊keepalive串連的最大保持時間,單位為秒。

keep-alive-requests: "10000"

下遊keepalive請求的最大數量。

上遊keepalive

upstream-keepalive-connections: "1000"

最大上遊keepalive串連數。

upstream-keepalive-requests: "2147483647"

允許的最大上遊keepalive請求數。

upstream-keepalive-time: 1h

上遊keepalive串連的最大保持時間。

upstream-keepalive-timeout: "150"

上遊keepalive串連的空閑逾時時間,單位為秒。

單個Worker最大串連

max-worker-connections: "65536"

單個Worker支援的最大串連數。

逾時配置

說明

可根據實際業務情境調整,按需配置。

proxy-connect-timeout: "3"

建立TCP串連的逾時時間,單位為秒。

proxy-read-timeout: "5"

讀取資料的逾時時間,單位為秒。

proxy-send-timeout: "5"

發送資料的逾時時間,單位為秒。

最佳化重試機制

說明

當後端服務異常情況下,多級重試的過多請求可能加重後端服務的負載引發雪崩問題。更多詳情請參見Ingress-nginx官方文檔

proxy-next-upstream-tries: "3"

失敗後的重試次數,預設為3次,包括1次初始請求和2次重試。

proxy-next-upstream: "off"

指定重試條件,設定為off則關閉重試功能。

proxy-next-upstream-timeout

指定請求重試的逾時時間,單位為秒,根據實際應用情境進行調整。

配置日誌自動輪轉

Nginx Ingress Controller Pod預設將日誌記錄到/dev/stdout。隨著記錄檔逐漸增大,記錄新日誌耗費的資源也會更多。通過定時輪轉日誌,即將一個時間段中的日誌儲存到獨立檔案中,並清除原有日誌記錄的方法,可降低記錄日誌的資源消耗。

  1. 以SSH方式登入部署Nginx Ingress Controller Pod的ECS節點。具體操作,請參見通過密鑰認證登入Linux執行個體

  2. /root目錄下添加檔案nginx-log-rotate.sh

    containerd節點

    #!/bin/bash
    # 最多保留記錄檔個數,可根據需求進行調整。
    keep_log_num=5
    
    #擷取所有運行中的ingress-nginx容器ID
    ingress_nginx_container_ids=$(crictl ps | grep nginx-ingress-controller | grep -v pause | awk '{print $1}')
    if [[ -z "$ingress_nginx_container_ids" ]]; then
     echo "error: failed to get ingress nginx container ids"
     exit 1
    fi
    
    # 隨機睡眠5~10秒。
    sleep $(( RANDOM % (10 - 5 + 1 ) + 5 ))
    for id in $ingress_nginx_container_ids; do
     crictl exec $id bash -c "cd /var/log/nginx; if [[ \$(ls access.log-* | wc -l) -gt $keep_log_num ]]; then rm -f \$(ls -t access.log-* | tail -1); fi ; mv access.log access.log-\$(date +%F:%T) ; kill -USR1 \$(cat /tmp/nginx/nginx.pid)"
    done	
    

    Docker節點

    #!/bin/bash
    # 最多保留記錄檔個數,可根據需求進行調整。
    keep_log_num=5
    
    #擷取所有運行中的ingress-nginx容器ID
    ingress_nginx_container_ids=$(docker ps | grep nginx-ingress-controller | grep -v pause | awk '{print $1}')
    if [[ -z "$ingress_nginx_container_ids" ]]; then
     echo "error: failed to get ingress nginx container ids"
     exit 1
    fi
    
    # 隨機睡眠5~10秒。
    sleep $(( RANDOM % (10 - 5 + 1 ) + 5 ))
    for id in $ingress_nginx_container_ids; do
     docker exec $id bash -c "cd /var/log/nginx; if [[ \$(ls access.log-* | wc -l) -gt $keep_log_num ]]; then rm -f \$(ls -t access.log-* | tail -1); fi ; mv access.log access.log-\$(date +%F:%T) ; kill -USR1 \$(cat /tmp/nginx/nginx.pid)"
    done	
    	
  3. 執行以下命令,對nginx-log-rotate.sh檔案添加可執行許可權。

    chmod 755 /root/nginx-log-rotate.sh
  4. /etc/crontab檔案結尾添加以下內容:

    */15 * * * *  root /root/nginx-log-rotate.sh
    說明

    此樣本使用Cron運算式,每15分鐘對日誌輪轉一次,您可根據實際需求進行調整。

啟用Brotli壓縮

壓縮是一種通過犧牲CPU時間來節省大量網路頻寬的通用方法,能夠提升輸送量。Brotli是Google開發的一種壓縮演算法。相較於常用的gzip壓縮演算法(Nginx Ingress Controller預設使用gzip),Brotli在文本類資料(如網頁資源)上的壓縮率通常比 gzip 高約 15%~30%,但具體提升取決情境的詳細情況。在Nginx Ingress中啟用Brotli壓縮,需要配置以下參數。

  • enable-brotli: 是否啟用Brotli壓縮演算法,取值為 true 或 false

  • brotli-level: 壓縮層級,範圍是1到11,預設是4。層級越高,CPU效能消耗越大。

  • brotli-types: 指定使用Brotli即時壓縮的MIME類型。

您可通過在ConfigMap中添加以下配置啟用Brotli壓縮:

data:
  enable-brotli: "true"
  brotli-level: "6"
  brotli-types: "text/xml image/svg+xml application/x-font-ttf image/vnd.microsoft.icon application/x-font-opentype application/json font/eot application/vnd.ms-fontobject application/javascript font/otf application/xml application/xhtml+xml text/javascript application/x-javascript text/plain application/x-font-truetype application/xml+rss image/x-icon font/opentype text/css image/x-win-bitmap"

HTTPS效能最佳化

為了提升Nginx ingress Controller的HTTPS的效能,可以配置以下參數:SSL 會話緩衝、OCSP Stapling、TLS 1.3 早期資料以及調整密碼套件優先順序。

  • SSL會話緩衝與逾時

    設定SSL 共用工作階段緩衝的大小以及重用緩衝中儲存的會話參數的時間,可以減少SSL握手的開銷。

    • ConfigMap配置:

      data:
        ssl-session-cache-size: "10m"
        ssl-session-timeout: "10m"
    • 對應Nginx側的nginx.conf配置,可以根據實際情境需求調整。

      ssl_session_cache shared:SSL:120m;   # 1m 4000個。
      ssl_session_timeout 1h;              # 會話逾時時間為1小時。
  • 啟用OCSP Stapling

    使用OCSP Stapling可以減少用戶端認證驗證的時間。

    data:
      enable-ocsp: "true"
  • 支援TLS 1.3早期資料(0-RTT)

    啟用TLS 1.3的0-RTT功能可以允許用戶端在握手完成之前就發送資料,從而減少串連建立的延遲。

    data:
      ssl-early-data: "true"
      ssl-protocols: "TLSv1.3"
  • 調整Cipher優先順序(無需手動調優)

    通過調整加密套件的優先順序,可以有效降低延遲。Nginx Ingress Controller的預設配置已進行了最佳化。

    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on;    # 優先使用伺服器端的Cipher配置。