このトピックでは、Nginx Ingress の問題に関する診断プロセス、トラブルシューティングの考え方、一般的な検査方法、および解決策について説明します。
内容
カテゴリ | 内容 |
診断プロセス | |
トラブルシューティングの考え方 | |
一般的な検査方法 | |
よくある質問と解決策 |
背景情報
Container Service for Kubernetes (ACK) は、オープンソースバージョンに基づいて最適化された NGINX Ingress controller を提供し、完全な互換性とすべてのコミュニティ アノテーションのサポートを備えています。
Ingress が正常に機能するのは、クラスターに NGINX Ingress controller をデプロイして Ingress のルーティングルールを解析する場合のみです。NGINX Ingress controller がルーティングルールに一致するリクエストを受信すると、NGINX Ingress controller はリクエストを対応するバックエンドサービスにルーティングします。バックエンドサービスは、リクエストを Pod に転送します。Kubernetes クラスターでは、サービス、Ingress、および NGINX Ingress controller は次のプロセスで動作します:
サービスは、一連のレプリケートされた Pod で実行されるバックエンドアプリケーションの抽象化です。
Ingress にはリバースプロキシのルールが含まれています。HTTP または HTTPS リクエストがどのサービス Pod にルーティングされるかを制御します。たとえば、リクエストは、リクエスト内のホストと URL パスに基づいて、異なるサービス Pod にルーティングされます。
NGINX Ingress controller は、Ingress ルールを解析するリバースプロキシプログラムです。Ingress ルールに変更が加えられると、NGINX Ingress controller はそれに応じて Ingress ルールを更新します。NGINX Ingress controller がリクエストを受信すると、Ingress ルールに基づいてリクエストをサービス Pod にリダイレクトします。
NGINX Ingress controller は、API サーバーから Ingress ルールの変更を取得し、nginx.conf などの構成ファイルを動的に生成します。これらの構成ファイルは、NGINX などのロードバランサーに必要です。次に、NGINX Ingress controller はロードバランサーを再読み込みします。たとえば、NGINX Ingress controller は nginx -s reload コマンドを実行して NGINX を再読み込みし、新しい Ingress ルールを生成します。
診断プロセス

次の手順に従って、問題が Ingress によって引き起こされているかどうかを確認し、Ingress Controller が正しく構成されていることを確認します。
Controller Pod で、アクセスが期待どおりに機能することを確認します。詳細については、「Controller Pod から Ingress およびバックエンド Pod に手動でアクセスする」をご参照ください。
Nginx Ingress Controller が正しく使用されていることを確認します。詳細については、「Nginx Ingress コミュニティドキュメント」をご参照ください。
Ingress 診断機能を使用して Ingress とコンポーネントの構成を確認し、推奨される変更を適用します。Ingress 診断機能の詳細については、「Ingress 診断機能を使用する」をご参照ください。
トラブルシューティングの考え方 に従って、関連する問題を特定して解決します。
問題が解決しない場合は、次のチェックを実行します:
HTTPS 証明書の問題の場合:
ドメイン名に対して透過的プロキシモードの WAF が有効になっているかどうかを確認します。
有効になっている場合は、WAF または透過的プロキシモードの WAF に TLS 証明書が設定されていないことを確認します。
有効になっていない場合は、次のステップに進みます。
SLB インスタンスがレイヤー 7 リスナーを使用しているかどうかを確認します。
使用している場合は、SLB インスタンスのレイヤー 7 リスナーに TLS 証明書が設定されていないことを確認します。
使用していない場合は、次のステップに進みます。
HTTPS 証明書以外の問題については、Controller Pod のエラーログを確認します。詳細については、「Controller Pod のエラーログを確認する」をご参照ください。
問題が解決しない場合は、Controller Pod と対応するバックエンドアプリケーション Pod でパケットをキャプチャして問題を特定します。詳細については、「パケットをキャプチャする」をご参照ください。
トラブルシューティングの考え方
トラブルシューティングの考え方 | 症状 | 解決策 |
アクセス失敗 | クラスター内の Pod から Ingress にアクセスできない | |
Ingress 自体にアクセスできない | ||
TCP または UDP サービスにアクセスできない | ||
HTTPS アクセスの問題 | 証明書が更新されない、またはデフォルトの証明書が返される | |
| ||
Ingress リソースを追加する際の問題 | 「failed calling webhook...」エラーが報告される | |
Ingress は追加されたが有効にならない | ||
予期しないアクセス動作 | クライアントの送信元 IP アドレスを取得できない | |
IP アドレスのホワイトリストが有効にならない、または期待どおりに機能しない | ||
Ingress によって公開されている gRPC サービスに接続できない | ||
段階的リリースが有効にならない | ||
段階的リリースルールに従ってトラフィックが分散されない、または他のトラフィックが影響を受ける | 段階的リリースルールに基づいてトラフィックが分散されない、または他のトラフィックが段階的リリースサービスにルーティングされる | |
| ||
502、503、413、499 などの HTTP エラーが発生する | ||
ページの読み込み時に一部のリソースの読み込みに失敗する |
| |
リソースにアクセスすると |
一般的な検査方法
Ingress 診断機能を使用する
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、 を選択します。
[トラブルシューティング] ページで、[Ingress 診断] をクリックします。
[Ingress 診断] パネルで、問題のある Ingress の URL (例: https://www.example.com) を入力します。[読み取り、同意しました] を選択し、[診断の開始] をクリックします。
診断が完了したら、診断結果に基づいて問題を解決します。
Simple Log Service (SLS) を使用して Controller Pod のアクセスログを表示する
Ingress Controller のアクセスログ形式は ConfigMap で定義されます。デフォルトの ConfigMap は、kube-system 名前空間の nginx-configuration です。
ACK Ingress Controller のデフォルトのログ形式は次のとおりです:
$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]ログ形式を変更する場合は、SLS のログ収集ルールも変更する必要があります。そうしないと、ログ情報が SLS コンソールに正しく表示されません。ログ形式は慎重に変更してください。
Ingress Controller のログは、SLS コンソールでは次の図のように表示されます。詳細については、「ACK クラスターからコンテナーログを収集する」をご参照ください。

