このトピックでは、NGINX Ingress Controller に関するよくある質問とその回答を紹介します。TLS/SSL 証明書、設定、パフォーマンス、トラブルシューティングなどをカバーしています。
NGINX Ingress Controller の旧バージョンにおける既知の問題
旧バージョンには以下の既知の問題があります。安定性を確保するために、最新バージョンへのアップグレードを推奨します。
Ingress の defaultBackend パラメーター値が NGINX Ingress Controller のグローバル設定を上書きする
影響を受けるバージョン:1.2.1-aliyun.1 以前。
解決策:NGINX Ingress Controller をバージョン 1.5.1-aliyun.1 以降にアップグレードします。
nginx-cfg-xx の一時設定ファイルがクリアされず、ディスクがいっぱいになる可能性がある
影響を受けるバージョン:1.10.2-aliyun.1 以前。
解決策:NGINX Ingress Controller をバージョン 1.10.4-aliyun.1 以降にアップグレードします。
原因:
client-body-buffer-sizeの値が 32 ビット整数のストレージ上限を超えているためです。解決策:
client-body-buffer-sizeを200Mのような小さい値に設定します。
サポートされている TLS バージョン
Ingress-nginx は TLS 1.2 と TLS 1.3 をサポートしています。1.2 より前の TLS バージョンを使用しているクライアントは、ハンドシェイクエラーが発生する可能性があります。
追加の TLS バージョンをサポートするには、kube-system 名前空間の nginx-configuration ConfigMap に以下を追加します。詳細については、「TLS/HTTPS」をご参照ください。
NGINX Ingress Controller 1.7.0 以降で TLS 1.0 または 1.1 を有効にするには、ssl-ciphers パラメーターに @SECLEVEL=0 を指定する必要があります。

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:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
ssl-protocols: "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"リクエストヘッダーはバックエンドサーバーに渡されるか
デフォルトでは、ingress-nginx はレイヤー 7 のリクエストヘッダーをバックエンドサーバーに渡しますが、非標準の HTTP ヘッダー (例:Mobile Version) は除外します。これらのヘッダーを保持するには、kubectl edit cm -n kube-system nginx-configuration を実行して ConfigMap を更新します。詳細については、「ConfigMap」をご参照ください。
enable-underscores-in-headers: trueHTTPS バックエンドサーバーへのリクエスト転送方法
ingress-nginx を介して HTTPS バックエンドサーバーにリクエストを転送するには、Ingress に次のアノテーションを追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: xxxx
annotations:
# バックエンドサーバーが使用するプロトコルとして HTTPS を指定する必要があります。
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"レイヤー 7 でクライアント IP アドレスを渡す方法
デフォルトでは、ingress-nginx は X-Forward-For および X-Real-IP ヘッダーを追加してクライアント IP アドレスを渡します。ただし、クライアントが既にこれらのヘッダーを含んでいる場合、バックエンドサーバーは元のクライアント IP を取得できません。
kubectl edit cm -n kube-system nginx-configuration コマンドを実行して nginx-configuration ConfigMap を変更します。これにより、ingress-nginx はレイヤー 7 でクライアント IP アドレスを渡すことができます。
compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"トラフィックが NGINX Ingress に到達する前に複数のアップストリームプロキシサーバーを通過する場合、proxy-real-ip-cidr フィールドを nginx-configuration ConfigMap に追加し、proxy-real-ip-cidr の値をアップストリームプロキシサーバーの CIDR ブロックに設定する必要があります。複数の CIDR ブロックはカンマ (,) で区切ります。詳細については、「WAF の使用」をご参照ください。
proxy-real-ip-cidr: "0.0.0.0/0,::/0" IPv6 シナリオで、NGINX Ingress が空の X-Forwarded-For ヘッダーを受信し、アップストリームの Classic Load Balancer (CLB) インスタンスが使用されている場合、CLB インスタンスで Proxy プロトコルを有効にすることでクライアント IP アドレスを取得できます。Proxy プロトコルの詳細については、「レイヤー 4 リスナーを有効にしてクライアント IP アドレスを保持し、バックエンドサーバーに渡す」をご参照ください。
HSTS の設定方法
HTTP Strict Transport Security (HSTS) はデフォルトで有効になっています。ブラウザが初めてプレーン HTTP 経由でサービスにアクセスすると、サーバー (HSTS が有効な場合) は HSTS 応答をトリガーします。ブラウザの開発者ツールでは、応答ヘッダーに HSTS サポートを示す Non-Authoritative-Reason: HSTS フィールドが表示されます。ブラウザが HSTS 互換の場合、後続のリクエストは自動的に HTTPS に切り替わり、下の図に示すようにステータスコード 307 Internal Redirect が返されます。
クライアントリクエストをバックエンドの HTTPS サーバーに転送したくない場合は、nginx-ingress-controller の HSTS を無効にします。詳細な手順については、「HSTS」をご参照ください。
デフォルトでは、HSTS 設定はブラウザによってキャッシュされます。nginx-ingress-controller の HSTS を無効にした後、手動でブラウザのキャッシュを削除する必要があります。
サポートされている書き換えルール
Ingress-nginx は、単純な書き換えルールのみをサポートします。複雑な書き換えルールには、以下を使用してください。
configuration-snippet:このアノテーションを Ingress の location 設定に追加します。
server-snippet:Ingress の server 設定に追加します。
次の図に示すように、他のスニペットを使用してグローバル設定を追加できます。詳細については、「main-snippet」をご参照ください。
NGINX Ingress Controller のアップグレード中に更新されるリソース
NGINX Ingress Controller のバージョンが 0.44 より前の場合、次のリソースが含まれます。
serviceaccount/ingress-nginx
configmap/nginx-configuration
configmap/tcp-services
configmap/udp-services
clusterrole.rbac.authorization.k8s.io/ingress-nginx
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx
role.rbac.authorization.k8s.io/ingress-nginx
rolebinding.rbac.authorization.k8s.io/ingress-nginx
service/nginx-ingress-lb
deployment.apps/nginx-ingress-controller
バージョンが 0.44 以降の場合、上記のリソースに加えて、次のリソースが含まれます。
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission
service/ingress-nginx-controller-admission
serviceaccount/ingress-nginx-admission
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission
role.rbac.authorization.k8s.io/ingress-nginx-admission
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission
job.batch/ingress-nginx-admission-create
job.batch/ingress-nginx-admission-patch
ACK コンソールの [アドオン] ページから NGINX Ingress Controller をアップグレードする場合、次のリソースは変更されません。
configmap/nginx-configuration
configmap/tcp-services
configmap/udp-services
service/nginx-ingress-lb
他のすべてのリソース設定はデフォルト値にリセットされます。たとえば、deployment.apps/nginx-ingress-controller リソースの replicas のデフォルト値は 2 です。NGINX Ingress Controller をアップグレードする前にこの replicas を 5 に設定した場合、アップグレード後にデフォルト値の 2 に戻ります。
レイヤー 4 リスナーからレイヤー 7 リスナーへの切り替え方法
デフォルトでは、ingress-nginx の LoadBalancer は TCP ポート 80 と 443 をリッスンします。プロトコルを HTTP または HTTPS に変更することで、レイヤー 7 リスナーに切り替えます。
システムがリスナーを変更する際、サービスが一時的に中断されます。この操作はオフピーク時に実行することを推奨します。
証明書を作成し、証明書 ID (cert-id) を記録します。詳細については、「Certificate Management Service の証明書を使用する」をご参照ください。
アノテーションを使用して、Ingress が使用する LoadBalancer リスナーをレイヤー 4 からレイヤー 7 に変更します。
ACK コンソールにログインします。左側のナビゲーションウィンドウで、クラスター をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[サービス] ページの上部で、[名前空間] を
kube-systemに設定します。ingress-nginx-lbService を見つけ、[アクション] 列の [YAML の編集] をクリックします。[YAML の編集] パネルで、
https(ポート 443) という名前のポートのtargetPortを80に更新します。- name: https port: 443 protocol: TCP targetPort: 80 # ポート 443 の targetPort を 80 に設定します。annotationsフィールドに以下を追加し、[OK] をクリックします。service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "http:80,https:443" service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id: "${YOUR_CERT_ID}"
結果を検証します。
[サービス] ページで、ingress-nginx-lb サービスを探し、[タイプ] 列の
アイコンをクリックします。 [リスナー] タブをクリックします。[フロントエンドプロトコル/ポート] 列に
HTTP:80とHTTPS:443の両方が表示されていれば、LoadBalancer のリスナーはレイヤー 4 からレイヤー 7 に変更されています。
ack-ingress-nginx で既存の SLB インスタンスを使用する方法
ACK コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
[アプリカタログ] タブで、クラスターのバージョンに応じて ack-ingress-nginx または ack-ingress-nginx-v1 を選択します。
クラスターが Kubernetes 1.20 以前を実行している場合は、ack-ingress-nginx を選択します。
クラスターが Kubernetes 1.20 より後のバージョンを実行している場合は、ack-ingress-nginx-v1 を選択します。
Ingress Controller をデプロイします。手順については、「トラフィック分離のために複数の Ingress Controller をデプロイする」をご参照ください。
[パラメーター] ウィザードページで、次の操作を行います。
controller.service.annotations セクションのすべてのアノテーションを削除します。

