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

Container Service for Kubernetes:NGINX Ingressコントローラのトラブルシューティング

最終更新日:Nov 14, 2024

このトピックでは、NGINX Ingressコントローラーの診断手順とエラーのトラブルシューティング方法について説明します。 このトピックでは、一般的な診断方法についても説明し、NGINX Ingressコントローラーに関するよくある質問に対する回答を提供します。

目次

カテゴリ

コンテンツ

診断手順

診断手順

トラブルシューティング

トラブルシューティング

一般的な診断方法

よくある質問

背景情報

Container Service for Kubernetes (ACK) は、オープンソースバージョンに基づいて最適化されたNGINX Ingressコントローラーを提供します。 ACKによって提供されるNGINX Ingressコントローラは、オープンソースバージョンと互換性があり、オープンソースバージョンによって提供されるすべての注釈をサポートします。 ACKクラスターの作成時にNGINX Ingressコントローラーをインストールできます。

Ingressは、NGINX IngressコントローラーをクラスターにデプロイしてIngressのルーティングルールを解析する場合にのみ、通常どおり機能します。 NGINX Ingressコントローラがルーティングルールに一致する要求を受信した後、NGINX Ingressコントローラは、対応するバックエンドサービスに要求をルーティングします。 その後、バックエンドサービスは要求をポッドに転送します。 Kubernetesクラスターでは、Services、Ingress、およびNGINX Ingressコントローラーは次のプロセスで動作します。

  • サービスは、複製されたポッドのセットで実行されるバックエンドアプリケーションの抽象化です。

  • Ingressにはリバースプロキシルールが含まれています。 HTTPまたはHTTPSリクエストがルーティングされるサービスポッドを制御します。 たとえば、リクエストは、リクエスト内のホストとURLパスに基づいて、異なるServiceポッドにルーティングされます。

  • NGINX Ingressコントローラは、Ingressルールを解析するリバースプロキシプログラムです。 Ingressルールに変更が加えられた場合、NGINX Ingressコントローラはそれに応じてIngressルールを更新します。 NGINX Ingressコントローラーがリクエストを受信すると、Ingressルールに基づいてリクエストをServiceポッドにリダイレクトします。

NGINX Ingressコントローラーは、APIサーバーからIngressルールの変更を取得し、nginx.confなどの設定ファイルを動的に生成します。 これらの設定ファイルは、NGINXなどのロードバランサーで必要です。 次に、NGINX Ingressコントローラはロードバランサをリロードします。 たとえば、NGINX Ingressコントローラーはnginx -s loadコマンドを実行してNGINXをリロードし、新しいIngressルールを生成します。S2

診断手順

诊断流程Ingress.png

  1. 次の手順を実行して、Ingressによって問題が発生しているかどうかを確認できます。 Ingressコントローラーの設定が有効であることを確認してください。

    1. コントローラポッドから特定のポッドにアクセスできるかどうかを確認します。 詳細については、「Ingressコントローラポッドを使用してIngressポッドとバックエンドポッドに手動でアクセスする」をご参照ください。

    2. NGINX Ingressコントローラーが正しく設定されているかどうかを確認します。 詳細については、「NGINX Ingressコントローラーのドキュメント」をご参照ください。

  2. Ingress診断機能を使用して、Ingressとコンポーネントの設定を確認します。 次に、プロンプトに基づいて設定を変更します。 詳細については、「Ingress診断機能の使用」をご参照ください。

  3. 問題の原因を特定し、に基づいて関連するソリューションを参照します。トラブルシューティング.

  4. 問題が解決しない場合は、次の手順を実行します。

    • TLS証明書に関連する問題:

      1. ドメイン名がCNAMEレコードモードまたは透過プロキシモードでWeb Application Firewall (WAF) に追加されているかどうかを確認します。

        • ドメイン名がWAFに追加されている場合は、ドメイン名にTLS証明書があるかどうかを確認します。

        • ドメイン名がWAFに追加されていない場合は、次の手順に進みます。

      2. Server Load Balancer (SLB) インスタンスにレイヤー7リスナーが追加されているかどうかを確認します。

        • レイヤ7リスナーがSLBインスタンスに追加されている場合は、TLS証明書がリスナーに関連付けられているかどうかを確認します。

        • SLBインスタンスにレイヤー7リスナーが追加されていない場合は、次の手順に進みます。

    • 問題がTLS証明書に関連していない場合は、コントローラポッドのエラーログを確認してください。 詳細については、「NGINX Ingressコントローラポッドのエラーログの診断」をご参照ください。

  5. 問題が解決しない場合は、コントローラポッドとバックエンドポッドでパケットをキャプチャして、問題の原因を特定します。 詳細については、「パケットのキャプチャ」をご参照ください。

  6. 問題が解決しない場合は、チケットの送信します。

トラブルシューティング

トラブルシューティング

問題

解決策

接続に関連する問題

クラスター内のポッドはIngressにアクセスできません。

Kubernetesクラスター内からLoadBalancerのIPアドレスにアクセスできないのはなぜですか。

Ingressコントローラにアクセスできません。

IngressコントローラポッドがIngressコントローラへのアクセスに失敗するのはなぜですか。

TCPおよびUDPサービスにアクセスできません。

TCPまたはUDPを使用するサービスを追加する方法?

HTTPSアクセスに関連する問題

証明書が更新されないか、デフォルトの証明書が返されます。

TLS証明書をクラスターに追加した後、またはTLS証明書を変更した後に、デフォルトのTLS証明書または以前のTLS証明書が使用されるのはなぜですか。

RX_RECORD_TOO_LONG /間違ったバージョン番号というエラーが返されます。

HTTPSリクエストに対して次のエラーが返されるのはなぜですか。

Ingressの作成時にエラーが発生する

Ingressを作成すると、「webhookの呼び出しに失敗しました... 」というエラーが発生します。

