すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:高負荷シナリオでのNGINX Ingressコントローラーのインストール

最終更新日:Feb 17, 2025

Ingressは、Kubernetesクラスター内のサービスへの外部アクセスを管理するためのレイヤー7負荷分散を提供するAPIオブジェクトです。 NGINX Ingressコントローラは、Ingressの機能を実装するために使用されます。 これにより、IngressはIngressルールに基づいて外部アクセスの負荷分散を実行できます。 高負荷のシナリオでは、不十分なCPUリソースとネットワーク接続がアプリケーションのパフォーマンスを低下させる可能性があります。 このトピックでは、NGINX Ingressコントローラーを使用して、高負荷シナリオでアプリケーションのパフォーマンスを向上させる方法について説明します。

前提条件

  • Container Service for Kubernetes (ACK) クラスターのNGINX Ingressコントローラーは通常どおり実行されます。

  • kubectlクライアントがクラスターに接続されています。 詳細については、「kubectlを使用したACKクラスターへの接続」をご参照ください。

デプロイメントノート

高負荷シナリオでNGINX Ingressコントローラーをデプロイする場合は、次の項目に注意してください。

Elastic Compute Service (ECS) インスタンスの仕様

クラスターが多数の同時リクエストを受信すると、Ingressは大量のCPUリソースとネットワーク接続を消費します。 次のインスタンスタイプなど、パフォーマンスが強化されたECSインスタンスタイプを使用することを推奨します。

  • ecs.c6e.8xlarge (32 Core - 64 GB): パフォーマンスが向上したコンピューティング最適化インスタンスタイプ。 このインスタンスタイプは、最大6,000,000パケット /秒 (PPS) をサポートします。

  • ecs.g6e.8xlarge (32 Core - 128 GB): パフォーマンスが向上した汎用インスタンスタイプ。 このインスタンスタイプは、最大6,000,000 PPSをサポートします。

ECSインスタンスタイプの詳細については、「インスタンスファミリーの概要」をご参照ください。

Kubernetes設定

  • 排他ノードを使用してNGINX Ingressコントローラーをデプロイします。 次のコマンドを実行して、ノードにラベルとテイントを追加します。

    kubectl label nodes $node_name ingress-pod="yes"
    kubectl taint nodes $node_name ingress-pod="yes":NoExecute
  • CPUポリシーをstaticに設定します。

  • ingress-controller ServiceのServer Load Balancer (slb) 仕様としてSuper I (SLB. s3.large) を選択することを推奨します。

  • Terwayをネットワークプラグインとして使用し、ENI専用モードを使用することを推奨します。

NGINX Ingressコントローラの設定

  • NGINX Ingressコントローラーの保証ポッドを設定します。

    • nginx-ingress-controllerのコンテナーのリクエストlimitsパラメーターを30 Coreと40 GiBに設定します。

    • init-sysctl initコンテナのrequestsおよびlimitsパラメーターを100 mおよび70 MiBに設定します。

  • NGINX IngressコントローラーDeploymentのレプリケートされたポッドの数を、新しく追加されたノードの数に設定します。

  • NGINX IngressコントローラーのConfigMapのworker-processesを28に設定します。 これにより、システムの28のワーカープロセスが予約されます。

  • NGINX IngressコントローラーのConfigMapでkeepaliveを設定して、接続を介したリクエストの最大数を指定します。

  • ロギングを無効にします。

ステップ1: ノードの追加

ACKクラスターにノードプールを作成し、ノードプールに2つのノードを追加します。

次の説明に基づいてノードプールを設定します。 詳細については、「ノードプールの作成と管理」をご参照ください。

  • オペレーティングシステムAlibaba Cloud Linux 3に設定します。

  • [ノードラベル][テイント] を設定します。

    • テイントを追加します。 Keyをingress-podに設定し、Valueyesに設定し、EffectNoExecuteに設定します。

    • ノードラベルを追加します。 Keyをingress-podに設定し、Valueyesに設定します。

  • [CPUポリシー][静的] に設定します。