新しいアノテーションを追加します。
# 使用したい SLB インスタンスを指定します。 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "${YOUR_LOADBALANCER_ID}" # リスナーを上書きします。 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
[OK] をクリックして Ingress Controller をデプロイします。
Ingress Controller がデプロイされた後、Ingress クラスを設定します。手順については、「トラフィック分離のために複数の Ingress Controller をデプロイする」をご参照ください。
複数の Ingress Controller からアクセスログを収集する方法
前提条件
クラスターに Logtail がインストールされていること。デフォルトでは、Logtail はクラスター作成時にインストールされます。インストールされていない場合は、「ACK クラスターからコンテナーログを収集する」を参照して手動でインストールしてください。
デフォルトの Ingress Controller でログ収集が有効になっていること。
他の Ingress Controller の Pod に追加されたラベルが取得されていること。詳細については、「Docker コンテナーのラベルと環境変数を取得する方法」をご参照ください。
手順:
ACK コンソールにログインします。左側のナビゲーションウィンドウで、クラスター をクリックします。
[クラスター] ページで、対象のクラスター名をクリックし、左側のナビゲーションウィンドウで [クラスター情報] をクリックします。
[クラスター情報] ページで、[基本情報] タブをクリックし、[クラスターリソース] セクションの [Log Service プロジェクト] の右側にあるハイパーリンクをクリックします。
[Logstores] ページで、Logstore を作成します。手順については、「Logstore の管理」をご参照ください。ログの重複収集を避けるため、各 Ingress Controller ごとに個別の Logstore を作成することを推奨します。
Logstore の名前は、その Logstore を使用する Ingress Controller の名前に基づいて付けることができます。
表示されるメッセージで、[データ収集ウィザード] をクリックします。
[クイックデータインポート] ダイアログボックスで、 を選択します。[注意] メッセージで [続行] をクリックします。[Kubernetes 標準出力と標準エラー] ページで、次の操作を行います。
[マシングループの作成] ステップで、[既存のマシングループを使用] をクリックします。
[マシングループ設定] ステップで、
k8s-group-<YOUR_CLUSTER_ID>マシングループを選択し、>をクリックしてマシングループを [適用済みサーバーグループ] セクションに移動します。その後、[次へ] をクリックします。[Logtail 設定] ステップで、次の操作を行います。
[他の設定をインポート] をクリックします。クラスターが使用するプロジェクトと
k8s-nginx-ingress設定を選択し、[OK] をクリックします。[グローバル設定] セクションで、設定名を変更します。[コンテナーフィルタリング] オプションを有効にし、Ingress Controller コンテナーのラベルをキーと値のペアとして追加します。
[プロセッサー設定] セクションで、[プロセッサー名] 列の [フィールドの抽出 (正規表現モード)] をクリックして、ログ処理フィールドを表示します。
説明異なる NGINX Ingress Controller が異なるログフォーマットを使用している場合、対応するログフィールドのキーと正規表現を設定してください。
[クエリと分析の設定] ステップで、[次へ] をクリックします。
[終了] ステップで、[ログの照会] をクリックすると、収集されたログが表示されます。
nginx-ingress-controller の TCP リスナーを有効にする方法
デフォルトでは、Ingress は外部の HTTP および HTTPS リクエストのみをクラスター内の Service に転送します。ingress-nginx を設定して、関連する ConfigMap で指定された TCP ポートで受信した外部 TCP リクエストの転送を有効にすることができます。
tcp-echo テンプレートを使用して Service と Deployment をデプロイします。
次のテンプレートを使用して ConfigMap を作成します。
tcp-services-cm.yamlファイルを変更し、変更を保存して終了します。apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: kube-system data: 9000: "default/tcp-echo:9000" # この設定は、ポート 9000 で受信した外部 TCP リクエストが default 名前空間の tcp-echo Service に転送されることを示します。 9001: "default/tcp-echo:9001"ConfigMap を作成します。
kubectl apply -f tcp-services-cm.yaml
nginx-ingress-controllerが使用する Service に TCP ポートを追加し、変更を保存して終了します。kubectl edit svc nginx-ingress-lb -n kube-systemapiVersion: v1 kind: Service metadata: labels: app: nginx-ingress-lb name: nginx-ingress-lb namespace: kube-system spec: allocateLoadBalancerNodePorts: true clusterIP: 192.168.xx.xx ipFamilies: - IPv4 ports: - name: http nodePort: 30xxx port: 80 protocol: TCP targetPort: 80 - name: https nodePort: 30xxx port: 443 protocol: TCP targetPort: 443 - name: tcp-echo-9000 # ポート名 port: 9000 # ポート番号 protocol: TCP # プロトコル targetPort: 9000 # 宛先ポート - name: tcp-echo-9001 # ポート名 port: 9001 # ポート番号 protocol: TCP # プロトコル targetPort: 9001 selector: app: ingress-nginx sessionAffinity: None type: LoadBalancer設定が有効になったか確認します。
次のコマンドを実行して Ingress の情報をクエリします。Ingress に関連付けられた SLB インスタンスの IP アドレスを取得できます。
kubectl get svc -n kube-system| grep nginx-ingress-lb期待される出力:
nginx-ingress-lb LoadBalancer 192.168.xx.xx 172.16.xx.xx 80:31246/TCP,443:30298/TCP,9000:32545/TCP,9001:31069/TCPncコマンドを実行して、ポート 9000 に対応する IP アドレスにhelloworldを送信します。応答が返されない場合、構成は有効になっています。echo "helloworld" | nc <172.16.xx.xx> 9000 echo "helloworld" | nc <172.16.xx.xx> 9001
NGINX Ingress Controller はどのように TLS 証明書をリクエストにマッチングさせるか
Kubernetes の Ingress リソースでは、TLS 証明書は spec.tls フィールドで定義されますが、それが適用されるホスト名は spec.rules.host フィールドで指定されます。
NGINX Ingress Controller はこれらのルールを処理し、各ホスト名とそれに対応する証明書のマッピングを内部の Lua テーブルに保存します。
リクエストフロー
クライアントが HTTPS リクエストを開始すると、TLS ハンドシェイクのサーバー名表示 (SNI) 拡張にリクエストされたホスト名を含めます。
NGINX Ingress Controller はこのリクエストを受信し、
certificate.call()関数を使用して Lua マッピングテーブルで SNI ホスト名を検索します。一致する証明書が見つかった場合、それがクライアントに提示され、TLS ハンドシェイクが完了します。
リクエストされたホスト名に一致する証明書が見つからない場合、コントローラーはデフォルトの自己署名
fake証明書を提示します。
このロジックを実装する関連する NGINX 設定を以下に示します。
## Start server _
server {
server_name _ ;
listen 80 default_server reuseport backlog=65535 ;
listen [::]:80 default_server reuseport backlog=65535 ;
listen 443 default_server reuseport backlog=65535 ssl http2 ;
listen [::]:443 default_server reuseport backlog=65535 ssl http2 ;
set $proxy_upstream_name "-";
ssl_reject_handshake off;
ssl_certificate_by_lua_block {
certificate.call()
}
...
}
## Start server www.example.com
server {
server_name www.example.com ;
listen 80 ;
listen [::]:80 ;
listen 443 ssl http2 ;
listen [::]:443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
...
}ingress-nginx は、証明書のステータス検証のパフォーマンスを向上させる機能である Online Certificate Status Protocol (OCSP) ステープリングをサポートしています。この機能を有効にすると、クライアントは証明書の失効ステータスを確認するために認証局 (CA) に直接問い合わせる必要がなくなります。これにより、証明書の検証時間が短縮され、初期接続の全体的な速度が向上します。詳細については、「OCSP ステープリングの設定」をご参照ください。
NGINX Ingress に一致する証明書がない場合の対処法
TLS 証明書とその秘密鍵が一致しない場合、または証明書のドメイン名がクライアントが使用するホスト名と一致しない場合、HTTPS アクセスエラーが発生する可能性があります。この問題をトラブルシューティングするには、次の操作を実行してください。
証明書と秘密鍵が一致することを確認する
次のコマンドを実行して、Kubernetes Secret から証明書と秘密鍵を抽出し、それらの暗号化モジュラスを比較します。
# <YOUR-SECRET-NAME> と <SECRET-NAMESPACE> を実際の値に置き換えてください kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/tls.crt && \ # <YOUR-SECRET-NAME> を使用する Secret に置き換えてください。 kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/tls.key && \ # 証明書とキーのモジュラスの MD5 ハッシュを計算して比較します openssl x509 -noout -modulus -in /tmp/tls.crt | openssl md5 && \ openssl rsa -noout -modulus -in /tmp/tls.key | openssl md5上記のコマンドは、証明書とキーを抽出してデコードし、それぞれ
/tmp/tls.crtと/tmp/tls.keyに保存します。その後、opensslコマンドが両方のファイルの公開モジュラスの MD5 ハッシュを計算します。2 つの結果のハッシュ値が同一でない場合、証明書と秘密鍵が一致していないことを意味します。これを修正するには、有効な一致するキーペアで Secret を更新する必要があります。
証明書がドメイン名と一致することを確認する
次のコマンドを実行して証明書の内容を検査し、それがカバーするドメイン名を確認します。
kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath={.data."tls\.crt"} | base64 -d | openssl x509 -text -nooutコマンドからの出力を確認し、以下を検査します。
Subject:
CN = example.comのような形式のコモンネーム (CN) フィールドを探します。Subject Alternative Name (SAN):
DNS:エントリを探します。
サービスへのアクセスに使用しているホスト名が
CNまたは SAN エントリのいずれにもリストされていない場合、その証明書はそのドメインに対して有効ではないことを意味します。これを解決するには、正しいホスト名をカバーする新しい証明書を取得して設定する必要があります。
高トラフィック下で NGINX Pod がヘルスチェックに失敗する場合の対処法
背景
NGINX Ingress Controller のヘルスチェックは、ポート 10246 で NGINX プロセスによって公開される /healthz パスにアクセスすることで機能します。このチェックは、NGINX プロセスが正常であり、サービスが正しく実行されていることを確認します。
現象
ヘルスチェックが失敗すると、healthz エンドポイントに到達できないことを示す次のようなログエントリが表示されます。
I0412 11:01:52.581960 7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:01:55 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:01:55.895683 7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:02.582247 7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:05 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:05.896126 7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:12.582687 7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:15 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:15.895719 7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:22.582516 7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:25 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:25.896955 7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:28.983016 7 nginx.go:408] "NGINX process has stopped"
I0412 11:02:28.983033 7 sigterm.go:44] Handled quit, delaying controller exit for 10 seconds
I0412 11:02:32.582587 7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:35 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:35.895853 7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:38.986048 7 sigterm.go:47] "Exiting" code=0原因
高トラフィック下では、NGINX ワーカープロセスが過負荷になり、CPU 使用率が非常に高くなる (時には 100% に近づく) ことがあります。システムがこのレベルのストレス下にあると、ヘルスチェックプローブにタイムリーに応答するためのリソースが不足し、失敗する可能性があります。
解決策
推奨される解決策は、NGINX Ingress Controller の Pod レプリカ数を増やすことです。これにより、トラフィック負荷が複数の Pod に分散され、単一インスタンスの CPU 負荷が軽減され、ヘルスチェックが成功するようになります。
cert-manager が証明書の発行に失敗する場合の対処法
この問題は、Web Application Firewall (WAF) が有効になっている場合に発生する可能性があります。WAF は、cert-manager がドメイン所有権を検証するために使用する HTTP01 リクエストを傍受またはブロックすることがあり、これにより証明書発行プロセスが正常に完了しなくなります。
これを解決するには、一時的に WAF を無効にして、HTTP-01 チャレンジが成功するようにします。
WAF を無効にする前に、アプリケーションを不必要なリスクにさらさないように、潜在的なセキュリティへの影響を十分に評価する必要があります。
高トラフィック下で NGINX が大量のメモリを使用する理由
現象
高トラフィック負荷の下で、NGINX Ingress Controller のメモリ使用量が大幅に増加し、最終的に Out-of-Memory (OOM) イベントが発生することが観察されます。
原因
Pod を調査し、コントローラープロセスが大量のメモリを消費していることが判明した場合、問題は Prometheus メトリクスの収集に関連するメモリリークである可能性が高いです。
これは、NGINX Ingress Controller バージョン 1.6.4 の既知の問題であり、nginx_ingress_controller_ingress_upstream_latency_seconds のような高カーディナリティのメトリクスにしばしば関連しています。
解決策
NGINX Ingress Controller を最新バージョンにアップグレードしてください。最新バージョンにはこの問題の修正が含まれています。高トラフィック環境向けに NGINX Ingress を設定する際は、メモリ使用量に大きな影響を与える可能性のあるメトリクスに特に注意してください。
詳細については、以下のコミュニティリソースをご参照ください。
NGINX Ingress Controller がアップグレード中に停止した場合の対処法
現象
NGINX Ingress Controller の段階的ロールアウト (カナリアアップグレード) 中に、プロセスが検証フェーズでスタックし、先に進めなくなります。Operation is forbidden for task in a failed state のようなエラーメッセージが表示されることがあります。
原因
この問題は通常、アドオンのアップグレードタスクが事前に定義された 4 日間の有効期限を超えたためにシステムによって自動的にクリーンアップされた場合に発生します。この場合、問題を解決するには、アドオンのデプロイメント状態を手動でリセットする必要があります。
注意:アドオンがすでにアップグレードの最終段階である「リリース済み」フェーズに達している場合は、何もする必要はありません。現在のタスクがタイムアウトして自動的に終了するのを待つだけです。
手順
Deployment をリセットしてアップグレードを続行するには、次の手順に従ってください。
次のコマンドを実行して、
Deploymentマニフェストを編集用に開きます。kubectl edit deploy -n kube-system nginx-ingress-controllerエディターで、
specセクションの下にある次のフィールドを見つけ、以下のようにデフォルト値に戻します。spec.minReadySeconds: 0spec.progressDeadlineSeconds: 600spec.strategy.rollingUpdate.maxSurge: 25%spec.strategy.rollingUpdate.maxUnavailable: 25%