Ingressを作成するときに次のエラーが発生するのはなぜですか: "failed calling webhook"?

Ingressは作成されますが、Ingressは有効になりません。

Ingressルールが有効にならないのはなぜですか?

アクセスが期待に応えられない

クライアントIPアドレスは保持できません。

IngressコントローラポッドがクライアントIPアドレスを保持できないのはなぜですか。

IPホワイトリストは有効にならないか、期待どおりに機能しません。

Ingressによって公開されているgRPCサービスにアクセスできません。

Ingressによって公開されるgRPCサービスへのアクセスに失敗するのはなぜですか?

カナリアリリースルールは有効になりません。

カナリアリリースルールが有効にならないのはなぜですか?

カナリアリリースルールが無効であるか、他のトラフィックがカナリアIngressに関連付けられているバックエンドポッドに配信されます。

カナリアリリースルールに基づいてトラフィックが配信されない場合、または他のIngressからのトラフィックがカナリアサービスにルーティングされる場合はどうすればよいですか?

次のエラーが発生します。プレーンHTTPリクエストがHTTPSポートに送信されました

バックエンドHTTPSサービスへのアクセスに失敗するのはなぜですか。

502、503、413、または499のステータスコードが返されます。

一般的なHTTPステータスコード

一部のページは表示できません。

書き換え対象のアノテーションは設定されていますが, リソースへのアクセス時に404エラーが発生します。

リクエストがルートディレクトリにリダイレクトされたときに、一部のwebページリソースの読み込みに失敗したり、空白の白い画面が返されたりするのはなぜですか。

リソースにアクセスすると、net::ERR_FAILEDまたはnet::ERR_HTTP2_SERVER_REFUSED_STREAMエラーが返されます。

次のエラーが発生するのはなぜですか: net::ERR_HTTP2_SERVER_REFUSED_STREAM?

一般的に使用される診断方法

Ingress診断機能の使用

  1. ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。

  2. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、[検査と診断] > [診断] を選択します。

  3. On the診断ページをクリックします。侵入診断.

  4. [Ingress診断] パネルで、https://www.example.com などのアクセスできないURLを入力します。 [知っていると同意する] を選択し、[診断の作成] をクリックします。

    診断が完了したら、診断結果を表示して問題の修正を試みることができます。

Simple log ServiceでNGINX Ingressコントローラポッドのアクセスログを診断する

NGINX Ingressコントローラーのアクセスログ形式は、kube-system名前空間のnginx-configuration ConfigMapで確認できます。

次のサンプルコードは、NGINX Ingressコントローラのアクセスログの既定の形式を示しています。

$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] 
重要

ログ形式を変更した後、それに応じてSimple log Serviceのログ収集ルールを変更する必要があります。 それ以外の場合、NGINX IngressコントローラーのアクセスログをSimple log Serviceに収集できません。 ログ形式を変更するときは注意してください。

次の図は、Simple log ServiceコンソールにNGINX Ingressコントローラーのアクセスログが表示されるページを示しています。 詳細については、「手順4: ログデータの表示」をご参照ください。

SLS日志.png

次の表に、Simple log Serviceコンソールに表示されるログフィールドを示します。 コンソールに表示される一部のログフィールドは、実際のログフィールドとは異なります。

項目

説明

remote_addr/client_ip

クライアントの IP アドレス。

request/(method + url + version)

リクエストに関する詳細。 リクエストメソッド、URL、およびHTTPバージョンが含まれています。

request_time

リクエストの処理時間。 時間は、クライアント要求の最初のバイトが受信されたときに開始し、応答の最後のバイトが送信されたときに終了する。 このフィールドの値は、クライアントのネットワーク条件に基づいて変化するため、要求処理能力を反映しません。

upstream_addr

上流サーバーのIPアドレス。 上流サーバーがリクエストを受信しない場合、戻り値は空です。 サーバー障害により複数の上流サーバーにリクエストが送信された場合、コンマ (,) で区切られた複数のIPアドレスが返されます。

upstream_status

上流サーバーからの応答に含まれるHTTPステータスコード。 HTTPステータスコードが成功した要求を示す場合、アップストリームサーバーにアクセスできます。 502ステータスコードが返された場合、上流サーバーにアクセスできません。 複数のステータスコードはコンマ (,) で区切ります。

upstream_response_time

上流サーバーの応答時間。 単位は秒です。

proxy_upstream_name

上流サーバーの名前。 名前の形式は <名前空間>-<サービス名>-<ポート番号> です。

proxy_alternative_upstream_name

代替上流サーバーの名前。 要求が代替上流サーバに転送される場合、代替上流サーバの名前が返される。 たとえば、カナリアリリースを実装します。

デフォルトでは、次のコマンドを実行して、NGINX Ingressコントローラの最近のアクセスログを照会できます。

kubectl logs <コントローラポッド名> -n <namespace> | 少ない

期待される出力:

42.11。** - [42.11.**.**]-[25/Nov/2021:11:40:30 0800]" GET / HTTP/1.1 "200 615"_"curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 46b79dkahflhakjhdhfkah **** 47.11。**[]
42.11.** - [42.11.**.**]-[25/Nov/2021:11:40:31 0800]" GET / HTTP/1.1 "200 615"_"curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 fadgrerthflhakjhdhfkah **** 47.11。**[] 

NGINX Ingressコントローラポッドのエラーログの診断

