Ingressは、Kubernetesクラスター内のサービスへの外部アクセスを管理するためのレイヤー7負荷分散を提供するAPIオブジェクトです。 NGINX Ingressコントローラは、Ingressの機能を実装するために使用されます。 これにより、IngressはIngressルールに基づいて外部アクセスの負荷分散を実行できます。 高負荷のシナリオでは、不十分なCPUリソースとネットワーク接続がアプリケーションのパフォーマンスを低下させる可能性があります。 このトピックでは、NGINX Ingressコントローラーを使用して、高負荷シナリオでアプリケーションのパフォーマンスを向上させる方法について説明します。
前提条件
Container Service for Kubernetes (ACK) クラスターのNGINX Ingressコントローラーは通常どおり実行されます。
kubectlクライアントがクラスターに接続されています。 詳細については、「クラスターのkubeconfigファイルを取得し、kubectlを使用してクラスターに接続する」をご参照ください。
デプロイの説明
高負荷シナリオで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
に設定し、Valueをyes
に設定し、EffectをNoExecuteに設定します。ノードラベルを追加します。 Keyを
ingress-pod
に設定し、Valueをyes
に設定します。
[CPUポリシー] を [静的] に設定します。
ステップ2: NGINX Ingressコントローラの更新
kubectl edit deploy nginx-ingress-controller -n kube-system
コマンドを実行し、次の説明に基づいてNGINX Ingressコントローラの構成ファイルを編集します。
ポッドのanti-affinity設定を削除します。
podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - ingress-nginx topologyKey: kubernetes.io/hostname
initコンテナーの
requests
とlimits
パラメーターを設定します。resources: limits: cpu: "30" memory: 40Gi requests: cpu: "30" memory: 40Gi
nginx-ingress-controllerコンテナーの
requests
およびlimits
パラメーターを30 Coreおよび40 GiBに設定します。resources: limits: cpu: "30" memory: 40Gi requests: cpu: "30" memory: 40Gi
ノードのアフィニティ設定と許容範囲を設定します。
nodeSelector: ingress-pod: "yes" tolerations: - effect: NoExecute key: ingress-pod operator: Equal value: "yes"
NGINX IngressコントローラーDeploymentのレプリケートされたポッドの数を、新しく追加されたノードの数に設定します。
スタートアップパラメーターに
-- 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を更新する
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"
ログをファイルにインポートし、ログローテーションを設定します。
デフォルトでは、ログは /dev/stdoutファイルに書き込まれます。 クラスターが大量のリクエストを受信した場合、CPU使用率は高くなります。 この場合、ログを /dev/stdoutファイルに書き込み、ログローテーションを設定することを推奨します。
SSHを使用して、ingress-controllerポッドがデプロイされているECSインスタンスにログインします。 詳細については、「SSHキーペアを使用したLinuxインスタンスへの接続」をご参照ください。
次の内容を /etc/crontabファイルの末尾に追加します。
*/15 * * * * root /root/nginx-log-rotate.sh
説明この例では、ログは15分ごとにローテーションされます。 要件に基づいて間隔を変更できます。
/ルートディレクトリで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
次のコマンドを実行して、nginx-log-rotate.shファイルを実行可能にします。
chmod 755 /root/nginx-log-rotate.sh