変更を保存してエディターを終了します。
期待される結果
変更を保存すると、アドオンのアップグレードが自動的に再開され、古い Pod が置き換えられて段階的ロールアウトが完了します。
アップグレードはバックグラウンドで正常に完了しますが、ACK コンソールの [アドオン] ページのアドオンのステータスは「アップグレード中」のままになることがあります。この表示の問題は、通常、約 2 週間後に自動的に解決されます。
コントローラーバージョン 1.10 以降、チャンク転送エンコーディング (Transfer-Encoding: chunked) が機能しなくなった理由
現象
アプリケーションが HTTP ヘッダー Transfer-Encoding: chunked を設定しており、コントローラーのログに重複ヘッダーに関するエラーが表示されます。
原因
これは、v1.10 以降のコントローラーで使用されている基盤となる NGINX バージョンの更新に関連しています (NGINX 更新ログをご参照ください)。新しい NGINX バージョンでは、HTTP 応答の検証がより厳格になっています。バックエンドサービスが複数の Transfer-Encoding: chunked ヘッダーを返した場合、NGINX はその応答を無効として扱います。
解決策
バックエンドサービスが単一の Transfer-Encoding: chunked ヘッダーのみを返すようにしてください。詳細については、GitHub Issue #11162 をご参照ください。
IP 許可リスト/拒否リストによるアクセス制御の設定方法
NGINX Ingress は、Ingress リソースのアノテーションまたはグローバルな ConfigMap のキーと値のペアを使用して、IP ベースのアクセス制御をサポートします。
ConfigMap:すべての Ingress にグローバルに適用されます。
Ingress アノテーション:特定の Ingress リソースにのみ適用されます。
Ingress リソースのアノテーションは、常にグローバルな ConfigMap 設定よりも優先されます。
Ingress マニフェストで次のアノテーションを使用します。
アノテーション | 説明 |
| 許可リストは、クライアントの IP アドレスまたは CIDR ブロックのリストです。複数の値を指定する場合は、カンマ (,) で区切ります。 |
| クライアント IP アドレスまたは CIDR ブロックの拒否リスト。複数の値を指定する場合は、コンマ (,) で区切ります。 |
詳細については、Denylist Source Range および Whitelist Source Range の公式ドキュメントをご参照ください。
NGINX Ingress v1.2.1 の defaultBackend に関する既知の問題
現象
Ingress リソースで defaultBackend を設定すると、デフォルトサーバーの defaultBackend 設定が誤って上書きされることがあります。
解決策
これは既知の問題です (GitHub Issue #8823 をご参照ください)。これを解決するには、NGINX Ingress Controller をバージョン 1.3 以降にアップグレードすることを推奨します。手順については、「NGINX Ingress Controller のアップグレード」をご参照ください。
curl を使用すると Connection reset by peer エラーが発生する理由
現象
curl を使用して HTTP 経由で外部の公開サービスにアクセスすると、curl: (56) Recv failure: Connection reset by peer というエラーが表示されます。
原因
これは通常、プレーンテキストの HTTP リクエストに、ネットワークの中継装置によって機密と見なされるキーワードが含まれている場合に発生し、接続がブロックまたはリセットされます。
解決策
Ingress ルートに TLS 証明書を設定し、すべての通信に HTTPS を使用してトラフィックが暗号化されるようにします。
パスマッチングの優先順位はどのように機能するか
NGINX の正規表現パスは定義された順に評価され、最初に一致したものが使用されます。より正確なパスマッチングを可能にするため、ingress-nginx はまずすべてのパスを長さの降順でソートし、それらを nginx.conf ファイルに location ブロックとして書き込みます。
詳細な説明については、公式ドキュメント「Ingress Path Matching」をご参照ください。
非べき等なリクエストがリトライされない理由
バージョン 1.9.13 以降、NGINX はエラーが発生した場合に非べき等なリクエスト (POST、LOCK、PATCH) をリトライしません。
以前の動作に戻すには、nginx-configuration ConfigMap で retry-non-idempotent: "true" を設定します。
大きなクライアントヘッダーやクッキーを持つリクエストをサポートする方法
現象
NGINX Ingress 経由でサービスにアクセスすると、400 Bad Request エラーと Request Header Or Cookie Too Large というメッセージが表示されます。
原因
このエラーは、クライアントのリクエストヘッダーまたはクッキーのサイズが Nginx で設定されたデフォルトのバッファーサイズを超えた場合に発生します。
解決策
関連するバッファーサイズを増やします。2 つの主要なパラメーターは次のとおりです。
client-header-buffer-size:クライアントリクエストヘッダーのバッファーサイズ。デフォルトは
1kです。large-client-header-buffers:大きなクライアントリクエストヘッダーを読み取るためのバッファーの最大数とサイズ。デフォルトは
4 8kです。
これらのパラメーターを変更するには、nginx-configuration ConfigMap を編集します。kubectl edit cm -n kube-system nginx-configuration
例:
client-max-body-size: "16k"
large-client-header-buffers: "4 32k" 変更を適用した後、NGINX 設定でそれらが有効になっていることを確認します。Ingress Controller Pod の 1 つの内部にある nginx.conf ファイルを検査できます。kubectl exec <nginx-ingress-pod> -n kube-system -- cat /etc/nginx/nginx.conf
Exact または Prefix パスがまだ正規表現として扱われる理由
特定の host に対する Ingress ルールのいずれかで use-regex または rewrite-target アノテーションが使用されている場合、その同じホスト配下のすべてのパスで、大文字と小文字を区別しない正規表現マッチングが強制的に使用されます。 これは NGINX Ingress Controller の現在の実装ロジックです。 詳細については、「コミュニティドキュメント」をご参照ください。

多数の Ingress があるクラスターで Ingress を追加する際に検証 Webhook の応答が遅い理由
これは NGINX Ingress Controller V1.12 以前の既知のパフォーマンス問題です。検証 Webhook は既存のすべての Ingress に対して完全なチェックを実行するため、大規模な環境では遅くなる可能性があります。#11115 をご参照ください。
解決策:
オプション 1:Webhook のタイムアウトを増やす
応答時間が長くなっても許容でき、増分検証を使用したくない場合は、検証 Webhook のタイムアウトを増やします。デフォルトは10sです。アクション:
validatingwebhookconfigurationsオブジェクトの名前がingress-nginx-admissionのものを編集し、timeoutSecondsの値を増やします (最大30s)。注意:この値はアドオンのアップグレード中に上書きされます。
オプション 2:増分検証を有効にする
NGINX Ingress Controller のDeploymentを変更して、--disable-full-test=true起動引数を追加します。効果:このフラグを使用すると、Webhook は新しい Ingress ルールに対してのみ増分検証を実行します。これにより検証速度は大幅に向上しますが、異なる Ingress リソース間の競合は検出しません。
スニペットの使用に関する注意点
問題
複数の Ingress リソースにわたって同じドメインに対して server-snippet アノテーションを設定すると、ログに警告が表示され、最初のスニペットのみが適用されることがあります。これにより、予期しない動作が発生する可能性があります。
ログ警告の例:
W0619 14:58:49.323721 7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")
W0619 14:58:49.323727 7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")
W0619 14:58:49.323734 7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")この警告は、test.example.com のスニペットがすでに定義されており、他の Ingress リソースからの後続の定義が無視されていることを示しています。
Secret で設定した TLS 証明書が機能しない理由
コントローラーのログを確認する
NGINX Ingress Controller Pod のログを調べて、証明書関連のエラーがないか確認します。
kubectl -n kube-system logs <nginx-ingress-controller-pod-name> | grep "Error getting SSL certificate"以下のようなエラーが表示された場合、証明書 Secret の読み込みに問題があることを示しています (xxxx は Secret の名前です)。
Error getting SSL certificate "xxxx": local SSL certificate xxxx tls was not found. Using default certificateこのエラーには主に 3 つの原因が考えられます。
原因 1:Secret が存在しない
ログメッセージで指定された名前の Secret が正しい名前空間に実際に存在することを確認します。
原因 2:証明書と秘密鍵が一致しない
Secret に保存されている tls.crt (公開鍵) と tls.key (秘密鍵) は、一致するペアでなければなりません。
kubectl create secret tlsを使用して、一致しないペアでtlsSecret を作成しようとすると、コマンドは次のエラーで失敗します。error: tls: private key does not match public key既存の Secret の不一致を確認するには、次のスクリプトを実行します。
export SECRET_NAME=<Your Secret Name> export NAME_SPACE=<Your Secret Namespace> diff <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.key}' | base64 -d | openssl rsa -noout -modulus | openssl md5) && echo "Certificate and Key match" || echo "Certificate and Key do not match"このコマンドは、証明書とキーのモジュラスを比較します。キーと証明書が一致しない場合、出力には 2 つの異なるハッシュ値と
Certificate and Key do not matchというメッセージが表示されます。有効なキーペアで Secret を更新する必要があります。root@Aliyun ~/ssl # export SECRET_NAME=test root@Aliyun ~/ssl # export NAME_SPACE=default root@Aliyun ~/ssl # diff <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.key}' | base64 -d | openssl rsa -noout -modulus | openssl md5) && echo "Certificate and Key match" || echo "Certificate and Key do not match" 1c1 < (stdin)= 66a309089e87e32d1b6fe361ebf8cd88 --- > (stdin)= 12e15c5fe35585b6fd9920abc8e8706d Certificate and Key do not match
原因 3:同じドメインの別の Ingress で TLS エントリが誤って設定されている
複数の Ingress リソースにわたって同じドメインに対して tls セクションを定義している場合、そのうちの 1 つの設定にエラーがあると、証明書が正しく読み込まれなくなる可能性があります。そのドメインを参照するすべての Ingress リソースを確認し、誤った設定を修正してください。
証明書を更新した後も証明書の有効期限切れアラートが届く理由
原因
古いバージョンの NGINX Ingress Controller には、証明書が更新された後も nginx_ingress_controller_ssl_expire_time_seconds メトリクスが正しく更新またはパージされないという既知のバグがあります。これにより、監視システムが古いデータに基づいて certificate expired アラートを発し続ける可能性があります。
解決策
古いメトリクスをクリアするには、NGINX Ingress Controller Pod のローリングリスタートを実行する必要があります。
この問題は新しいバージョンで解決されているため、NGINX Ingress Controller をバージョン 1.11.4 以降にアップグレードすることを強く推奨します。
特定の NGINX Ingress Controller バージョンのデフォルト設定を見つける方法
設定パラメーターのデフォルト値は、NGINX Ingress Controller のバージョンによって異なります。たとえば、use-gzip はバージョン 0.35.0 以前ではデフォルトで有効でしたが、バージョン 1.11.4 ではデフォルトで無効になっています。
特定のバージョンの特定のパラメーターのデフォルトの動作を見つけるには、公式ドキュメントの対応するバージョンブランチにある configmap.md ファイルを参照してください。
例:controller-v1.8.0 の場合、ページの左側にあるバージョンセレクターを使用して他のバージョンに切り替えます。