NGINX Ingressコントローラポッドのエラーログを診断して、トラブルシューティングの範囲を絞り込むことができます。 Ingressコントローラポッドのエラーログには、次のタイプが含まれます。

  • Ingressコントローラのエラーを記録するログ。 通常、このタイプのエラーログは、無効なIngress設定が原因で生成されます。 次のコマンドを実行して、このタイプのエラーログを照会できます。

    kubectl logs <コントローラポッド名> -n <namespace> | grep -E ^[WE]
    説明

    イングレスコントローラの初期化中に、いくつかの警告イベントが生成され得る。 たとえば、kubeconfigファイルまたはIngressClassリソースを指定しない場合、警告イベントが生成されます。 これらのイベントはIngressコントローラーには影響せず、無視できます。

  • NGINXアプリケーションのエラーを記録するログ。 通常、このタイプのエラーログは、要求処理の失敗により生成されます。 次のコマンドを実行して、このタイプのエラーログを照会できます。

    kubectl logs <コントローラポッド名> -n <namespace> | grepエラー

Ingressコントローラポッドを使用してIngressポッドとバックエンドポッドに手動でアクセスする

  1. 次のコマンドを実行して、Ingressコントローラポッドにログインします。

    kubectl exec <コントローラポッド名> -n <namespace> -it -- bash
  2. IngressコントローラポッドにはcurlとOpenSSLがプリインストールされており、ネットワーク接続のテストと証明書の検証が可能です。

    • 次のコマンドを実行して、Ingressとバックエンドポッド間のネットワーク接続をテストします。

      # Ingressの実際のドメイン名でe your.domain.comを再生します。 
      curl -H "ホスト: your.domain.com" http:// 127.0.**/ # for http
      curl -- resolv e your.domain.com:443:127。0.0.1 https:// 127.0.0.1/ # for https 
    • 次のコマンドを実行して証明書を確認します。

      openssl s_client -servernam e your.domain.com -connect 127.0.0.1:443
    • バックエンドポッドへのアクセスをテストします。

      説明

      Ingressコントローラーは、ClusterIPサービスを使用する代わりに、バックエンドポッドのIPアドレスに直接接続します。

      1. 次のkubectlコマンドを実行して、バックエンドポッドのIPアドレスを照会します。

        kubectl get pod -n <namespace> <pod name> -o wide

        期待される出力:

        NAME READY STATUS RESTARTS AGE IPノードNOMINATED NOMINATED NODE READINESS GATES
        nginx-dp-7f5fcc7f-**** 1/1実行0 23時間10.71.0.146 cn-beijing.192.168。** <none> <none> 

        出力は、バックエンドポッドのIPアドレスが10.71.0.146であることを示しています。

      2. Ingressコントローラポッドとバックエンドポッド間のネットワーク接続をテストするには、次のコマンドを実行してIngressコントローラポッドを使用してIPアドレスに接続します。

        curl http://<your pod ip >:< port>/path

キャプチャパケット

問題を特定できない場合は、パケットをキャプチャして診断します。

  1. 問題がIngressコントローラポッドに関連しているか、アプリケーションポッドに関連しているかを確認します。 これを実行できない場合は、Ingressコントローラポッドとアプリケーションポッドの両方のパケットをキャプチャします。

  2. アプリケーションポッドとIngressコントローラポッドが実行されているノードにログインします。

  3. Elastic Compute Service (ECS) インスタンスで次のコマンドを実行して、Ingressによって受信されたすべての最近のパケットをキャプチャします。

    tcpdump -i任意のホスト <アプリケーションポッドIPまたはIngressコントローラポッドIP> -C 20 -W 200 -w /tmp/ingress.pcap
  4. ログデータにエラーが確認された場合は、パケットのキャプチャを停止します。

  5. エラーが発生した期間に転送されるパケットを診断します。

    説明
    • パケットキャプチャはサービスに影響を与えず、CPU使用率とディスクI/Oのわずかな増加のみを引き起こします。

    • 上記のコマンドは、キャプチャされたパケットをローテーションし、最大で200を生成できます. pcapファイルのサイズはそれぞれ20 MBです。

Kubernetesクラスター内からLoadBalancerのIPアドレスにアクセスできないのはなぜですか。

問題

Kubernetesクラスターでは、LoadBalancerのexternalTrafficPolicyがLocalに設定されている場合、特定のノードのみがLoadBalancerのIPアドレスにアクセスできます。

原因

externalTrafficPolicy: LocalはLoadBalancerに設定されます。 ローカルモードでは、LoadBalancerのIPアドレスは、ローカルノード (LoadBalancerを実行するノード) でプロビジョニングされたポッドからのみアクセスできます。 LoadBalancerのIPアドレスは、クラスター内の他のノードのポッドからアクセスできません。 LoadBalancerのIPアドレスはKubernetesクラスターの外部にあります。 ACKクラスター内のノードまたはポッドがセカンドホップを使用せずにIPアドレスにアクセスできない場合、リクエストはLoadBalancerを通過しません。 その結果、LoadBalancerのIPアドレスは、LoadBalancerを使用するサービスの拡張IPアドレスと見なされます。 リクエストは、iptablesまたはIP仮想サーバー (IPVS) に基づくkube-proxyによって転送されます。

このシナリオでは、要求されたポッドがローカルノードでプロビジョニングされていない場合、接続の問題が発生します。 LoadBalancerのIPアドレスは、要求されたポッドがローカルノードでプロビジョニングされている場合にのみアクセスできます。 external-lbの詳細については、「kube-proxyがexternal-lbのIPアドレスをノードのローカルiptablesルールに追加」をご参照ください。