SLS コンソールの一部のログフィールドは、実際のログフィールドとは名前が異なります。次の表にフィールドを示します。
フィールド | 説明 |
| クライアントの実際の IP アドレス。 |
| リクエストメソッド、URL、HTTP バージョンなどのリクエスト情報。 |
| クライアントリクエストの受信から完全な応答の送信までのリクエストの合計時間。この値は、クライアントのネットワーク状態などの要因に影響される可能性があり、リクエストの実際の処理速度を表していない場合があります。 |
| バックエンドアップストリームのアドレス。リクエストがバックエンドに到達しない場合、この値は空になります。バックエンドの障害により複数のアップストリームがリクエストされた場合、この値はカンマ区切りのリストになります。 |
| バックエンドアップストリームによって返される HTTP コード。この値が通常の HTTP ステータスコードである場合、バックエンドアップストリームによって返されます。アクセス可能なバックエンドがない場合、この値は 502 になります。複数の値はカンマ (,) で区切られます。 |
| バックエンドアップストリームの応答時間 (秒単位)。 |
| バックエンドアップストリームの名前。命名規則は |
| バックエンドの代替アップストリームの名前。Canary を使用して設定された段階的リリースサービスなど、リクエストが代替アップストリームに転送された場合、この値は空ではありません。 |
デフォルトでは、次のコマンドを実行して、コンテナー内の最近のアクセスログを直接表示することもできます。
kubectl logs <controller pod name> -n <namespace> | less期待される出力:
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.**.**[]Controller Pod のエラーログを確認する
Ingress Controller Pod のログを使用して、問題の範囲を絞り込むことができます。Controller Pod のエラーログは次のように分類されます:
Controller エラーログ: これらのログは通常、Ingress 構成が正しくない場合に生成されます。次のコマンドを実行して、Controller エラーログをフィルターできます。
kubectl logs <controller pod name> -n <namespace> | grep -E ^[WE]説明Ingress Controller が起動すると、いくつかの警告レベルのエラーが生成されます。これは正常です。たとえば、kubeConfig や Ingress クラスを指定しないことに関する警告メッセージなどは、Ingress Controller の正常な動作に影響を与えないため、無視できます。
Nginx エラーログ: これらのログは通常、リクエストの処理中にエラーが発生した場合に生成されます。次のコマンドを実行して、Nginx エラーログをフィルターできます。
kubectl logs <controller pod name> -n <namespace> | grep error
Controller Pod から Ingress およびバックエンド Pod に手動でアクセスする
次のコマンドを実行して、Controller Pod にログインします。
kubectl exec <controller pod name> -n <namespace> -it -- bashcurl や OpenSSL などのツールは Pod にプリインストールされています。これらのツールを使用して、接続性をテストし、証明書の構成を検証できます。
次のコマンドを実行して、Ingress を介してバックエンドにアクセスできるかどうかをテストします。
# your.domain.com をテストする実際のドメイン名に置き換えます。 curl -H "Host: your.domain.com" http://127.0.**.**/ # http の場合 curl --resolve your.domain.com:443:127.0.0.1 https://127.0.0.1/ # https の場合次のコマンドを実行して、証明書情報を確認します。
openssl s_client -servername your.domain.com -connect 127.0.0.1:443バックエンド Pod にアクセスできるかどうかをテストします。
説明Ingress Controller は、サービス ClusterIP を使用してバックエンド Pod にアクセスしません。代わりに、バックエンド Pod の IP アドレスに直接アクセスします。
kubectl を使用して次のコマンドを実行し、バックエンド Pod の IP アドレスを取得します。
kubectl get pod -n <namespace> <pod name> -o wide期待される出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-dp-7f5fcc7f-**** 1/1 Running 0 23h 10.71.0.146 cn-beijing.192.168.**.** <none> <none>期待される出力から、バックエンド Pod の IP アドレスは 10.71.0.146 です。
Controller Pod から Pod にアクセスする次のコマンドを実行して、Controller Pod からバックエンド Pod への接続が正しく機能していることを確認します。
curl http://<your pod ip>:<port>/path
Nginx Ingress のトラブルシューティング用のコマンド
kubectl-plugin
公式の Kubernetes Ingress controller は元々 Nginx をベースにしていましたが、バージョン 0.25.0 で OpenResty に切り替わりました。controller は API Server 上の Ingress リソースの変更をリッスンし、対応する Nginx 構成を自動的に生成し、その後構成を再読み込みして変更を適用します。詳細については、「公式ドキュメント」をご参照ください。
Ingress の数が増えるにつれて、すべての構成が単一の Nginx.conf ファイルに統合されます。これにより、構成ファイルが長くなり、デバッグが困難になります。バージョン 0.14.0 以降、アップストリーム部分は lua-resty-balancer を使用して動的に生成されるようになり、デバッグがさらに複雑になりました。Ingress-nginx 構成のデバッグを簡素化するために、コミュニティは ingress-nginx という名前の kubectl プラグインを提供しました。詳細については、「kubectl-plugin」をご参照ください。
次のコマンドを実行して、ingress-nginx controller に認識されているバックエンドサービスに関する情報を取得します。
kubectl ingress-nginx backends -n ingress-nginxdbg コマンド
kubectl-plugin に加えて、
dbgコマンドを使用して関連情報を表示および診断することもできます。次のコマンドを実行して、Nginx Ingress コンテナーにログインします。
kubectl exec -itn kube-system <nginx-ingress-pod-name> bash/dbgコマンドを実行します。次の出力が返されます。nginx-ingress-controller-69f46d8b7-qmt25:/$ /dbg dbg is a tool for quickly inspecting the state of the nginx instance Usage: dbg [command] Available Commands: backends Inspect the dynamically-loaded backends information certs Inspect dynamic SSL certificates completion Generate the autocompletion script for the specified shell conf Dump the contents of /etc/nginx/nginx.conf general Output the general dynamic lua state help Help about any command Flags: -h, --help help for dbg --status-port int Port to use for the lua HTTP endpoint configuration. (default 10246) Use "dbg [command] --help" for more information about a command.
特定のドメイン名の証明書が存在するかどうかを確認します。
/dbg certs get <hostname>現在のすべてのバックエンドサービスに関する情報を表示します。
/dbg backends all
Nginx Ingress のステータス
Nginx には、ランタイム統計を出力する自己チェックモジュールが含まれています。Nginx Ingress コンテナーでは、curl コマンドを実行してポート 10246 の nginx_status にアクセスし、Nginx のリクエストと接続の統計を表示できます。
次のコマンドを実行して、Nginx Ingress コンテナーにログインします。
kubectl exec -itn kube-system <nginx-ingress-pod-name> bash次のコマンドを実行して、Nginx の現在のリクエストと接続の統計を表示します。
nginx-ingress-controller-79c5b4d87f-xxx:/etc/nginx$ curl localhost:10246/nginx_status Active connections: 12818 server accepts handled requests 22717127 22717127 823821421 Reading: 0 Writing: 382 Waiting: 12483Nginx の起動以来、22,717,127 の接続を受け入れ、823,821,421 のリクエストを処理しました。これは、各接続が平均で約 36.2 のリクエストを処理したことを意味します。
Active connections: Nginx サーバー上のアクティブな接続の総数は 12,818 です。
Reading: Nginx が現在リクエストヘッダーを読み取っている接続の数は 0 です。
Writing: Nginx が現在応答を送信している接続の数は 382 です。
Waiting: キープアライブ接続の数は 12,483 です。
パケットをキャプチャする
問題を特定できない場合は、さらなる診断のためにパケットをキャプチャする必要があります。
最初の問題の場所に基づいて、ネットワークの問題が Ingress Pod にあるか、アプリケーション Pod にあるかを判断します。情報が不十分な場合は、両方からパケットをキャプチャできます。
問題のあるアプリケーション Pod または Ingress Pod があるノードにログインします。
ECS インスタンス (コンテナー内ではない) で、次のコマンドを実行して Ingress トラフィック情報をファイルにキャプチャします。
tcpdump -i any host <application pod IP or Ingress pod IP> -C 20 -W 200 -w /tmp/ingress.pcapログを監視します。予期されるエラーが発生したら、パケットのキャプチャを停止します。
アプリケーションログのエラーメッセージを使用して、エラーの正確な時刻に対応するメッセージを特定します。
説明通常の状況では、パケットキャプチャはアプリケーションに影響を与えません。CPU 負荷とディスク書き込みがわずかに増加するだけです。
上記のコマンドは、キャプチャされたパケットをローテーションします。最大 200 個の .pcap ファイルを書き込むことができ、各ファイルのサイズは 20 MB です。
クラスター内からクラスター LoadBalancer の外部アドレスにアクセスできない
症状
クラスター内の一部のノード上の一部の Pod が、Nginx Ingress Controller の外部アドレス (SLB インスタンスの IP アドレス) を介してバックエンド Pod にアクセスできない場合がありますが、他の Pod はアクセスできます。
原因
この問題は、Controller のサービスの externalTrafficPolicy 構成が原因です。この構成は、外部トラフィックの処理方法を決定します。local に設定すると、Controller の Pod と同じノード上のバックエンド Pod のみがリクエストを受信できます。cluster に設定すると、アクセスは成功します。外部 LoadBalancer アドレスを使用してサービスにアクセスするクラスター内のリソースからのリクエストも、外部トラフィックとして扱われます。
解決策
(推奨) Kubernetes クラスター内のサービスに、その ClusterIP または Ingress サービス名を使用してアクセスします。Ingress サービス名は
nginx-ingress-lb.kube-systemです。kubectl edit svc nginx-ingress-lb -n kube-systemコマンドを実行して Ingress サービスを変更します。LoadBalancer サービスでexternalTrafficPolicyをClusterに設定します。クラスターのコンテナーネットワークプラグインが Flannel の場合、クライアントの送信元 IP アドレスは失われます。Terway を使用する場合、送信元 IP アドレスは保持できます。
例:
apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/backend-type: eni # Direct ENI access. labels: app: nginx-ingress-lb name: nginx-ingress-lb namespace: kube-system spec: externalTrafficPolicy: Clusterサービスアノテーションの詳細については、「アノテーションを使用して Classic Load Balancer (CLB) インスタンスを構成する」をご参照ください。
Ingress Controller 自体にアクセスできない
症状
Flannel クラスターの場合、ドメイン名、SLB IP アドレス、または ClusterIP を使用して自身の Pod 内から Ingress にアクセスすると、一部またはすべてのリクエストが失敗します。
原因
Flannel のデフォルト構成では、ループバックアクセスが許可されていません。
解決策
(推奨) 可能であれば、クラスターを再作成し、Terway ネットワークプラグインを使用します。既存のクラスターのアプリケーションを Terway モードのクラスターに移行します。
クラスターを再作成できない場合は、Flannel 構成を変更して
hairpinModeを有効にすることで問題を解決できます。構成を変更した後、Flannel Pod を再作成して変更を有効にします。次のコマンドを実行して Flannel を編集します。
kubectl edit cm kube-flannel-cfg -n kube-system返された cni-conf.json で、
delegateセクションに"hairpinMode": trueを追加します。例:
cni-conf.json: | { "name": "cb0", "cniVersion":"0.3.1", "type": "flannel", "delegate": { "isDefaultGateway": true, "hairpinMode": true } }次のコマンドを実行して Flannel を削除し、再作成します。
kubectl delete pod -n kube-system -l app=flannel
クラスターで TLS 証明書が追加または変更されたが、アクセスにはデフォルトまたは古い証明書がまだ使用されている
症状
クラスターに Secret を追加または変更し、Ingress で secretName を指定した後、Ingress にアクセスすると、まだデフォルトの証明書 (Kubernetes Ingress Controller Fake Certificate) または古い証明書が使用されます。
原因
証明書がクラスター内の Ingress Controller によって返されていません。
証明書が無効で、Controller によって正しく読み込まれませんでした。
Ingress Controller は、サーバ名表示 (SNI) に基づいて対応する証明書を返しますが、TLS ハンドシェイク中に SNI が含まれていなかった可能性があります。
解決策
次のいずれかの方法を使用して、TLS 接続の確立時に SNI フィールドが含まれていたかどうかを確認します:
SNI をサポートする新しいバージョンのブラウザを使用します。
openssl s_clientコマンドを使用して証明書をテストする場合は、-servernameパラメーターを含めます。curlコマンドを使用する場合は、IP アドレスと Host リクエストヘッダーメソッドを使用する代わりに、hosts エントリを追加するか、--resolveパラメーターを使用してドメイン名をマッピングします。
WAF、透過的プロキシモードの WAF、または SLB レイヤー 7 リスナーに TLS 証明書が設定されていないことを確認します。TLS 証明書は、クラスター内の Ingress Controller によって返される必要があります。
ACK コンソールで Ingress 診断を実行して、構成エラーとエラーログを確認します。詳細については、「Ingress 診断機能を使用する」をご参照ください。
次のコマンドを実行して、Ingress Pod のエラーログを手動で表示し、ログに基づいて修正を適用します。
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"。クライアントがリクエストを送信する際に、TLS ポートを使用し、トラフィックを暗号化していることを確認します。
バックエンド HTTPS サービスに接続できない
症状
Ingress を介してバックエンド HTTPS サービスにアクセスできません。
応答が 400 エラーで、メッセージが
The plain HTTP request was sent to HTTPS portである可能性があります。
原因
Ingress Controller からバックエンド Pod へのリクエストは、デフォルトの HTTP プロトコルを使用します。
解決策
Ingress リソースにアノテーションを設定します: nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"。
Ingress Pod で送信元 IP アドレスを保持できない
症状
クライアントの実際の IP アドレスが Ingress Pod に保持されません。ノードの IP アドレス、100.XX.XX.XX の範囲のアドレス、または別のアドレスとして表示されます。
原因
Ingress で使用されるサービスの
externalTrafficPolicyがClusterに設定されています。SLB インスタンスでレイヤー 7 プロキシが使用されています。
透過的プロキシモードの WAF が使用されています。
解決策
externalTrafficPolicyがClusterに設定され、フロントエンドでレイヤー 4 SLB インスタンスが使用されている場合。externalTrafficPolicyをLocalに変更できます。ただし、これにより、クラスター内から SLB IP アドレスを使用して Ingress にアクセスしようとすると失敗する可能性があります。解決策については、「クラスター内からクラスター LoadBalancer の外部アドレスにアクセスできない」をご参照ください。レイヤー 7 プロキシ (レイヤー 7 SLB、WAF、または透過的プロキシモードの WAF) が使用されている場合は、次の手順に従います:
レイヤー 7 プロキシが使用され、X-Forwarded-For リクエストヘッダーが有効になっていることを確認します。
Ingress Controller の ConfigMap (デフォルトは kube-system 名前空間の nginx-configuration) に、
enable-real-ip: "true"を追加します。ログを監視して、送信元 IP アドレスが取得できるかどうかを確認します。
複数の転送がある長いリンクパス (たとえば、Ingress Controller の前にリバースプロキシサービスが追加で構成されている) の場合、
enable-real-ipを有効にした後、ログのremote_addrの値を監視して、実際の IP アドレスが X-Forwarded-For リクエストヘッダーを介して Ingress コンテナーに渡されているかどうかを判断できます。そうでない場合は、リクエストが Ingress Controller に到達する前に、X-Forwarded-For などの方法でクライアントの実際の IP アドレスが運ばれるようにします。
段階的リリースルールが有効にならない
症状
クラスターに段階的リリースが設定されていますが、段階的リリースルールが有効になりません。
原因
考えられる理由は 2 つあります:
canary-*関連のアノテーションを使用する場合、nginx.ingress.kubernetes.io/canary: "true"が設定されていません。0.47.0 より前の Nginx Ingress Controller バージョンで
canary-*関連のアノテーションを使用する場合、Ingress ルールの Host フィールドにアプリケーションのドメイン名を指定する必要があります。空にすることはできません。
解決策
原因に基づいて、Ingress ルールの
nginx.ingress.kubernetes.io/canary: "true"または Host フィールドを変更します。詳細については、「ルーティングルール」をご参照ください。上記に該当しない場合は、「段階的リリースルールに基づいてトラフィックが分散されない、または他のトラフィックが段階的リリースサービスにルーティングされる」をご参照ください。
段階的リリースルールに基づいてトラフィックが分散されない、または他のトラフィックが段階的リリースサービスにルーティングされる
症状
段階的リリースルールが設定されていますが、ルールに従ってトラフィックが分散されない、または他の通常の Ingress からのトラフィックが段階的リリースサービスにルーティングされます。
原因
Nginx Ingress Controller では、段階的リリースルールは単一の Ingress に適用されるのではなく、同じサービスを使用するすべての Ingress に適用されます。
この問題の詳細については、「Ingress with canary annotation will affect all ingresses with same service」をご参照ください。
解決策
段階的リリースが必要な Ingress (service-match および canary-* 関連のアノテーションを使用するものを含む) については、元の Pod を指す個別のサービス (本番サービスと段階的リリースサービスの両方) を作成します。次に、その Ingress の段階的リリースを有効にします。詳細については、「Nginx Ingress を使用して段階的リリースとブルーグリーンデプロイメントを実装する」をご参照ください。
Ingress リソースを作成するときに「failed calling webhook」エラーが報告される
症状
Ingress リソースを追加すると、次の図に示すように、「Internal error occurred: failed calling webhook...」というメッセージが表示されます。