ステップ2: NGINX Ingressコントローラの更新

kubectl edit deploy nginx-ingress-controller -n kube-systemコマンドを実行し、次の説明に基づいてNGINX Ingressコントローラの構成ファイルを編集します。

  1. ポッドのanti-affinity設定を削除します。

    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
          operator: In
          values:
          - ingress-nginx
       topologyKey: kubernetes.io/hostname
  2. initコンテナーのrequestslimitsパラメーターを設定します。

    resources:
      limits:
        cpu: 100m
        memory: 70Mi
      requests:
        cpu: 100m
        memory: 70Mi
  3. nginx-ingress-controllerコンテナーのrequestsおよびlimitsパラメーターを30 Coreおよび40 GiBに設定します。

    resources:
      limits:
        cpu: "30"
        memory: 40Gi
      requests:
        cpu: "30"
        memory: 40Gi
  4. ノードのアフィニティ設定と許容範囲を設定します。

    nodeSelector:
      ingress-pod: "yes"
    tolerations:
    - effect: NoExecute
      key: ingress-pod
      operator: Equal
      value: "yes"
  5. NGINX Ingressコントローラーのレプリケートされたポッドの数を、新しく追加されたノードの数に設定します。

  6. スタートアップパラメーターに -- enable-metrics=falseを追加して、メトリック収集を無効にします。

    説明

    メトリックが必要ない場合は、メトリックの収集を無効にすることを推奨します。 NGINX Ingressコントローラーのバージョンがv1.9.3以降の場合、スタートアップパラメーター -- exclude-socket-metricsを設定して、メトリクスを除外することもできます。 例: nginx_ingress_controller_ingress_upstream_latency_seconds これは、システム性能への影響を軽減する。

    containers:
    - args:
      - /nginx-ingress-controller
      - --configmap=$(POD_NAMESPACE)/nginx-configuration
      - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
      - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
      - --annotations-prefix=nginx.ingress.kubernetes.io
      - --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb
      - --enable-metrics=false
      - --v=1

ステップ3: NGINX IngressコントローラのConfigMapを更新する

  1. kubectl edit cm -n kube-system nginx-configurationコマンドを実行し、NGINX IngressコントローラーのConfigMapを編集します。 次のテンプレートに基づいてConfigMapを変更します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-configuration
      namespace: kube-system
    data:
      allow-backend-server-header: "true"
      enable-underscores-in-headers: "true"
      generate-request-id: "true"
      ignore-invalid-headers: "true"
      log-format-upstream: $remote_addr - [$remote_addr] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]
      max-worker-connections: "65536"
      proxy-body-size: 20m
      proxy-connect-timeout: "3"
      proxy-read-timeout: "5"
      proxy-send-timeout: "5"
      reuse-port: "true"
      server-tokens: "false"
      ssl-redirect: "false"
      upstream-keepalive-timeout: "900"
      worker-processes: "28" # Specify the number of NGINX processes to start. You can set this value based on your node specifications. We recommend that you set the value to the number of CPU cores - 2. 
      worker-cpu-affinity: auto
      upstream-keepalive-connections: "300"
      upstream-keepalive-requests: "1000" # Specify the maximum number of requests through a persistent connection. 
      keep-alive: "900"
      keep-alive-requests: "10000"
  2. ログをファイルにインポートし、ログローテーションを設定します。

    デフォルトでは、ログは /dev/stdoutファイルに書き込まれます。 クラスターが大量のリクエストを受信した場合、CPU使用率は高くなります。 この場合、ログを /dev/stdoutファイルに書き込み、ログローテーションを設定することを推奨します。

    1. SSHを使用して、ingress-controllerポッドがデプロイされているECSインスタンスにログインします。 詳細については、「SSHキーペアを使用したLinuxインスタンスへの接続」をご参照ください。

    2. 次の内容を /etc/crontabファイルの末尾に追加します。

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

      この例では、ログは15分ごとにローテーションされます。 要件に基づいて間隔を変更できます。

    3. という名前のファイルを作成します。nginx-log-rotate.shで、/ルートディレクトリに移動します。

      Dockerクラスター

      #!/bin/bash
      # Specify the maximum number of log files that are retained. You can change the number based on your requirements. 
      keep_log_num=5
      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
      # Make the NGINX Ingress controller pods sleep for a time period of a random length between 5 and 10 seconds. 
      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	
      	

      containerdクラスター

      #!/bin/bash
      # Specify the maximum number of log files that are retained. You can change the number based on your requirements. 
      keep_log_num=5
      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
      # Make the NGINX Ingress controller pods sleep for a time period of a random length between 5 and 10 seconds. 
      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	
      	
    4. 次のコマンドを実行して、nginx-log-rotate.shファイルを実行可能にします。

      chmod 755 /root/nginx-log-rotate.sh

