このトピックでは、Ingress に関するよくある質問への回答を提供します。
ACK コンソールのアドオンページで NGINX Ingress コントローラーを更新した後、システムで何が更新されますか?
ingress-nginx のレイヤー 4 リスナーをレイヤー 7 HTTP または HTTPS リスナーに変更するにはどうすればよいですか?
ACK コンソールのマーケットプレイスページからデプロイされた ack-ingress-nginx に既存の SLB インスタンスを指定するにはどうすればよいですか?
NGINX Ingress コントローラー 1.10 以降を使用しているときに、チャンク転送(Transfer-Encoding: chunked)が正常に動作しない場合はどうすればよいですか?
NGINX Ingress へのアクセスを制御するために IP ブラックリストとホワイトリストを構成するにはどうすればよいですか?
curl を使用してインターネット経由で外部サービスにアクセスするときに接続リセットエラーが発生した場合はどうすればよいですか?
NGINX Ingress が大きなクライアントリクエストヘッダーまたは Cookie をサポートできるようにするにはどうすればよいですか?
Ingress の構成で特定のパスに pathType を Exact または Prefix に設定した後、代わりに正規表現が使用されるのはなぜですか?
多数の Ingress が既に存在するクラスターに新しい Ingress を追加すると、検証 Webhook の応答が遅いのはなぜですか?
NGINX Ingress コントローラーの以前のバージョンにおける既知の問題は何ですか?
次のリストは、NGINX Ingress コントローラーの以前のバージョンにおける問題への参照を提供します。 NGINX Ingress コントローラーを使用する際の問題を防ぐために、最新バージョンにアップグレードすることをお勧めします。 詳細については、「NGINX Ingress コントローラーをアップグレードする」をご参照ください。
Ingress の defaultBackend パラメーター値が NGINX Ingress コントローラーのグローバル構成を上書きします
影響を受けるバージョン: 1.2.1-aliyun.1 以前。
解決策: NGINX Ingress コントローラーをバージョン 1.5.1-aliyun.1 以降にアップグレードします。
影響を受けるバージョン: 1.10.2-aliyun.1 以前。
解決策: NGINX Ingress コントローラーを 1.10.4-aliyun.1 以降にアップグレードします。
原因:
client-body-buffer-size
の値が 32 ビット整数のストレージ制限を超えています。解決策:
client-body-buffer-size
を200M
などの小さい値に設定します。
Ingress でサポートされている SSL または TLS プロトコルバージョンはどれですか?
Ingress-nginx は、Transport Layer Security (TLS) 1.2 および TLS 1.3 をサポートしています。 ブラウザまたはモバイルクライアントで使用される TLS プロトコルバージョンが 1.2 より前の場合、クライアントと ingress-nginx 間のハンドシェイク中にエラーが発生する可能性があります。
ingress-nginx でより多くの TLS プロトコルバージョンをサポートするには、kube-system 名前空間の nginx-configuration
ConfigMap に次の構成を追加します。 詳細については、「TLS/HTTPS」をご参照ください。
NGINX Ingress コントローラー 1.7.0 以降で TLS 1.0 または 1.1 を有効にするには、@SECLEVEL=0
を ssl-ciphers
パラメーターで指定する必要があります。
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 はデフォルトでレイヤー 7 リクエストヘッダーをバックエンドサーバーに渡しますか?
デフォルトでは、ingress-nginx はレイヤー 7 リクエストヘッダーをバックエンドサーバーに渡します。 ただし、HTTP ルールに準拠していないリクエストヘッダーは、リクエストがバックエンドサーバーに転送される前に除外されます。 たとえば、モバイルバージョンのリクエストヘッダーは除外されます。 これらのリクエストヘッダーを除外したくない場合は、kubectl edit cm -n kube-system nginx-configuration
コマンドを実行して、関連する構成を nginx-configuration ConfigMap に追加します。 詳細については、「ConfigMap」をご参照ください。
enable-underscores-in-headers: true
ingress-nginx はバックエンド HTTPS サーバーにリクエストを転送できますか?
ingress-nginx がバックエンド HTTPS サーバーにリクエストを転送できるようにするには、次のコマンドを実行して、必要なアノテーションを Ingress 構成に追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: xxxx
annotations:
# バックエンドサーバーで使用されるプロトコルとして HTTPS を指定する必要があります。
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
Ingress はレイヤー 7 でクライアント IP アドレスを渡しますか?
デフォルトでは、ingress-nginx は X-Forward-For および X-Real-IP ヘッダーフィールドを追加して、クライアント IP アドレスを渡します。 ただし、X-Forward-For および X-Real-IP ヘッダーフィールドが既にクライアントによってリクエストに追加されている場合、バックエンドサーバーはクライアント IP アドレスを取得できません。
kubectl edit cm -n kube-system nginx-configuration
コマンドを実行して、kube-system 名前空間の 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 アドレスを保持し、バックエンドサーバーに渡す」をご参照ください。
NGINX Ingress コントローラーは HSTS をサポートしていますか?
デフォルトでは、nginx-ingress-controller で HTTP Strict Transport Security (HSTS) が有効になっています。 ブラウザがプレーン HTTP リクエストを初めて送信すると、バックエンドサーバー(HSTS が有効)からのレスポンスヘッダーに Non-Authoritative-Reason: HSTS
が含まれます。 これは、バックエンドサーバーが HSTS をサポートしていることを示します。 クライアントも HSTS をサポートしている場合、最初のアクセス試行が成功すると、クライアントは HTTPS リクエストの送信を続けます。 バックエンドサーバーからのレスポンスの本文には、次の図に示すように、307 Internal Redirect
ステータスコードが含まれています。
クライアントリクエストをバックエンド HTTPS サーバーに転送したくない場合は、nginx-ingress-controller の HSTS を無効にします。 詳細については、「HSTS」をご参照ください。
デフォルトでは、HSTS 構成はブラウザによってキャッシュされます。 nginx-ingress-controller の HSTS を無効にした後、ブラウザのキャッシュを手動で削除する必要があります。
ingress-nginx でサポートされている書き換えルールはどれですか?
ingress-nginx では、単純な書き換えルールのみがサポートされています。 詳細については、「書き換え」をご参照ください。 複雑な書き換えルールを構成する場合は、次の方法を使用します。
configuration-snippet: このアノテーションを Ingress の location 構成に追加します。 詳細については、「構成スニペット」をご参照ください。
server-snippet: このアノテーションを Ingress の server 構成に追加します。 詳細については、「サーバー スニペット」をご参照ください。
次の図に示すように、他のスニペットを使用してグローバル構成を追加できます。 詳細については、「main-snippet」をご参照ください。
ACK コンソールのアドオンページで NGINX Ingress コントローラーを更新した後、システムで何が更新されますか?
NGINX Ingress コントローラーのバージョンが 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
NGINX Ingress コントローラーのバージョンが 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
Container Service for Kubernetes (ACK) コンソールのアドオンページで NGINX Ingress コントローラーを更新すると、次のリソースの構成は変更されません。
configmap/nginx-configuration
configmap/tcp-services
configmap/udp-services
service/nginx-ingress-lb
他のリソースの構成はデフォルト値にリセットされます。 たとえば、deployment.apps/nginx-ingress-controller
リソースの replicas パラメーターのデフォルト値は 2 です。 NGINX Ingress コントローラーを更新する前に replicas の値を 5 に設定した場合、ACK コンソールのアドオンページからコンポーネントを更新した後、replicas パラメーターはデフォルト値の 2 を使用します。
ingress-nginx のレイヤー 4 リスナーをレイヤー 7 HTTP または HTTPS リスナーに変更するにはどうすればよいですか?
デフォルトでは、ingress-nginx ポッドの Server Load Balancer (SLB) インスタンスは TCP ポート 443 と 80 をリッスンします。 リスナーのプロトコルを HTTP または HTTPS に変更することで、レイヤー 4 リスナーをレイヤー 7 リスナーに変更できます。
システムがリスナーを変更すると、サービスが一時的に中断されます。 この操作は、オフピーク時に実行することをお勧めします。
証明書を作成し、証明書 ID (cert-id) を記録します。 詳細については、「Certificate Management Service の証明書を使用する」をご参照ください。
アノテーションを使用して、Ingress で使用される SLB インスタンスのリスナーをレイヤー 4 からレイヤー 7 に変更します。
ACK コンソール にログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターを見つけて、その名前をクリックします。 左側のウィンドウで、 を選択します。
[サービス] ページの上部で、[名前空間] を kube-system に設定します。
ingress-nginx-lb
サービスを見つけて、[アクション] 列の [YAML を編集] をクリックします。[YAML で表示] パネルで、
ports
セクションのポート 443 のtargetPort
を 80 に設定します。- name: https port: 443 protocol: TCP targetPort: 80 # ポート 443 の targetPort を 80 に設定します。
次の構成を
annotations
パラメーターに追加し、[更新] をクリックします。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 が表示されている場合、SLB インスタンスのリスナーはレイヤー 4 からレイヤー 7 に変更されています。
ACK コンソールのマーケットプレイスページからデプロイされた 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 コントローラーをデプロイします。 詳細については、「クラスターに複数の Ingress コントローラーをデプロイする」をご参照ください。
[パラメーター] ウィザードページで、元のアノテーションを削除してから、新しいアノテーションを追加します。
controller.service.annotations セクションのすべてのアノテーションを削除します。
新しいアノテーションを追加します。
使用する SLB インスタンスを指定します。 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "${YOUR_LOADBALANCER_ID}" # SLB インスタンスのリスナーを上書きします。 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
[OK] をクリックして、Ingress コントローラーをデプロイします。
Ingress コントローラーがデプロイされた後、Ingress コントローラーの Ingress クラスを構成します。 詳細については、「クラスターに複数の Ingress コントローラーをデプロイする」をご参照ください。
複数の Ingress コントローラーからアクセスログを収集するにはどうすればよいですか?
前提条件
Logtail がクラスターにインストールされています。 デフォルトでは、Logtail はクラスターの作成中にインストールされます。 Logtail がクラスターにインストールされていない場合は、「DaemonSet モードで Kubernetes コンテナーからテキストログを収集する」を参照して、Logtail を手動でインストールしてください。
デフォルトの Ingress コントローラーで ログ収集 が有効になっています。
他の Ingress コントローラーのポッドに追加されたラベルが取得されます。 詳細については、「Docker コンテナーのラベルと環境変数を取得するにはどうすればよいですか?」をご参照ください。
手順:
ACK コンソール にログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスタ] ページで、管理するクラスタの名前をクリックし、左側のナビゲーションペインで [クラスタ情報] をクリックします。
[クラスタ情報] ページで、[基本情報] タブをクリックし、[クラスタリソース] セクションの [Log Service プロジェクト] の右側にあるハイパーリンクをクリックします。
Simple Log Service (SLS) コンソールの [ログストア] ページで、ログストアを作成します。詳細については、「ログストアを管理する」をご参照ください。ログ収集の重複を避けるため、Ingress コントローラーごとに個別のログストアを作成することをお勧めします。
ログストアを使用する Ingress コントローラーの名前に基づいて、ログストアに名前を付けることができます。
表示されるメッセージで、[データ収集ウィザード] をクリックします。
[クイックデータインポート] ダイアログボックスで、
を選択します。Note メッセージで、[続行] をクリックします。[Kubernetes Stdout And Stderr] で、以下の操作を実行します。[マシン グループの作成] ステップで、[既存のマシン グループを使用] をクリックします。
[マシン グループの構成] ステップで、k8s-group-<YOUR_CLUSTER_ID> マシン グループを選択し、
>
をクリックして、マシン グループを [適用済みサーバー グループ] セクションに移動します。次に、[次へ] をクリックします。[Logtail 構成] ステップで、以下の操作を実行します。
[他の構成をインポート] をクリックします。クラスターで使用されているプロジェクトと k8s-nginx-ingress 構成を選択します。次に、[OK] をクリックします。
[グローバル構成] セクションで、構成名を変更します。[コンテナのフィルタリング] フィールドに、Ingress コントローラー コンテナのラベルをキーと値のペアとして追加します。次に、[次へ] をクリックします。
[プロセッサ構成] セクションで、[プロセッサ名] 列の [フィールドの抽出 (正規表現モード)] をクリックして、ログ処理フィールドを表示します。
説明異なる NGINX Ingress コントローラーが異なるログ フォーマットを使用している場合は、異なるログストアの Logtail 構成で Keys および Regex ログ処理フィールド パラメーターを適宜変更する必要があります。
[クエリと分析の構成] ステップで、[次へ] をクリックします。[終了] ステップで、[ログのクエリ] をクリックして、収集されたログを表示します。
nginx ingress コントローラーで TCP リスナーを有効にする方法
デフォルトでは、Ingress は外部の HTTP および HTTPS リクエストのみをクラスター内のサービスに転送します。 ingress-nginx を構成して、関連する ConfigMap で指定された TCP ポートで受信した外部 TCP リクエストを転送するように Ingress を有効にすることができます。
tcp-echo テンプレートを使用して、サービスとデプロイメントをデプロイします。
次のテンプレートを使用して、ConfigMap を作成します。
tcp-services-cm.yaml ファイルを変更します。 その後、変更を保存して終了します。
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: kube-system data: 9000: "default/tcp-echo:9000" # この構成は、ポート 9000 で受信した外部 TCP リクエストが、デフォルトの名前空間の tcp-echo サービスに転送されることを示します。 9001: "default/tcp-echo:9001"
次のコマンドを実行して、ConfigMap を作成します。
kubectl apply -f tcp-services-cm.yaml
nginx-ingress-controller が使用するサービスの TCP ポートを開きます。 その後、変更を保存して終了します。
kubectl edit svc nginx-ingress-lb -n kube-system
apiVersion: 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/TCP
nc
コマンドを実行して、helloworld
をポート 9000 に対応する IP アドレスに送信します。 応答が返されない場合、構成は有効になります。echo "helloworld" | nc <172.16.xx.xx> 9000 echo "helloworld" | nc <172.16.xx.xx> 9001
NGINX Ingress 用に構成された証明書の一致ロジックとは何ですか?
Ingress は、spec.tls
パラメーターを使用して TLS 構成を指定し、spec.rules.host
パラメーターを使用して Ingress のドメイン名を指定します。NGINX Ingress コントローラーは、Lua テーブルを使用して、ドメイン名と証明書間のマッピングを保存します。
クライアントが NGINX に HTTPS リクエストを送信すると、リクエストには、リクエストの送信先 host
を指定する Server Name Indication(SNI)フィールドが含まれます。NGINX Ingress は、certificate.call()
メソッドを使用して、証明書がドメイン名に関連付けられているかどうかを確認します。証明書が見つからない場合は、fake
証明書が返されます。
NGINX 構成の例:
## サーバー _ の開始
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()
}
...
}
## サーバー 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)で証明書のステータスを確認する必要はありません。これにより、証明書の検証が高速化され、NGINX へのアクセスが高速になります。詳細については、「OCSP ステープリングを構成する」をご参照ください。
NGINX Ingress と一致する証明書がない場合はどうすればよいですか?
この問題は、使用している証明書と秘密鍵が一致しない場合、または使用している証明書のドメイン名がアクセスされているドメイン名と異なる場合に発生します。この問題のトラブルシューティングを行うには、次の操作を実行します。
使用している Secret 内の証明書と秘密鍵が互いに一致するかどうかを確認します。
kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/tls.crt && \ # 使用する<YOUR-SECRET-NAME>に置き換えます。 kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/tls.key && \ openssl x509 -noout -modulus -in /tmp/tls.crt | openssl md5 && \ openssl rsa -noout -modulus -in /tmp/tls.key | openssl md5
上記のコマンドを実行して kubectl を使用し、Secret から証明書の内容を抽出し、証明書をデコードして、証明書を
/tmp/tls.crt
ファイルに、秘密鍵を/tmp/tls.key
ファイルに保存します。次に、OpenSSL MD5 関数を使用して、証明書と秘密鍵のハッシュ値を計算します。証明書のハッシュ値が秘密鍵のハッシュ値と異なる場合、証明書と秘密鍵は一致しません。互いに一致する証明書と秘密鍵を設定することをお勧めします。
証明書のドメイン名が、アクセスされているドメイン名と同じであるかどうかを確認します。
kubectl get secret <YOUR-SECRET-NAME> -n <SECRET-NAMESPACE> -o jsonpath={.data."tls\.crt"} | base64 -d | openssl x509 -text -noout
上記のコマンドを実行すると、システムは出力に証明書の詳細を返します。出力の CN フィールド(Common Name を示します)で証明書のドメイン名を確認できます。例:
CN = example.com
。 CN フィールドの値にアクセスされているドメイン名が含まれていない場合、証明書のドメイン名はアクセスされているドメイン名と同じです。ビジネス要件に基づいてドメイン名を変更し、証明書のドメイン名がアクセスされているドメイン名と同じであることを確認します。
高負荷のシナリオで NGINX ポッドがヘルスチェックに失敗した場合はどうすればよいですか?
ヘルスチェックは、NGINX のポート 10246 を介して /healthz
パスにリクエストを送信することで実行されます。
NGINX がヘルスチェックに失敗した場合、次のメッセージが返されます。
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 // ingress コントローラーがシャットダウンしています
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 // nginx ステータス情報の取得中に予期しないエラーが発生しました:
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 // ingress コントローラーがシャットダウンしています
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 // nginx ステータス情報の取得中に予期しないエラーが発生しました:
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 // ingress コントローラーがシャットダウンしています
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 // nginx ステータス情報の取得中に予期しないエラーが発生しました:
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 // ingress コントローラーがシャットダウンしています
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 // nginx ステータス情報の取得中に予期しないエラーが発生しました:
I0412 11:02:28.983016 7 nginx.go:408] "NGINX process has stopped" // "NGINX プロセスが停止しました"
I0412 11:02:28.983033 7 sigterm.go:44] Handled quit, delaying controller exit for 10 seconds // 終了を処理し、コントローラーの終了を 10 秒遅延させています
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 // ingress コントローラーがシャットダウンしています
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 // nginx ステータス情報の取得中に予期しないエラーが発生しました:
I0412 11:02:38.986048 7 sigterm.go:47] "Exiting" code=0 // "終了しています"
高負荷のシナリオでは、NGINX プロセスの CPU 使用率が急上昇し、100% に近づくことさえあります。 この場合、NGINX はヘルスチェックに失敗します。 この問題を解決するには、NGINX ポッドをスケールアウトして、ポッドを異なるノードに分散させることをお勧めします。
cert-manager エラーが原因で証明書の発行に失敗した場合はどうすればよいですか?
この問題は、Web Application Firewall(WAF)が有効になっている場合に発生する可能性があります。 WAF は HTTP01 リクエストを妨害する可能性があり、証明書の発行が中断されます。 この問題を解決するには、WAF を無効にすることをお勧めします。 WAF を無効にする前に、WAF を無効にした後の影響を評価してください。
ピーク時に NGINX のメモリ使用量が急増した場合はどうすればよいですか?
ピーク時に NGINX でメモリ使用量の急増とメモリ不足 (OOM) エラーが発生した場合は、NGINX ポッドにログインし、過剰なメモリを消費しているプロセスを特定します。 ほとんどの場合、メトリック収集プロセスがメモリリークにつながります。 これは、NGINX Ingress コントローラー V1.6.4 の既知の問題です。 この問題を解決するには、NGINX Ingress コントローラーを最新バージョンに更新し、高負荷シナリオでの NGINX Ingress コントローラーのインストールを参照して、nginx_ingress_controller_ingress_upstream_latency_seconds
など、メモリ使用量を大幅に増加させるメトリックの収集を無効にすることをお勧めします。 詳細については、「Ingress controller stress test」、「Prometheus metric collector memory leak」、および「Metrics PR」をご参照ください。
NGINX Ingress コントローラーがアップグレード中の状態のままになっている場合はどうすればよいですか?
NGINX Ingress コントローラーをアップグレードするためにカナリアリリースを実装すると、アップグレード タスクが検証 ステップで停止し、システムによって Operation is forbidden for task in failed state というメッセージが表示されます。ほとんどの場合、この問題は、アップグレード タスクの期間がタイムアウト期間(デフォルトでは 4 日間)を超えたために発生します。アップグレード タスクがタイムアウトすると、システムは自動的にタスクを終了します。この問題を解決するには、カナリアリリースのステータスを手動で変更する必要があります。
アップグレード タスクがリリース ステップにある場合は、アップグレードを実行する必要はありません。アップグレード タスクの期間が 4 日を超えると、システムは自動的にタスクを終了します。
手順
変更が完了すると、システムはカナリアリリースを再開して NGINX Ingress コントローラーをアップグレードします。ただし、NGINX Ingress コントローラーは、ACK コンソールのアドオン ページで約 2 週間、アップグレード中の状態のままになる可能性があります。
次のコマンドを実行して、nginx-ingress-controller デプロイメントを変更します。
kubectl edit deploy -n kube-system nginx-ingress-controller
以下のパラメーターを設定します。
spec.minReadySeconds: 0
spec.progressDeadlineSeconds: 600
spec.strategy.rollingUpdate.maxSurge: 25%
spec.strategy.rollingUpdate.maxUnavailable: 25%
変更を保存して終了します。
NGINX Ingress コントローラー 1.10 以降を使用している場合、チャンク転送(Transfer-Encoding: chunked)が正常に動作しない場合はどうすればよいですか?
コードで Transfer-Encoding: chunked
HTTP ヘッダーを指定し、コントローラーログに Transfer-Encoding: chunked ヘッダーが重複して存在する場合、問題は NGINX の更新が原因である可能性があります。詳細については、「NGINX 更新ログ」をご参照ください。NGINX 1.10 以降では、HTTP 応答の検証が強化されています。その結果、バックエンド アプリケーションから複数の Transfer-Encoding: chunked
ヘッダーが返されると、応答は無効と見なされます。この問題を解決するには、バックエンド アプリケーションが Transfer-Encoding: chunked
ヘッダーを 1 つだけ返すように設定する必要があります。詳細については、「GitHub Issue #11162」をご参照ください。
NGINX Ingress へのアクセスを制御するために IP ブラックリストとホワイトリストを構成するにはどうすればよいですか?
NGINX Ingress へのアクセスを制御するために IP ブラックリストとホワイトリストを構成する場合、nginx-configuration ConfigMap にキーと値のペアを追加して、Ingress にアノテーションを追加できます。 nginx-configuration ConfigMap は、すべての NGINX Ingress に対して有効になります。 Ingress で構成された IP ブラックリストとホワイトリストは、nginx-configuration ConfigMap で構成されたものよりも優先されます。次の表に、IP ブラックリストとホワイトリストを構成するために追加できるアノテーションを示します。詳細については、「Denylist Source Range」および「Whitelist Source Range」をご参照ください。
アノテーション | 説明 |
nginx.ingress.kubernetes.io/denylist-source-range | IP ブラックリスト。IP アドレスと CIDR ブロックがサポートされています。IP アドレスまたは CIDR ブロックはコンマ(,)で区切ります。 |
nginx.ingress.kubernetes.io/whitelist-source-range | IP ホワイトリスト。IP アドレスと CIDR ブロックがサポートされています。IP アドレスまたは CIDR ブロックはコンマ(,)で区切ります。 |
NGINX Ingress コントローラー 1.2.1 の既知の問題は何ですか?
Ingress の defaultBackend パラメーターを構成すると、デフォルト サーバーの defaultBackend パラメーター値が上書きされる可能性があります。詳細については、「GitHub Issue #8823」をご参照ください。この問題を解決するには、NGINX Ingress コントローラーを V1.3 以降にアップグレードすることをお勧めします。NGINX Ingress コントローラーのアップグレード方法の詳細については、「NGINX Ingress コントローラーをアップグレードする」をご参照ください。
curl を使用してインターネット経由でパブリックサービスにアクセスするときに接続リセットエラーが発生した場合はどうすればよいですか?
HTTP 経由で中国国外のパブリックサービスに curl
を使用してアクセスすると、curl: (56) Recv failure: Connection reset by peer
エラーが返される場合があります。ほとんどの場合、この問題は、HTTP プレーンテキストのリクエストに禁止用語が含まれているために発生します。これにより、リクエストがブロックされたり、レスポンスがリセットされたりします。 通信を暗号化するために、Ingress ルールに TLS 証明書を設定することができます。
パス一致の優先順位のロジックとは何ですか?
NGINX では、正規表現は最初に一致したポリシーに従います。より正確なパス一致を有効にするために、ingress-nginx はまずパスの長さを降順に並べ替えてから、NGINX 構成にパスを書き込みます。詳細については、「https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/」をご参照ください。
非 idempotent リクエストがリトライされないのはなぜですか?
NGINX 1.9.13 以降では、NGINX はエラー発生時に POST、LOCK、PATCH リクエストなどの非 idempotent リクエストをリトライしません。以前の動作に戻すには、nginx-configuration ConfigMap に retry-non-idempotent=true
を指定します。
NGINX Ingress で大きなクライアントリクエストヘッダーまたは Cookie をサポートするにはどうすればよいですか?
NGINX Ingress が過度に大きなクライアントリクエストヘッダーまたは Cookie を受信すると、"400 Request Header Or Cookie Too Large /Bad request"
エラーが返される場合があります。この問題を解決するには、次のパラメーターを変更して、クライアントリクエストヘッダーを読み取るためのバッファーサイズを増やす必要があります。
client-header-buffer-size: クライアントリクエストヘッダーを読み取るためのバッファーサイズ。デフォルト値:
1k
。large-client-header-buffers: 大きなクライアントリクエストヘッダーの読み取りに使用されるバッファーの最大数とサイズ。デフォルト値:
4 8k
。
kubectl edit cm -n kube-system nginx-configuration
コマンドを実行して、nginx-configuration ConfigMap を変更し、ビジネス要件に基づいて上記のパラメーターを変更できます。例:
client-max-body-size: "16k"
large-client-header-buffers: "4 32k"
変更が完了したら、新しい構成が NGINX データプレーンで有効になっていることを確認します。kubectl exec <nginx-ingress-pod> -n kube-system -- cat/etc/nginx/nginx.conf | vim -
コマンドを実行して、nginx.conf
ファイル内の構成をクエリし、構成が nginx-configuration ConfigMap から同期されているかどうかを確認できます。
pathType
を Exact
または Prefix
に設定した後、Ingress の構成で特定のパスに対して正規表現が使用されるのはなぜですか?
use-regex
または rewrite-target
アノテーションが特定のホストの Ingress に追加されている場合、大文字と小文字を区別しない正規表現が、そのホストのすべてのパスに適用されます。これは、NGINX Ingress コントローラーの実装ロジックです。詳細については、「コミュニティドキュメント」をご参照ください。
多数の Ingress が既に存在するクラスターに新しい Ingress を追加すると、検証 Webhook の応答が遅くなるのはなぜですか?
これは、NGINX Ingress コントローラー V1.12 以前における既知のパフォーマンスの問題です。詳細については、「#11115」をご参照ください。
解決策:
クラスターが低速の応答を許容し、検証を受け入れないと仮定します。Webhook の現在の応答がタイムアウトした場合、ingress-nginx-admission の validatingwebhookconfigurations のタイムアウト期間を延長できます。デフォルトのタイムアウト期間は 10 秒です。最大タイムアウト期間は 30 秒です。タイムアウト パラメーター値は、NGINX Ingress コントローラーのアップグレード時に上書きされることに注意してください。
--disable-full-test=true
設定を、NGINX Ingress コントローラー用に作成されたデプロイメントの起動パラメーターに追加します。この設定を追加すると、システムは Ingress に対して増分検証のみを実行します。これにより、検証速度が向上します。ただし、Ingress ルール間の競合は検出できません。
スニペットの問題はなぜ発生しますか?
複数のスニペットを異なる Ingress で構成すると、入力エラーが発生する可能性があります。その結果、構成が予期しないものになる可能性があります。
W0619 14:58:49.323721 7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com") // サーバースニペットはサーバー "test.example.com" に既に構成されているため、スキップします (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") // サーバースニペットはサーバー "test.example.com" に既に構成されているため、スキップします (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 "default/test.example.com")
Secret に保存されている証明書が有効にならないのはなぜですか?
kubectl -n kube-system logs <nginx-ingress-controller-pod-name> | grep "Error getting SSL certificate"
コマンドを実行して、NGINX Ingress コントローラーのポッドのログを表示します。ログに次のエラーメッセージが表示された場合は、次の手順を実行してこの問題のトラブルシューティングを行うことができます。xxxx
はサービス名を表します。
Error getting SSL certificate "xxxx": local SSL certificate xxxx tls was not found. Using default certificate // SSL 証明書 "xxxx" の取得中にエラーが発生しました: ローカル SSL 証明書 xxxx tls が見つかりませんでした。デフォルトの証明書を使用しています。
このエラーメッセージは、次の理由で発生する可能性があります。
xxxx
サービスが存在しません。公開鍵(
tls.crt
)が秘密鍵(tls.key
)と一致しません。kubectl create secret tls
コマンドを実行して、公開鍵(tls.crt
)が秘密鍵(tls.key
)と一致しない TLS Secret を作成すると、エラーメッセージが返されます。例:root@Aliyun ~/ssl # kubectl create secret tls tls-test-ingress --key example.com.key --cert httpbin.example.com.crt error: tls: private key does not match public key // エラー: tls: 秘密鍵が公開鍵と一致しません
既存の Secret の場合、次のコマンドを実行して、Secret にこの問題が存在するかどうかを確認できます。
export SECRET_NAME=<Your Secret Name> // SECRET_NAME をエクスポートします export NAME_SPACE=<Your Secret Namespace> // NAME_SPACE をエクスポートします 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" // 証明書と鍵が一致するかどうかを確認します
次の出力が返された場合、この問題は 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 // 証明書と鍵が一致しません
異なる Ingress 用に構成された複数の TLS 証明書で同じドメイン名が使用されています。ただし、1 つの TLS 証明書が正しく構成されていません。構成が正しくない TLS 証明書を見つけて、構成を修正します。
期限切れの証明書を更新した後も、証明書の有効期限に関するアラート通知が引き続き届くのはなぜですか?
特定のバグは、以前のバージョンの NGINX Ingress コントローラーに存在する可能性があります。証明書を更新した後も、metrics nginx_ingress_controller_ssl_expire_time_seconds
メトリックが引き続き存在する可能性があります。この問題を解決するには、NGINX Ingress コントローラーのローリングアップデートを実行する必要があります。この問題は、NGINX Ingress コントローラー V1.11.4 以降で修正されています。NGINX Ingress コントローラーのアップグレード方法の詳細については、「NGINX Ingress コントローラーをアップグレードする」をご参照ください。
NGINX Ingress コントローラーの異なるバージョンのデフォルト構成を表示するにはどうすればよいですか?
NGINX Ingress コントローラーの複数のバージョンが繰り返しリリースされています。パラメーターのデフォルト設定は、バージョンによって異なる場合があります。たとえば、use-gzip
パラメーターは、NGINX Ingress コントローラー V0.35.0 以前ではデフォルトで有効になっていますが、NGINX Ingress コントローラー V1.11.4 ではデフォルトで無効になっています。
特定のバージョンのパラメーターのデフォルト設定に関する情報を取得するには、NGINX Ingress コントローラーの Git リポジトリにある、そのバージョンのブランチ内の configmap.md
ファイルを確認します。次の図は、controller-v1.8.0 バージョンのブランチにある configmap.d ファイルを示しています。ページの左側でバージョンを切り替えることができます。