原因
Ingress リソースが追加されると、その有効性はサービス (デフォルトでは ingress-nginx-controller-admission) によって検証される必要があります。リンクに問題がある場合 (たとえば、サービスが削除されたり、Ingress controller が削除されたりした場合)、検証は失敗し、Ingress リソースは追加できません。
解決策
Webhook リンクをチェックして、すべてのリソースが存在し、正しく機能していることを確認します。リンクは ValidatingWebhookConfiguration -> Service -> Pod です。
Ingress Controller Pod の admission 機能が有効になっており、Pod が外部からアクセスできることを確認します。
Ingress Controller が削除されたか、Webhook 機能が不要な場合は、ValidatingWebhookConfiguration リソースを直接削除できます。
HTTPS アクセスで SSL_ERROR_RX_RECORD_TOO_LONG エラーが報告される
症状
HTTPS 経由でアクセスすると、SSL_ERROR_RX_RECORD_TOO_LONG または routines:CONNECT_CR_SRVR_HELLO:wrong version number エラーが報告されます。
原因
HTTPS リクエストが、HTTP ポートなどの非 HTTPS ポートにアクセスしています。
一般的な原因は次のとおりです:
SLB インスタンスのポート 443 が Ingress Pod のポート 80 にバインドされています。
Ingress Controller に対応するサービスのポート 443 が Ingress Pod のポート 80 にマッピングされています。
解決策
必要に応じて SLB 設定またはサービス設定を変更して、HTTPS が正しいポートにアクセスできるようにします。
一般的な HTTP エラーコードが表示される
症状
リクエストは、502、503、413、499 などの 2xx または 3xx 以外のステータスコードを返します。
原因と解決策
ログをチェックして、エラーが Ingress Controller によって返されたかどうかを判断します。詳細については、「Simple Log Service (SLS) を使用して Controller Pod のアクセスログを表示する」をご参照ください。その場合は、次の解決策を参照してください:
413 エラー
原因: リクエストデータのサイズが構成された制限を超えています。
解決策:
kubectl edit cm -n kube-system nginx-configurationを実行して Controller 構成を変更します。必要に応じてnginx.ingress.kubernetes.io/client-max-body-sizeとnginx.ingress.kubernetes.io/proxy-body-sizeの値を調整します。デフォルト値は20mです。
499 エラー
原因: サーバーが応答を送信する前にクライアントが切断しました。これは必ずしもコンポーネントやバックエンドアプリケーションの問題ではありません。
解決策:
少数の 499 エラーは、アプリケーションによっては正常な場合があり、無視できます。
多くの 499 エラーが発生する場合は、バックエンドアプリケーションの処理時間とフロントエンドリクエストのタイムアウトが期待どおりかどうかを確認します。
502 エラー
原因: Nginx Ingress は正しく機能していますが、Nginx Ingress Pod がターゲットのバックエンド Pod に接続できません。
解決策:
トリガー条件:
バックエンドサービスと Pod の構成が正しくない可能性があります。バックエンドサービスのポート構成とコンテナー内のアプリケーションコードを確認します。
断続的な問題
Nginx Ingress Controller の Pod の負荷が高い可能性があります。Controller の SLB インスタンスのリクエスト数と接続数を確認して負荷を評価し、必要に応じて Controller にリソースを追加できます。詳細については、「高可用性 Nginx Ingress Controller のデプロイ」をご参照ください。
バックエンド Pod がセッションを積極的に閉じている可能性があります。Nginx Ingress Controller はデフォルトで持続的接続を有効にします。バックエンドの持続的接続のアイドルタイムアウトが Controller のアイドルタイムアウト (デフォルトは 900 秒) より大きいことを確認します。
これらの方法で問題が特定できない場合は、キャプチャしたパケットを分析します。
503 エラー
原因: Ingress Controller がリクエストをルーティングするための利用可能なバックエンド Pod を見つけられません。
解決策:
まれなシナリオ
502 エラーの解決策を参照してください。
バックエンドアプリケーションの準備完了ステータスを確認し、適切なヘルスチェックを構成します。
エラーが持続する場合:
バックエンドサービスが正しく構成されているか、およびエンドポイントが存在するかどうかを確認します。
net::ERR_HTTP2_SERVER_REFUSED_STREAM エラーが発生する
症状
Web ページにアクセスすると、一部のリソースが正しく読み込まれず、コンソールに net::ERR_HTTP2_SERVER_REFUSED_STREAM または net::ERR_FAILED エラーが表示されます。
原因
並列リソースリクエストの数が多く、HTTP/2 の最大同時ストリーム制限に達しています。
解決策
(推奨) ConfigMap で、必要に応じて
http2-max-concurrent-streamsの値を増やします。デフォルトは 128 です。詳細については、「http2-max-concurrent-streams」をご参照ください。ConfigMap で、
use-http2をfalseに設定して HTTP/2 サポートを無効にします。詳細については、「use-http2」をご参照ください。
「The param of ServerGroupName is illegal」エラーが発生する
原因
ServerGroupName を生成するためのフォーマットは namespace+svcName+port です。サーバーグループ名は 2〜128 文字の長さで、文字または漢字で始まり、数字、ピリオド (.)、アンダースコア (_)、およびハイフン (-) を含めることができます。
解決策
サーバーグループの命名要件に準拠するように名前を変更します。
Ingress を作成するときに「certificate signed by unknown authority」エラーが報告される

