この記事では、パーソナライズされたエラーページの表示に関連するNGINX Ingressの2つの機能、およびそれらに存在する制限と回避方法についてお話したいと思います。
1.デフォルトのバックエンドの変更
デフォルトでは、NGINX Ingressは対応する機能を実行するデフォルトのバックエンドを使用します。 これは、IngressリソースにないホストでIngressをリクエストすると、404レスポンスコードのページが取得されることを意味します。
ただし、多くの場合、お客様は標準の404ではなく、会社のロゴやその他のアメニティを使用してページを表示するようにというリクエストを受け取ります。 これを行うために、NGINX Ingressには
default-backend-service
をオーバーライドする組み込み機能があります。 同じ名前のオプションには、
namespace/servicename
名形式の引数が引数として
namespace/servicename
れます。 サービスポートは80でなければなりません。
これを行うには、アプリケーション(イングレスnginxリポジトリのYAMLの実装例 )で独自のポッド(デプロイメント)とサービスを作成します。これはデフォルトのバックエンドの代わりに提供されます。
以下に小さな図を示します。
~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/ HTTP/1.1 404 Not Found Date: Mon, 11 Mar 2019 05:38:15 GMT Content-Type: */* Transfer-Encoding: chunked Connection: keep-alive <span>The page you're looking for could not be found.</span>
したがって、YAMLを介して
kind: Ingress
して明示的に作成されていないすべてのドメインは、default-backendに分類されます。 上記のリストでは、
sadsdasdas
そのドメインになっています。
2.デフォルトのバックエンドを使用して、アプリケーションでHTTPエラーを処理する
別の状況は、HTTPエラー(404、500、502 ...)で終わるアプリケーションへの要求で、そのような状況は処理されません(対応する美しいページは生成されません)。 また、多くのアプリケーションで同じエラーページを表示したいという開発者の要望が原因である可能性もあります。
サーバー側でこのケースを実装するには、次のものが必要です。
- デフォルトのバックエンドに関する項目から上記の指示に従ってください。
- たとえば、値
404,503
使用して、構成ConfigMap nginx-ingressにcustom-http-errors
キーを追加します(明らかに、新しいルールでカバーされるエラーコードに対応します)。
期待される結果が達成されます:クライアントアプリケーションが実行され、404または503の応答コードでエラーを受信すると、要求は自動的に新しいデフォルトバックエンドにリダイレクトされます...
ただし、デフォルトのバックエンドおよびcustom-http-errorsのアプリケーションを開発する場合、次の重要な機能を考慮する必要があります。
!!! Important The custom backend is expected to return the correct HTTP status code instead of 200. NGINX does not change the response from the custom default backend.
実際には、リクエストをリダイレクトする場合、ヘッダーには以前の応答コードと追加情報を含む有用な情報が含まれます(それらの完全なリストはこちらで入手できます )。
これは、あなた自身が正しい応答コードを処理する必要があることを意味します。 これがどのように機能するかのドキュメントからの例です。
異なるアプリケーション-異なるデフォルトのバックエンド
ソリューションがクラスター全体に対してグローバルではなく、特定のアプリケーションにのみ適用されるように、まずIngressのバージョンを確認する必要があります。 0.23以上に一致する場合、Ingressネイティブアノテーションを使用します。
- アノテーションを
default-backend
、 各イングレスのdefault-backend
を再定義できdefault-backend
。 - 注釈を使用して 、 各イングレスの
custom-http-errors
をオーバーライドできます。
その結果、イングレスリソースは次のようになります。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: {{ .Chart.Name }}-app2 annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/custom-http-errors: "404,502" nginx.ingress.kubernetes.io/default-backend: error-pages spec: tls: - hosts: - app2.example.com secretName: wildcard-tls rules: - host: app2.example.com http: paths: - path: / backend: serviceName: {{ .Chart.Name }}-app2 servicePort: 80
この場合、エラー404および502は、必要なすべてのヘッダーとともにエラーページサービスにリダイレクトされます。
Ingressの以前のバージョンでは、これは不可能でした ( 0.23での運命的なコミット )。 また、クラスターで2つの完全に異なるアプリケーションを実行しており、それぞれに異なるdefault-backend-serviceを指定し、それぞれに異なるエラーコードを処理したい場合は、2つの回避策を使用する必要があります。
イングレス<0.23:アプローチ1
このオプションは簡単です。 ページを提供するアプリケーションとして、通常のHTMLがあります。HTMLには、ヘッダーを確認して正しい応答コードを提供する方法がわかりません。 そのようなアプリケーションは、Ingressでurl
/error-pages
使用してロールアウトされ、HTMLは
ws
ディレクトリで提供されます。
YAMLの図:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: {{ .Chart.Name }}-app2 annotations: kubernetes.io/ingress.class: "nginx" ingress.kubernetes.io/server-snippet: | proxy_intercept_errors on; error_page 500 501 502 503 504 @error_pages; location @error_pages { rewrite ^ /error-pages/other/index.html break; proxy_pass http://error-pages.prod.svc.cluster.local; } spec: tls: - hosts: - app2.example.com secretName: wildcard-tls rules: - host: app2.example.com http: paths: - path: / backend: serviceName: {{ .Chart.Name }}-app2 servicePort: 80
この展開のサービスは、ClusterIPタイプである必要があります。
同時に、エラーを処理するアプリケーションで、Ingressに次の内容のserver-snippetまたはconfiguration-snippetを追加します。
nginx.ingress.kubernetes.io /server-snippet: | proxy_intercept_errors on; error_page 500 501 502 503 504 @error_pages; location @error_pages { rewrite ^ /error-pages/ws/index.html break; proxy_pass http://error-pages.prod.svc.cluster.local; }
イングレス<0.23:アプローチ2
ヘッダーを処理できるアプリケーションのオプション...とにかく、これはcustom-http-errorsから借用した、より正しい方法です。 手動で使用(コピー)すると、グローバル設定を変更できなくなります。
手順は次のとおりです。 必要なヘッダーをリッスンして正しく応答できるアプリケーションを使用して、同じ展開を作成します。 次の内容でサーバースニペットアプリケーションをIngressに追加します。
nginx.ingress.kubernetes.io /server-snippet: | proxy_intercept_errors off; error_page 404 = @custom_404; error_page 503 = @custom_503; location @custom_404 { internal; proxy_intercept_errors off; proxy_set_header X-Code 404; proxy_set_header X-Format $http_accept; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Namespace $namespace; proxy_set_header X-Ingress-Name $ingress_name; proxy_set_header X-Service-Name $service_name; proxy_set_header X-Service-Port $service_port; proxy_set_header Host $best_http_host; rewrite ^ /error-pages/ws/index.html break; proxy_pass http://error-pages.prod.svc.cluster.local; } location @custom_503 { internal; proxy_intercept_errors off; proxy_set_header X-Code 503; proxy_set_header X-Format $http_accept; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Namespace $namespace; proxy_set_header X-Ingress-Name $ingress_name; proxy_set_header X-Service-Name $service_name; proxy_set_header X-Service-Port $service_port; proxy_set_header Host $best_http_host; rewrite ^ /error-pages/ws/index.html break; proxy_pass http://error-pages.prod.svc.cluster.local; }
ご覧のとおり、処理するエラーごとに、「ネイティブ」のcustom-error-pagesのように、必要なヘッダーがすべて置換される場所を作成する必要があります 。 そのため、個々の場所やサーバーであっても、エラーのある個別のページを作成できます。
PS
その他のK8sのヒントとトリックのサイクル:
- 「 クラスターで動作しているリソースのHelm 2管理への転送 」。
- 「 ノードの割り当てとWebアプリケーションの負荷について 」
- 「 開発サイトへのアクセス 」;
- 「 大規模データベースのブートストラップの高速化。 」
ブログもご覧ください。