解決策

  • ClusterIPサービスまたはIngress名を使用して、Kubernetesクラスター内からLoadBalancerのIPアドレスにアクセスすることを推奨します。

    Ingress名は、kube-system名前空間のnginx-ingress-lbです。

  • kubectl edit svc nginx-ingress-lb -n kube-systemコマンドを実行して、Ingressを変更します。 LoadBalancerのexternalTrafficPolicyClusterに設定します。 設定を変更した後、クライアントのIPアドレスは保持できません。

  • クラスターのネットワークプラグインがTerwayに設定されており、ENI排他モードまたは包括モードが選択されている場合、LoadBalancerのexternalTrafficPolicyclusterに設定し、ENIアノテーションを追加できます。 アノテーションにより、署名付きelastic network Interface (ENI) であるポッドがLoadBalancerのバックエンドサーバーとして追加されます。 このようにして、クライアントのIPアドレスを保持し、LoadBalancerのIPアドレスにクラスター内からアクセスできます。

    例:

    apiVersion: v1
    種類: サービス
    メタデータ:
      アノテーション:
        service.beta.kubernetes.io/backend-type: eni# バックエンドサーバーとしてeniが割り当てられているポッドを指定します。 
      ラベル:
        アプリ: nginx-ingress-lb
      名前: nginx-ingress-lb
      名前空間: kube-system
    spec:
      externalTrafficPolicy: クラスター 

    サービス注釈の詳細については、「CLBインスタンスを構成するためのサービスのYAMLファイルへの注釈の追加」をご参照ください。

IngressコントローラポッドがIngressコントローラへのアクセスに失敗するのはなぜですか。

問題

Flannelが使用されているクラスターでは、Ingressコントローラーポッドがドメイン名、SLB IPアドレス、またはクラスターIPアドレスを介してIngressコントローラーにアクセスすると、Ingressコントローラーポッドから送信された要求の一部またはすべてがドロップされます。

原因

デフォルトでは、Flannelはループバック要求を許可しません。

解決策

  • Terwayネットワークプラグインを使用する新しいクラスターを作成し、ワークロードを新しいクラスターに移行することを推奨します。

  • 新しいクラスターを作成しない場合は、Flannelの設定でhairpinModeを有効にできます。 設定を変更した後、変更を有効にするためにFlannelポッドを再作成します。

    1. 次のコマンドを実行して、Flannelの設定を変更します。

      kubectl edit cm kube-フランネル-cfg -n kube-system
    2. 返されるcni-conf.jsonファイルで、delegateフィールドに "hairpinMode": trueを追加します。

      例:

      cni-conf.json: |
          {
            "name": "cb0" 、
            "cniVersion":"0.3.1" 、
            "type": "フランネル" 、
            "delegate": {
              "isDefaultGateway": true、
              "hairpinMode": true
            }
          }
    3. 次のコマンドを実行してFlannelを再起動します。

      kubectl delete pod -n kube-system -l app=フランネル
    4. ポッドを削除して再作成します。

TLS証明書をクラスターに追加した後、またはTLS証明書を変更した後に、デフォルトのTLS証明書または以前のTLS証明書が使用されるのはなぜですか。

問題

クラスターにシークレットを追加するか、クラスター内のシークレットを変更し、IngressのsecretNameフィールドのシークレット名を更新しました。 クラスターにアクセスすると、デフォルトの証明書 (Kubernetes Ingress Controller Fake certificate) または以前の証明書が使用されます。

原因

  • 証明書は、クラスターのIngressコントローラーによって返されません。

  • 証明書が無効で、Ingressコントローラは証明書をロードできません。

  • 証明書は、Server Name Indication (SNI) フィールドに基づいてIngressコントローラによって返されます。 SNIフィールドは、TLSハンドシェイクの一部として送信されなくてもよい。

解決策

  • 次のいずれかの方法を使用して、SNIフィールドがTLSハンドシェイクの一部として送信されているかどうかを確認します。

    • ブラウザをSNIをサポートするバージョンにアップグレードします。

    • openssl s_clientコマンドを実行して証明書が使用中かどうかを確認するときは、-servernameパラメーターを指定します。

    • curlコマンドを実行する場合は、ホスト要求ヘッダーを使用する以外に、ホストを追加するか、-- resolveパラメーターを使用してドメイン名をマップします。

  • CNAMEレコードモードまたは透過プロキシモードでWebアプリケーションファイアウォール (WAF) にWebサイトを接続する場合、TLS証明書が指定されていないこと、またはTLS証明書がSLBインスタンスのレイヤー7リスナーに関連付けられていないことを確認してください。 TLS証明書は、クラスターのIngressコントローラーによって返される必要があります。

  • Container Intelligence Serviceコンソールに移動し、Ingressを診断します。 診断レポートで、Ingressの設定が有効かどうか、およびログデータにエラーが表示されているかどうかを確認します。 詳細については、「Ingress診断機能の使用」をご参照ください。

  • 次のコマンドを実行して、Ingressコントローラポッドのエラーログを表示し、ログデータに基づいて問題をトラブルシューティングします。

    kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]

Ingressによって公開されるgRPCサービスへのアクセスに失敗するのはなぜですか?

問題

Ingressによって公開されるgRPCサービスにはアクセスできません。

原因

  • バックエンドプロトコルを指定するためにIngressにアノテーションを設定しないでください。

  • gRPCサービスには、トランスポート層セキュリティ (TLS) を使用してのみアクセスできます。

解決策

  • Ingressに次のアノテーションを設定します。nginx.ingress.kubernetes.io/backend-protocol:"GRPC"

  • クライアントがHTTPSポートを使用してリクエストを送信し、トラフィックがTLSを使用して暗号化されていることを確認します。

バックエンドHTTPSサービスへのアクセスに失敗するのはなぜですか。

問題

  • Ingressを介してバックエンドHTTPSサービスにアクセスできません。

  • 400のエラーコードが返され、次のエラーメッセージが表示されます。the plain HTTP request was sent to HTTPS port

原因

Ingressコントローラーは、HTTPリクエストをバックエンドポッドに送信します。 デフォルト設定です。

解決策

Ingressに次のアノテーションを設定します。nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"

IngressコントローラポッドがクライアントIPアドレスを保持できないのはなぜですか。

問題

Ingressコントローラポッドは、クライアントIPアドレスを保持できません。 ノードIPアドレス100.XX. XX.XXまたはその他のアドレスが表示されます。

原因

  • externalTrafficPolicyは、Ingressに関連付けられているサービスのクラスターに設定されます。

  • SLBインスタンスはレイヤ7プロキシを使用します。

  • WebサイトがCNAMEレコードモードまたは透過プロキシモードでWAFに接続されています。

