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

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

最終更新日:Nov 14, 2024

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

前提条件

デプロイの説明

高負荷シナリオで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コンテナーのrequestsおよび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: "30"
        memory: 40Gi
      requests:
        cpu: "30"
        memory: 40Gi
  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コントローラーDeploymentのレプリケートされたポッドの数を、新しく追加されたノードの数に設定します。

  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