原因
Ingress を作成すると、前の図に示されているエラーが発生します。これは、複数の Ingress controller がデプロイされ、それらが同じリソース (Secret、サービス、Webhook 構成などを含む場合があります) を使用しているためです。これにより、Webhook の実行中に使用される SSL 証明書がバックエンドサービスと一致しなくなり、エラーが発生します。
解決策
2 つの Ingress controller を再デプロイし、それらのリソースが重複しないようにします。Ingress に含まれるリソースの詳細については、「ACK コンポーネント管理で Nginx Ingress Controller コンポーネントをアップグレードすると、システムにどのような更新が行われますか?」をご参照ください。
ヘルスチェックに失敗したため Ingress Pod が再起動する
症状
Controller Pod がヘルスチェックに失敗し、再起動します。
原因
Ingress Pod またはそのノードの負荷が高く、ヘルスチェックが失敗します。
クラスターノードで
tcp_tw_reuseまたはtcp_timestampsカーネルパラメーターが設定されているため、ヘルスチェックが失敗する可能性があります。
解決策
Ingress Pod をスケールアウトし、問題が解決するかどうかを監視します。詳細については、「Nginx Ingress Controller の高可用性デプロイメント」をご参照ください。
tcp_tw_reuseを無効にするか、2 に設定し、tcp_timestampsも無効にします。その後、問題が解決するかどうかを監視します。
TCP および UDP サービスを追加する
対応する ConfigMap (デフォルトでは、kube-system 名前空間の tcp-services と udp-services) に、対応するエントリを追加します。
たとえば、デフォルト名前空間の example-go のポート 8080 をポート 9000 にマッピングするには、次の例を参照してください。
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: ingress-nginx data: 9000: "default/example-go:8080" # ポート 8080 をポート 9000 にマッピングします。Ingress デプロイメント (デフォルトでは、kube-system 名前空間の nginx-ingress-controller) に、マッピングされたポートを追加します。
Ingress に対応するサービスに、マッピングされたポートを追加します。
TCP および UDP サービスの追加の詳細については、「TCP および UDP サービスの公開」をご参照ください。
Ingress ルールが有効にならない
症状
Ingress ルールが追加または変更されても有効になりません。
原因
Ingress 構成のエラーにより、新しい Ingress ルールが正しく読み込まれません。
Ingress リソースが正しく構成されておらず、期待される構成と一致しません。
Ingress Controller に権限の問題があり、Ingress リソースの変更を正しく監視できません。
古い Ingress が、新しい Ingress と競合するドメイン名に
server-alias構成を使用しているため、ルールが無視されます。
解決策
ACK コンソールの Ingress 診断ツールを使用して問題を診断し、プロンプトに従います。詳細については、「Ingress 診断機能を使用する」をご参照ください。
古い Ingress の構成エラーまたは競合を確認します:
rewrite-target以外の場合で、パスに正規表現が使用されている場合は、アノテーションnginx.ingress.kubernetes.io/use-regex: "true"が構成されていることを確認します。PathType が期待と一致するかどうかを確認します。デフォルトでは、
ImplementationSpecificはPrefixと同じ効果があります。
Ingress Controller に関連付けられている ClusterRole、ClusterRoleBinding、Role、RoleBinding、および ServiceAccount がすべて存在することを確認します。これらのリソースのデフォルト名は ingress-nginx です。
Controller Pod にログインし、nginx.conf ファイルに追加されたルールを表示します。
次のコマンドを実行して、コンテナーのログを手動で表示し、問題を特定します。
kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]
ルートディレクトリへの書き換え後に一部のリソースの読み込みに失敗するか、空白の画面が表示される
症状
Ingress rewrite-target アノテーションを使用してアクセスを書き換えた後、一部のページリソースの読み込みに失敗するか、空白の画面が表示されます。
原因
rewrite-targetが正規表現で構成されていない可能性があります。アプリケーションのリソースリクエストパスがルートディレクトリにハードコーディングされています。
解決策
rewrite-targetが正規表現とキャプチャグループで使用されているかどうかを確認します。詳細については、「Rewrite」をご参照ください。フロントエンドリクエストが正しいパスにアクセスしているかどうかを確認します。
アップグレード後に SLS での異常なログ解析を修正する方法
症状
ingress-nginx-controller コンポーネントには現在、0.20 と 0.30 の 2 つの主要なバージョンがあります。コンソールの [コンポーネント] ページからバージョン 0.20 から 0.30 にアップグレードした後、Ingress の段階的リリースまたはブルーグリーンデプロイメント機能を使用すると、Ingress ダッシュボードが実際のバックエンドサービスのアクセスステータスを正しく表示しない場合があります。
原因
バージョン 0.20 と 0.30 のデフォルトの出力形式が異なるため、Ingress の段階的リリースまたはブルーグリーンデプロイメント機能を使用すると、Ingress ダッシュボードが実際のバックエンドサービスのアクセスステータスを正しく表示しない場合があります。
解決策
nginx-configuration configmap と k8s-nginx-ingress 構成を更新して問題を修正するには、次の手順を実行します。
nginx-configuration configmapを更新します。nginx-configuration configmapを変更していない場合は、次の内容をnginx-configuration.yamlとして保存し、kubectl apply -f nginx-configuration.yamlコマンドを実行してデプロイします。apiVersion: v1 kind: ConfigMap 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: "10" reuse-port: "true" server-tokens: "false" ssl-redirect: "false" upstream-keepalive-timeout: "900" worker-cpu-affinity: auto metadata: labels: app: ingress-nginx name: nginx-configuration namespace: kube-systemnginx-configuration configmapを変更した場合は、次のコマンドを実行して修正し、構成が上書きされないようにします:kubectl edit configmap nginx-configuration -n kube-system
log-format-upstreamフィールドの末尾に[$proxy_alternative_upstream_name]を追加し、保存して終了します。k8s-nginx-ingress構成を更新します。次の内容を
k8s-nginx-ingress.yamlファイルとして保存し、kubectl apply -f k8s-nginx-ingress.yamlコマンドを実行してデプロイします。
「cannot list/get/update resource」エラーが発生する
症状
Controller Pod のエラーログを確認する で説明されている方法を使用して、Pod 内の Controller エラーログを見つけることができます。ログは次のようになります:
User "system:serviceaccount:kube-system:ingress-nginx" cannot list/get/update resource "xxx" in API group "xxx" at the cluster scope/ in the namespace "kube-system"原因
Nginx Ingress Controller には、関連するリソースを更新するために必要な権限がありません。
解決策
ログに基づいて、問題が ClusterRole または Role によって引き起こされているかどうかを判断します。
ログに
at the cluster scopeが含まれている場合、問題は ClusterRole (ingress-nginx) にあります。ログに
in the namespace "kube-system"が含まれている場合、問題は Role (kube-system/ingress-nginx) にあります。
対応する権限と権限バインディングが完全であることを確認します。
ClusterRole の場合:
ClusterRole
ingress-nginxと ClusterRoleBindingingress-nginxが存在することを確認します。存在しない場合は、作成、復元、またはコンポーネントのアンインストールと再インストールができます。ClusterRole
ingress-nginxにログに対応する権限 (この例では、networking.k8s.io/ingresses の List 権限) が含まれていることを確認します。権限が存在しない場合は、手動で ClusterRole に追加できます。
Role の場合:
Role
kube-system/ingress-nginxと RoleBindingkube-system/ingress-nginxが存在することを確認します。存在しない場合は、作成、復元、またはコンポーネントのアンインストールと再インストールができます。Role
ingress-nginxにログに対応する権限 (この例では、ConfigMapingress-controller-leader-nginxの Update 権限) が含まれていることを確認します。権限が存在しない場合は、手動で Role に追加できます。
「configuration file failed」エラーが発生する
症状
Controller Pod のエラーログを確認する で説明されている方法を使用して、Pod 内の Controller エラーログを見つけることができます。ログは次のようになります:
requeuing……nginx: configuration file xxx test failed (multiple lines)原因
構成エラーにより、Nginx 構成の再読み込みが失敗しました。これは通常、Ingress ルールまたは ConfigMap に挿入されたスニペットの構文エラーが原因です。
解決策
ログのエラーメッセージを確認して (警告レベルのメッセージは無視できます)、問題をおおよそ特定します。エラーメッセージが明確でない場合は、エラーメッセージのファイル行番号を使用して、Pod 内の対応するファイルを表示できます。次の例では、ファイルは /tmp/nginx/nginx-cfg2825306115 で、行は 449 です。