解決策

  • externalTrafficPolicyがサービスのクラスターに設定され、レイヤー4 SLBインスタンスが使用されている場合は、次の手順を実行します。

    externalTrafficPolicyLocalに設定します。 ただし、クラスター内からLoadBalancerのIPアドレスにアクセスできない場合があります。 詳細については、「」をご参照ください。Kubernetesクラスター内からLoadBalancerのIPアドレスにアクセスできないのはなぜですか。

  • レイヤー7プロキシが使用されている場合、たとえばレイヤー7 SLBインスタンスが使用されている場合、またはWebサイトがCNAMEレコードモードまたは透過プロキシモードでWAFに接続されている場合は、次の手順を実行します。

    1. レイヤー7プロキシでX-Forwarded-Forヘッダーが有効になっていることを確認します。

    2. IngressコントローラーのConfigMapにenable-real-ip: "true" を追加します。 デフォルトでは、ConfigMapはnginx-configurationという名前で、kube-system名前空間に属します。

    3. ログデータを分析して、クライアントIPアドレスが保存できるかどうかを確認します。

  • クライアント要求がIngressコントローラポッドに到達する前に複数のホップを通過する場合 (たとえば、要求がIngressコントローラポッドに到達する前にリバースプロキシを通過する必要がある場合) 、enable-real-ipをtrueに設定した後、remote_addrの値を確認できます。 値がクライアントIPアドレスの場合、X-Forwarded-ForヘッダーがクライアントIPアドレスをIngressコントローラーポッドに渡すために有効になっていることを示します。 X-Forwarded-Forヘッダーが無効になっている場合は、リクエストがIngressコントローラポッドに到達する前に、X-Forwarded-Forヘッダーを有効にするか、他の方法を使用してリクエストにクライアントIPアドレスを追加します。

カナリアリリースルールが有効にならないのはなぜですか?

問題

クラスターにカナリアリリースルールを設定しますが、ルールは有効になりません。

原因

考えられる原因:

  • canary-* アノテーションを追加する場合、nginx.ingress.kubernetes.io/canary: "true" は設定しません。

  • NGINX Ingressコントローラーのバージョンが0.47.0より前です。 canary-* アノテーションを追加するときは、Ingressルールのホストフィールドでアプリケーションのドメイン名を指定しません。

解決策

カナリアリリースルールに基づいてトラフィックが配信されない場合、または他のIngressからのトラフィックがカナリアサービスにルーティングされる場合はどうすればよいですか?

問題

カナリアリリースルールを設定しましたが、トラフィックはカナリアリリースルールに基づいて配信されません。または、他のIngressからのトラフィックはカナリアサービスにルーティングされます。

原因

NGINX Ingressコントローラーのカナリアリリースルールは、カナリアリリースルールが作成されたサービスに関連付けられているすべてのIngressに対して有効になります。

この問題の詳細については、「カナリア注釈を持つIngressが、同じサービスに関連付けられている他のIngressに影響を与える」をご参照ください。

解決策

Canary Ingressには、service-matchアノテーションまたはcanary-* アノテーションが割り当てられたIngressが含まれます。 カナリアIngressを作成する前に、カナリアリリースに使用される同じサービスを2つ作成し、アクセスするバックエンドポッドにサービスをマップします。

Ingressを作成するときに次のエラーが発生するのはなぜですか: "failed calling webhook"?

問題

Ingressを作成すると、「内部エラーが発生しました: webhookの呼び出しに失敗しました... 」というエラーが発生します。

Ingress FAQ.png

原因

Ingressリソースを作成すると、Ingressが有効かどうかを確認するためにサービスが使用されます。 デフォルトでは、ingress-nginx-controller-admissionという名前のサービスが使用されます。 webhookリンクエラーが発生した場合 (サービスやIngressコントローラーが削除された場合など) 、Ingressを作成できません。

解決策

  • 次のwebhookリンクに基づいて、リソースが存在し、期待どおりに動作するかどうかを確認します。ValidatingWebhookConfiguration > Service > Pod。

  • Ingressコントローラポッドのアドミッション機能が有効になっており、クラスターの外部からポッドにアクセスできることを確認してください。

  • Ingressコントローラーが削除されている場合、またはwebhook機能を使用しない場合は、ValidatingWebhookConfigurationリソースを削除できます。

HTTPSリクエストに対して次のエラーが返されるのはなぜですか。

問題

HTTPSリクエストに対して次のエラーのいずれかが返されます。SSL_ERROR_RX_RECORD_TOO_LONGまたはルーチン: CONNECT_CR_SRVR_HELLO: 間違ったバージョン番号

原因

HTTPSリクエストは、HTTPポートなどの非HTTPSポートに配信されます。

一般的な原因:

  • Server Load Balancer (SLB) インスタンスのポート443は、Ingressコントローラポッドのポート80にマップされます。

  • Ingressコントローラポッドに関連付けられているサービスのポート443は、Ingressコントローラポッドのポート80にマップされます。

解決策

HTTPSリクエストが適切なポートに配信されるように、SLBインスタンスまたはサービスの設定を変更します。

一般的なHTTPステータスコード

問題

2xx、3xx以外のHTTPステータスコード (502、503、413、499など) が返されます。

原因と解決策

