如果您的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規格。
Pod獨佔節點
由於Nginx的基礎開銷,在資源總量相同的情況下,單個高規格Pod(例如32核)的效能表現優於多個低規格Pod(例如兩個16核的Pod)。因此,在保證高可用的前提下,您可使用少量高規格Pod而不是多個更低規格的Pod。
例如,您可建立一個高規格但僅有少量節點的節點池,並通過汙點與容忍度配置使其中的每個節點被單個Controller Pod獨佔。這樣的部署方式可以使Nginx Ingress Controller最大化利用資源,並且不受叢集內其他應用的影響。
關閉指標採集
Nginx Ingress Controller預設採集指標供其他組件使用,但採集消耗一定的CPU資源,如果不需要擷取指標,建議關閉採集。通過在Nginx啟動參數中添加--enable-metrics=false,即可關閉所有指標採集。
v1.9.3以上版本的Nginx Ingress Controller還添加了一些自訂指標採集參數。例如,添加--exclude-socket-metrics後,即可停止採集Socket相關指標。關於啟動參數的更多資訊,請參見cli-arguments。
調整逾時策略
您可通過減少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串連相關原理,並在修改後持續觀察串連狀態和資源使用方式,確保調整安全有效。
ConfigMap配置
Nginx Ingress Controller的全域配置儲存在ConfigMap中。您可執行以下命令,編輯ConfigMap。
kubectl edit cm -n kube-system nginx-configuration配置項說明
ConfigMap中的關鍵配置項說明如下。
配置項 | 配置參數 | 描述 |
下遊 |
| 下遊 |
| 下遊 | |
上遊 |
| 最大上遊 |
| 允許的最大上遊 | |
| 上遊 | |
| 上遊 | |
單個Worker最大串連 |
| 單個Worker支援的最大串連數。 |
逾時配置 說明 可根據實際業務情境調整,按需配置。 |
| 建立TCP串連的逾時時間,單位為秒。 |
| 讀取資料的逾時時間,單位為秒。 | |
| 發送資料的逾時時間,單位為秒。 | |
最佳化重試機制 說明 當後端服務異常情況下,多級重試的過多請求可能加重後端服務的負載引發雪崩問題。更多詳情請參見Ingress-nginx官方文檔。 |
| 失敗後的重試次數,預設為3次,包括1次初始請求和2次重試。 |
| 指定重試條件,設定為off則關閉重試功能。 | |
| 指定請求重試的逾時時間,單位為秒,根據實際應用情境進行調整。 |
配置日誌自動輪轉
Nginx Ingress Controller Pod預設將日誌記錄到/dev/stdout。隨著記錄檔逐漸增大,記錄新日誌耗費的資源也會更多。通過定時輪轉日誌,即將一個時間段中的日誌儲存到獨立檔案中,並清除原有日誌記錄的方法,可降低記錄日誌的資源消耗。
以SSH方式登入部署Nginx Ingress Controller Pod的ECS節點。具體操作,請參見通過密鑰認證登入Linux執行個體。
在
/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)" doneDocker節點
#!/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執行以下命令,對
nginx-log-rotate.sh檔案添加可執行許可權。chmod 755 /root/nginx-log-rotate.sh在
/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配置。