次のコマンドを実行して、対応する行の近くの構成にエラーがないか確認します。
# Pod でコマンドを実行します。 kubectl exec -n <namespace> <controller pod name> -it -- bash # エラーファイルを番号付きで表示し、対応する行の近くの構成にエラーがないか確認します。 cat -n /tmp/nginx/nginx-cfg2825306115エラーメッセージと構成ファイルに基づいて、エラーの原因を特定し、実際の構成に従って修正します。
「Unexpected error validating SSL certificate」エラーが発生する
症状
Controller Pod のエラーログを確認する で説明されている方法を使用して、Pod 内の Controller エラーログを見つけることができます。ログは次のようになります:
Unexpected error validating SSL certificate "xxx" for server "xxx"
原因
証明書の構成が正しくありません。一般的な理由は、証明書に含まれるドメイン名が Ingress で構成されたドメイン名と一致しないことです。証明書に SAN 拡張がないなど、一部の警告レベルのログは、証明書の通常の使用に影響を与えません。実際状況に基づいて問題があるかどうかを判断します。
解決策
エラーメッセージに基づいて、クラスター内の証明書の問題を確認します。
証明書の cert と key のフォーマットと内容は正しいですか?
証明書に含まれるドメイン名は、Ingress で構成されたドメイン名と一致しますか?
証明書は期限切れですか?
多くの構成ファイルが Controller からクリアされない
症状
Nginx Ingress Controller の以前のバージョン (1.10 より前) には、既知のバグがあります。通常の状況では、生成された nginx-cfg ファイルは迅速にクリアされるはずです。ただし、Ingress 構成が正しくなく、レンダリングされた nginx.conf ファイルでエラーが発生した場合、これらの不正な構成ファイルは期待どおりにクリアされません。これにより、nginx-cfgxxx ファイルが蓄積され、大量のディスク領域を消費します。