ログを表示し、Ingressコントローラーからエラーが返されたかどうかを確認します。 詳細については、「Simple log ServiceのNGINX Ingressコントローラポッドのアクセスログの診断」をご参照ください。 Ingressコントローラーからエラーが返された場合は、次のソリューションを使用します。

  • 413エラー

    • 原因: リクエストサイズが上限を超えています。

    • 解決策: IngressコントローラのConfigMapでproxy-body-sizeの値を大きくします。 proxy-body-sizeのデフォルト値は、オープンソースKubernetesのNGINX Ingressコントローラーの場合1 MBであり、proxy-body-sizeのデフォルト値は、ACKのNGINX Ingressコントローラーの場合20 MBです。

  • 499エラー

    • 原因: クライアントは事前に接続を終了します。 このエラーは、Ingressコントローラーまたはバックエンドサービスが原因ではない可能性があります。

    • 解決策:

      • 499エラーが頻繁に発生せず、ワークロードに影響がない場合は、エラーを無視できます。

      • 499エラーが頻繁に発生する場合は、バックエンドポッドがリクエストを処理するのにかかる時間が、クライアントで設定されているリクエストタイムアウト期間を超えているかどうかを確認する必要があります。

  • 502エラー

    • 原因: Ingressコントローラーがバックエンドポッドに接続できません。

    • 解決策:

      • 問題は時々発生します:

        • バックエンドポッドが期待どおりに機能するかどうかを確認します。 バックエンドポッドがオーバーロードされている場合は、バックエンドポッドを追加します。

        • デフォルトでは、IngressコントローラーはHTTP永続接続を介してHTTP 1.1リクエストをバックエンドサービスに送信します。 バックエンドポッドに設定されたアイドル永続接続のタイムアウト期間が、Ingressコントローラーに設定されたタイムアウト期間よりも長いことを確認します。 デフォルトでは、タイムアウト時間は900秒に設定されています。

      • 問題は毎回発生します。

        サービスポートが有効かどうか、およびIngressコントローラポッドからサービスにアクセスできるかどうかを確認します。

        • 問題が解決しない場合は、パケットをキャプチャして分析し、次に チケットを起票します。

    • 503エラー

      • 症状: Ingressコントローラーがバックエンドポッドを検出できないか、Ingressコントローラーがすべてのバックエンドポッドにアクセスできません。

      • 解決策:

        • 問題は時々発生します:

          • 502エラーを解決するためのソリューションを参照してください。

          • バックエンドポッドのステータスを確認し、ヘルスチェックを設定します。

        • 問題は毎回発生します。

          サービス設定が有効かどうか、およびエンドポイントが存在するかどうかを確認します。

        • 上記の方法を使用して原因を特定できない場合は、チケットを起票します。

    次のエラーが発生するのはなぜですか: net::ERR_HTTP2_SERVER_REFUSED_STREAM?

    問題

    Webサイトにアクセスすると、一部のリソースをロードできず、コンソールに次のエラーのいずれかが表示されます。net::ERR_HTTP2_SERVER_REFUSED_STREAMまたはnet::ERR_FAILED

    原因

    リソースへの同時HTTP/2ストリームの数が上限に達しました。

    解決策

    • ConfigMapのhttp2-max-concurrentストリームをより大きな値に変更することを推奨します。 デフォルト値は 128 です。 詳細は、「http2-max-concurrentストリーム」をご参照ください。

    • ConfigMapでuse-http2falseに設定して、HTTP/2を無効にします。 詳細は、「use-http2」をご参照ください。

    次のエラーが発生するのはなぜですか。

    原因

    ServerGroupNameは、namespace + svcName + portの形式で生成されます。 サーバーグループ名は2 ~ 128文字で、英数字、ピリオド (.) 、アンダースコア (_) 、ハイフン (-) を使用できます。 先頭は英字とする必要があります。

    解決策

    必要な形式に基づいてサーバーグループ名を変更します。

    Ingressを作成するときに、「未知の機関によって署名された証明書」エラーが発生するのはなぜですか?

    Ingress

    原因

    複数のIngressがクラスターにデプロイされ、IngressがSecrets、Services、webhook設定などの同じリソースを使用している場合、webhookがトリガーされたときにバックエンドサーバーとの通信に異なるSSL証明書が使用されるため、上記のエラーが発生します。

    解決策

    2つのIngressを再デプロイし、Ingressが異なるリソースを使用するようにします。 Ingressで使用されるリソースの詳細については、ACKコンソールの [アドオン] ページでNGINX Ingressコントローラーを更新した後のシステムの更新は何ですか? RDSインスタンスの

    ヘルスチェックに失敗した後、Ingressコントローラポッドが再起動するのはなぜですか?

    問題

    Ingressコントローラポッドは、ヘルスチェックに失敗すると再起動します。

    原因

    • Ingressコントローラポッドまたはポッドがデプロイされているノードがオーバーロードされています。 その結果、ポッドはヘルスチェックに合格しませんでした。

    • tcp_tw_reusetcp_tw_timestampなどのカーネルパラメーターは、Ingressコントローラポッドがデプロイされているクラスターノードに設定できます。 これにより、ヘルスチェックが失敗する可能性があります。

    解決策

    • Ingressコントローラポッドを追加し、問題が解決しないか確認します。 詳細については、「信頼性の高いIngressアクセスレイヤのデプロイ」をご参照ください。

    • tcp_tw_reuseを無効にするか、パラメーターの値を2に設定し、tcp_tw_timestampsを無効にして、問題が解決するかどうかを確認します。

    TCPまたはUDPを使用するサービスを追加する方法?

    1. tcp-servicesおよびudp-services ConfigMapsに特定のエントリを追加します。 デフォルトでは、ConfigMapsはkube-system名前空間に属します。

      次のコードブロックは、既定の名前空間のexample-goのポート8080をポート9000にマップする方法の例を示しています。

      apiVersion: v1
      kind: ConfigMap
      メタデータ:
        名前: tcp-services
        名前空間: ingress-nginx
      データ:
        9000: "default/example-go:8080"# ポート8080をポート9000にマップします。
    2. NGINX Ingressコントローラーの展開にポート9000を追加します。 デフォルトでは、Deploymentはnginx-ingress-controllerという名前で、kube-system名前空間に属します。

    3. Ingressに関連付けられているサービスにポート9000を追加します。

      サンプルYAMLテンプレート

      apiVersion: v1
      種類: サービス
      メタデータ:
        名前: ingress-nginx
        名前空間: ingress-nginx
        ラベル:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/part-of: ingress-nginx
      spec:
        type: LoadBalancer
        ポート:
          - name: http
            port: 80
            targetPort: 80
            protocol: TCP
          - name: https
            port: 443
            targetPort: 443
            protocol: TCP
          -name: proxied-tcp-9000
            ポート: 9000
            targetPort: 9000
            protocol: TCP
        セレクタ:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/part-of: ingress-nginx 

      TCPまたはUDPを使用するサービスを追加する方法の詳細については、「TCPまたはUDPを使用するサービスの公開」をご参照ください。

    Ingressルールが有効にならないのはなぜですか?

    問題

    Ingressルールを追加または変更した後、ルールは有効になりません。

    原因

    • Ingressの設定にエラーが含まれています。 その結果、IngressはIngressルールをロードできませんでした。

    • Ingressリソースの設定にエラーが含まれています。

    • Ingressコントローラーに必要な権限がありません。 その結果、IngressコントローラーはIngressリソースに加えられた変更を監視できません。

    • 以前のIngressは、server-aliasフィールドで指定されたドメイン名を使用します。 ドメイン名が新しいIngressのドメイン名と競合しています。 その結果、Ingressルールは無視されます。

    解決策

    • Container Intelligence Serviceコンソールに移動し、Ingressを診断し、プロンプトに基づいて問題を解決します。 詳細については、「Ingress診断機能の使用」をご参照ください。

    • 以前のIngressの設定にエラーが含まれているか、または設定の競合が存在するかどうかを確認します。

      • rewrite-targetが使用されず、パスが正規表現で指定されている場合は、nginx.ingress.kubernetes.io/use-regex: "trueアノテーションが追加されていることを確認してください。

      • PathTypeが期待値に設定されているかどうかを確認します。 デフォルトでは、ImplementationSpecificPrefixと同じ効果があります。

    • Ingressコントローラーに関連付けられているClusterRole、ClusterRoleBinding、Role、RoleBinding、およびServiceAccountが存在することを確認します。 デフォルトの名前はingress-nginxです。

    • Ingressコントローラポッドに接続し、nginx.confファイルに追加されたルールを表示します。

    • 次のコマンドを実行して、ポッドログを表示し、原因を特定します。

      kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]

    リクエストがルートディレクトリにリダイレクトされたときに、一部のwebページリソースの読み込みに失敗したり、空白の白い画面が返されたりするのはなぜですか。

    問題

    Ingressでrewrite-targetアノテーションを設定してリクエストを書き換えると、一部のwebページリソースを読み込むことができないか、バックエンドサービスにアクセスすると空白の白い画面が表示されます。

    原因

    • 正規表現ではrewrite-targetを設定しません。

    • リクエストされたリソースのパスは、ルートディレクトリに設定されます。

    解決策

    • 正規表現にrewrite-targetが設定されているかどうか、およびキャプチャグループが使用されているかどうかを確認します。 詳細については、「書き換え」をご参照ください。

    • リクエストが期待されるパスにリダイレクトされるかどうかを確認します。

    ingress-nginx-controllerの更新後にSimple Log Serviceがログを期待どおりに解析できない問題を修正するにはどうすればよいですか?

    問題

    ingress-nginx-controllerコンポーネントには、0.20と0.30の2つの一般的なバージョンがあります。 ACKコンソールの [アドオン] ページでingress-nginx-controllerを0.20から0.30に更新した後、Ingressダッシュボードには、Ingressでカナリアリリースまたは青緑色リリースを実行しても、バックエンドサーバーへのリクエストの実際の統計が表示されません。

    原因

    ingress-nginx-controller 0.20のデフォルトのログ形式は、ingress-nginx-controller 0.30のそれとは異なります。 したがって、ingress-nginx-controllerを0.20から0.30に更新した後、Ingressダッシュボードには、Ingressでカナリアリリースまたは青緑色リリースを実行するときに、バックエンドサーバーへのリクエストの実際の統計が表示されない場合があります。

    解決策

    この問題を修正するには、次の手順を実行してnginx-configuration ConfigMapとk8s-nginx-ingressの設定を更新します。

    1. nginx-configuration ConfigMapを更新します。

      • nginx-configuration ConfigMapを変更していない場合は、次の内容をnginx-configuration.yamlという名前のファイルにコピーし、kubectl apply -f nginx-configuration.yamlコマンドを実行してファイルをデプロイします。

        apiVersion: v1
        kind: ConfigMap
        データ:
          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_stream_local] "$request" $status $body_bytese_sent "$http_user_agent" $http_user_length $request_length $response_upse_proq_$ $$upserge_time] [$pro_case]
          max-worker-connections: "65536"
          proxy-body-size: 20m
          proxy-connect-timeout: "10"
          reuse-port: "true"
          server-tokens: "false"
          ssl-redirect: "false"
          upstream-keepalive-timeout: "900"
          worker-cpu-affinity: auto
        メタデータ:
          ラベル:
            app: ingress-nginx
          name: nginx-configuration
          名前空間: kube-system 
      • nginx-configuration ConfigMapを変更した場合は、次のコマンドを実行して設定を更新します。 これにより、以前の変更は上書きされません。

        kubectl edit configmap nginx-configuration -n kube-system

      log-format-upstreamフィールドに [$proxy_alternative_upstream_name] を追加し、変更を保存して終了します。

    2. 変更します。Modify thek8s-nginx-ingress設定します。

      次のコンテンツをk8s-nginx-ingress.yamlという名前のファイルにコピーし、kubectl apply -f k8s-nginx-ingress.yamlコマンドを実行してデプロイを開始します。

      YAMLファイルの内容を表示する

      apiVersion: log.alibabacloud.com/v1alpha1
      kind: AliyunLogConfig
      メタデータ:
        namespace: kube-system
        #あなたの設定名は、k8sクラスタ内でユニークでなければなりません
        名前: k8s-nginx-ingress
      spec:
        #ログをアップロードするためのログストア名
        logstore: nginx-ingress
        # product code, only for k8s nginx ingress
        productCode: k8s-nginx-ingress
        #logtail 設定の詳細
        logtailConfig:
          inputType:プラグイン
          #logtailの設定名は、[metadata.name]と同じでなければなりません
          configName: k8s-nginx-ingress
          inputDetail:
            プラグイン:
              入力:
              - type: service_docker_stdout
                詳細:
                  IncludeLabel:
                    io.kubernetes.container.name: nginx-ingress-controller
                  標準エラー:false
                  Stdout:true
              プロセッサ:
              - type: processor_regex
                詳細:
                  KeepSource: false
                  Keys:
                  - client_ip
                  - x_forward_for
                  - remote_user
                  - time
                  - method
                  - url
                  - version
                  - 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
                  NoKeyError:true
                  NoMatchError: true
                  Regex: ^(\S +)\s-\s\[([^]]+)]\s-\s(\S +)\s\[(\S +)\s\S +\s "(\w +)\s(\S +)\s([^"]+)\s(\d +)\d +)\s "([^"]*)"\s"([^ "]*)"\s(\S +)\s(\S +)\s(\s +)+ \S [([^]]*)]\s(\S +)\s(\S +)\s(\S +))\s(\S +)\s *(\S *)\s *\[*([^]]*)\]*.*
                  SourceKey: コンテンツ 

    一般的なNGINX Ingressコントローラのエラー

    発行

    NGINX Ingressコントローラポッドのアクセスログを診断する」で説明されている手順に従ってアクセスログを診断すると、コントローラエラーが見つかります。 例:

    ユーザー「system:serviceaccount:kube-system:ingress-nginx」は、APIグループ「xxx」のリソース「xxx」をクラスタースコープ /名前空間「kube-system」に一覧表示 /取得 /更新できません

    原因

    NGINX Ingressコントローラーには、リソースを更新する権限がありません。

    解決策

    • ログデータに基づいて、問題がClusterRoleまたはRoleによって発生しているかどうかを確認します。

      • ログデータにクラスタースコープが含まれている場合、原因はClusterRole (ingress-nginx) です。

      • ログデータに名前空間 "kube-system" が含まれている場合、原因はRole (kube-system/ingrerss-nginx) です。

    • 必要な権限が付与され、ロールバインディングが正しいことを確認してください。

      • 原因がClusterRoleの場合:

        • ClusterRole ingress-nginxおよびClusterRoleBinding ingress-nginxが存在することを確認します。 ClusterRoleとClusterRoleBindingが存在しない場合は、手動で作成するか、関連するコンポーネントを再インストールするか、または チケットを起票してテクニカルサポートをリクエストします。

        • ClusterRole ingress-nginxがログデータに示されている権限を提供できることを確認します。 次の図では、networking.k8s.io/ingressesに対するLIST権限が必要です。 ClusterRoleが対応する権限を提供できない場合は、権限を追加します。77

      • 原因が役割である場合:

        • Role kube-system/ingress-nginxおよびRoleBinding kube-system/ingress-nginxが存在することを確認してください。 RoleとRoleBindingが存在しない場合は、手動で作成するか、関連するコンポーネントを再インストールするか、または チケットを起票してテクニカルサポートをリクエストします。

        • ロールingress-nginxがログデータに示された権限を提供できることを確認します。 次の図では、ingress-controller-leader-nginx ConfigMapに対するUPDATE権限が必要です。 ロールが対応する権限を提供できない場合は、権限を追加します。78

    問題

    NGINX Ingressコントローラポッドのアクセスログを診断する」で説明されている手順に従ってアクセスログを診断すると、コントローラエラーが見つかります。 例:

    requeuing……nginx: 設定ファイルxxxテストに失敗しました (複数行)

    原因

    IngressルールまたはConfigMapの構文エラーにより、NGINX設定のリロードに失敗しました。

    解決策

    • ログのエラーメッセージを確認し、構文エラーを見つけます。 警告メッセージは無視できます。 エラーメッセージが構文エラーの特定に役立たない場合は、エラーメッセージに基づいてポッド内の対応するファイルとコード行を見つけることができます。 たとえば、次の図に示すように、/tmp/nginx/nginx-cfg2825306115ファイルの449行目を見つけます。95

      次のコマンドを実行して、構文エラーを確認します。

      # ポッドにアクセスしてコマンドを実行します。 
      kubectl exec -n <namespace> <コントローラポッド名> -it -- bash
      # 構文エラーと表示行番号を含むファイルを印刷します。 次に、対応する行の構文エラーを確認します。 
      cat -n /tmp/nginx/nginx-cfg2825306115 
    • 構文エラーを見つけて修正します。

    問題

    NGINX Ingressコントローラポッドのアクセスログを診断する」で説明されている手順に従ってアクセスログを診断すると、コントローラエラーが見つかります。 例:

    サーバー「xxx」のSSL証明書「xxx」の予期しないエラー検証

    94

    原因

    証明書に関連付けられているドメイン名がIngressで指定されているドメイン名と異なるため、証明書構成エラーが発生します。 重要度レベルがWarningの証明書エラーが発生した場合は、証明書を正常に使用し続けることができます。 たとえば、証明書にSAN属性がないことをシステムが要求した場合でも、証明書を引き続き使用できます。

    解決策

    証明書が次の要件を満たしていることを確認します。

    • の形式と内容。The format and content of the. certファイルと。キーファイルが有効です。

    • 証明書に関連付けられているドメイン名は、Ingressで指定されているものと同じです。

    • 証明書の有効期限が切れていない。