ステップ4: 設定の最適化

この手順では、カーネルパラメーター、アプリケーション設定、圧縮設定、およびHTTPSパフォーマンスを最適化する方法を示します。

  • カーネルパラメーターの最適化

    カーネルパラメータを最適化する前に、パラメータをよく理解し、注意してください。

    • TIME_WAIT設定の変更

      NGINX Ingressのパフォーマンスを最適化するには、OSパラメーターを変更してTIME_WAITポートの再利用を有効にし、FIN_WAIT2およびTIME_WAIT状態の接続のタイムアウト期間を短縮します。

      • net.ipv4.tcp_fin_timeout=15: FIN_WAIT2状態の接続のタイムアウト期間を短縮します。 このようにして、接続はより短い期間内に解放される。

      • net.net filter.nf_conntrack_tcp_timeout_time_wait=30: 接続がtime-WAIT状態のままである期間を短縮します。 このようにして、接続はより短い期間内に解放される。

    • 設定手順

      1. 次のコマンドを実行して、NGINX Ingressコントローラー用に作成されたDeploymentの設定を変更します。

        kubectl edit deployments -n kube-system nginx-ingress-controller
      2. sysctl -w net.ipv4.tcp_fin_timeout=15およびsysctl -w net.net filter.nf_conntrack_tcp_timeout_time_wait=30の設定をinit containerセクションに追加します。 次に、変更を保存して終了します。

        initContainers:
              - command:   # Add the sysctl -w net.ipv4.tcp_fin_timeout=15 and sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30 settings. 
                - /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 
                  sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30   
                  fi
  • アプリケーション設定の最適化

    NGINX Ingressコントローラのアプリケーション設定を最適化するには、次の手順を実行します。

    1. 次のコマンドを実行して、NGINX IngressコントローラのConfigMapを変更します。

       kubectl edit cm -n kube-system nginx-configuration
    2. 次の表のパラメーターの説明に基づいて、ConfigMapのパラメーターを変更します。

      項目

      パラメーター

      説明

      ダウンストリーム接続のキープアライブ設定

      キープアライブ: "60"

      キープアライブ接続のタイムアウト期間。 単位は秒です。

      keep-alive-requests: "10000"

      キープアライブ接続で送信できるリクエストの最大数。

      アップストリーム接続のキープアライブ設定

      upstream-keepalive-connections: "1000"

      キープアライブ接続の最大数。

      upstream-keepalive-requests: "2147483647"

      キープアライブ接続で送信できるリクエストの最大数。

      upstream-keepalive-time: 1h

      キープアライブ接続でリクエストを処理できる最大期間。

      upstream-keepalive-timeout: "150"

      アイドル状態のアップストリームキープアライブ接続のタイムアウト期間。 単位は秒です。

      各作業プロセスの接続上限

      max-worker-connections: "65536"

      ワーカープロセスによって開くことができる同時接続の最大数。

      タイムアウト設定

      説明

      ビジネス要件に基づいてパラメーター値を変更できます。

      proxy-connect-timeout: "3"

      接続を確立するためのタイムアウト期間。 単位は秒です。

      proxy-read-timeout: "5"

      データを読み取るためのタイムアウト時間。 単位は秒です。

      proxy-send-timeout: "5"

      データ送信のタイムアウト期間。 単位は秒です。

      再試行設定

      説明

      バックエンドサービスでエラーが発生すると、複数回の再試行により過度のリクエストが発生する可能性があります。 これにより、バックエンドサービスの負荷が増加したり、サービスの雪崩が発生したりする可能性があります。 詳細については、「ingress-nginx公式ドキュメント」をご参照ください。

      proxy-next-upstream-tries: "3"

      リクエストの送信に失敗した後のリトライ回数。 デフォルト値:3 デフォルト値には、元のリクエストと2回の再試行が含まれます。

      proxy-next-upstream: "off"

      リトライがトリガーされる条件。 再試行を無効にするには、値をoffに設定します。

      proxy-next-upstream-timeout

      リクエストの再試行のタイムアウト時間。 単位は秒です。 ビジネス要件に基づいて値を変更できます。

  • Brotli圧縮の有効化

    データ圧縮は追加のCPU時間を消費しますが、圧縮データパケットは帯域幅の使用を減らし、ネットワークスループットを高めます。 Brotliは、Googleが開発したオープンソースの圧縮アルゴリズムです。 一般的に使用されるgzip圧縮アルゴリズムと比較して、Brotliの圧縮率は20% に高く30% ます。 gzipは、NGINX Ingressコントローラーで使用されるデフォルトの圧縮アルゴリズムです。 ingress-nginxのBrotli圧縮を有効にするには、次のパラメーターを設定する必要があります。 詳細については、「ingress-nginx公式ドキュメント」をご参照ください。

    • enable-brotli: Brotliを有効にするかどうかを指定します。 有効な値: trueおよびfalse

    • brotli-level: 圧縮レベル。 有効な値: 1 ~ 11。 デフォルト値: 4。 より高い圧縮レベルは、より多量のCPUリソースを必要とする。

    • brotli-types: Brotliによってその場で圧縮される多目的インターネットメール拡張 (MIME) 型。

    次のコマンドを実行して、Brotli圧縮を有効にします。

     kubectl edit cm -n kube-system nginx-configuration

    サンプル設定:

    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パフォーマンスの最適化

    HTTPSパフォーマンスを向上させるには、kubectl edit cm -n kube-system nginx-configurationコマンドを実行してnginx-configuration ConfigMapを変更し、ConfigMapで次の設定を設定します: SSLセッションキャッシュ、オンライン証明書ステータスプロトコル (OCSP) ステープル、TLS 1.3初期データのサポート、および暗号スイートの優先度。

    • SSLセッションのキャッシュとタイムアウト

      共有SSLセッションキャッシュのサイズと、クライアントがキャッシュに格納されたセッションパラメーターを再利用できる期間を設定します。 これにより、SSLハンドシェイクのオーバーヘッドを減らすことができます。

      • ConfigMap設定:

        ssl-session-cache-size: "10m"
        ssl-session-timeout: "10m"
      • nginx側のNGINX. conf設定。 ビジネス要件に基づいて設定を変更できます。

        ssl_session_cache shared:SSL:120m;   # 1 MB of cache can store about 4,000 sessions. 
        ssl_session_timeout 1h;              # The timeout period of sessions is 1 hour.
    • OCSPステープルの有効化

      OCSPステープルは、クライアント証明書の検証に必要な時間を短縮できます。

      enable-ocsp: "true"
    • TLS 1.3早期データ (0-RTT) のサポート

      TLS 1.3早期データ機能は、ゼロラウンドトリップ時間 (0-RTT) とも呼ばれ、クライアントはハンドシェイクが完了する前にデータを送信できます。 これは、応答時間を短縮するのに役立つ。

      ssl-early-data: "true"
      ssl-protocols: "TLSv1.3"
    • 暗号スイートの優先度の変更 (最適化)

      暗号スイートの優先順位を変更して、ネットワークの遅延を減らすことができます。 ACKはNGINX Ingressコントローラ設定の暗号スイート優先度を最適化しました。

      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;    # The cipher configurations on the server side take precedence.