原因
原因はクリーンアップロジックの欠陥です。正しく生成された構成ファイルは適切にクリーンアップされますが、無効な構成ファイルに対してはクリーンアップメカニズムが機能せず、システムに残ってしまいます。詳細については、「コミュニティの GitHub Issue #11568」をご参照ください。
解決策
この問題を解決するには、次の解決策を検討してください。
Nginx Ingress Controller のアップグレード: Nginx Ingress Controller をバージョン 1.10 以降にアップグレードすることをお勧めします。詳細については、「Nginx Ingress Controller コンポーネントのアップグレード」をご参照ください。
古いファイルの手動クリア: クリアされていない
nginx-cfgxxxファイルを定期的に削除します。スクリプトを記述してこのプロセスを自動化し、手動の作業負荷を軽減できます。構成エラーの確認: 新しい Ingress 構成を適用する前に、その正しさを慎重に確認して、無効な構成ファイルが生成されないようにします。
Controller のアップグレード後に Pod が Pending 状態のままになる問題のトラブルシューティング
症状
Nginx Ingress Controller をアップグレードすると、Pod がスケジュールに失敗し、長時間 Pending 状態のままになることがあります。
原因
Nginx Ingress Controller をアップグレードすると、デフォルトのノードアフィニティとポッドアンチアフィニティルールのため、新しいバージョンの Pod がスケジュールに失敗することがあります。クラスターに十分な利用可能なリソースがあることを確認する必要があります。
次のコマンドを使用して、具体的な原因を表示できます:
kubectl -n kube-system describe pod <pending-pod-name>kubectl -n kube-system get events解決策
この問題を解決するには、次の解決策を検討してください。
クラスターリソースのスケールアウト: 新しいノードを追加して、アフィニティルールの要件を満たします。詳細については、「ノードプールを手動でスケールする」をご参照ください。
アフィニティの調整: リソースが制約されている状況では、
kubectl edit deploy nginx-ingress-controller -n kube-systemコマンドを実行してアンチアフィニティ要件を緩和し、Pod が同じノードにスケジュールされるようにすることができます。この方法では、コンポーネントの高可用性が低下する可能性があります。
高同時実行性の Flannel CNI および IPVS クラスターで Nginx Ingress に複数の CLB インスタンスを使用すると TCP ストリームの混乱が発生する
症状
Flannel CNI と IPVS ネットワークモードを使用する ACK クラスターで、Nginx Ingress Controller が複数の Classic Load Balancer (CLB) インスタンスにバインドされている場合、高同時実行性の状況で TCP ストリームの混乱が発生することがあります。パケットキャプチャで次の異常が明らかになる場合があります。
パケットの再送
異常な TCP 接続リセット

原因
Flannel ネットワークプラグインで構成された ACK クラスターでは、CLB インスタンスは Nginx Ingress Controller が配置されているノードの NodePort にトラフィックを転送します。ただし、複数のサービスが異なる NodePort を使用する場合、高同時実行シナリオで IPVS セッションの競合が発生する可能性があります。
解決策
単一ロードバランサー戦略: Nginx Ingress Controller 用に LoadBalancer サービスを 1 つだけ作成します。他の CLB インスタンスを手動で構成して、ノードの NodePort にバインドし、競合の可能性を減らします。
複数の NodePort が同時にアクティブになるのを避ける: 同じノード上で、複数の NodePort が同時にアクティブになるのを避けて、IPVS セッション競合のリスクを減らします。