NGINX Ingress ControllerによるTCP/UDP負荷分散とWAF構成の強化

NGINX | 2021年3月31日

標準のKubernetes Ingressリソースは、基本的なIngress負荷分散のプロビジョニングと設定には非常に適していますが、Kubernetesを本番環境で利用できるレベルにするために必要なカスタマイズ機能は備えていません。そのため、NGINXを使用しないユーザーは、エラーが発生しやすく、使いにくいうえに安全性に欠け、きめ細かなスコープ設定もできないアノテーション、ConfigMap、カスタムテンプレートを使用せざるを得ません。NGINX Ingressリソースは、この問題を解決するためのF5の答えです。

NGINX Ingressリソースは、NGINX Ingress ControllerのNGINX Open Sourceベース版とNGINX Plusベース版の両方で利用できます。ネイティブかつ型安全で、インデントを使用した設定形式により、Ingressロードバランシングを容易に実装できます。このブログでは、WAFとロードバランシングポリシーをより簡単に設定できるよう、NGINX Ingress Controller 1.11.0で導入された2つの機能を取り上げます。

  • TransportServerリソース – TransportServerリソースでは、TCP、UDP、TLS Passthroughの負荷分散設定を定義します。TCP/UDP負荷分散を強化するため、ヘルスチェック、ステータスレポート、設定スニペットを追加しました。
  • NGINX Ingress WAFポリシー – NGINX App Protect 3.0をNGINX Ingress Controllerとともにデプロイすると、NGINX Ingressリソースを活用して、特定のKubernetesサービスにWAFポリシーを適用できます。

TransportServerリソースの機能強化

NGINX Ingress Controller 1.11.0では、TransportServer(TS)リソースが以下の領域で拡張されています。

注:リリース1.11.0でTransportServerリソースに追加された機能は、現在開発中のテクノロジープレビューです。今後のリリースで、安定した本番環境対応の品質基準へと移行する予定です。

TransportServerスニペット

In NGINX Ingress Controllerでは、VirtualServerおよびVirtualServerRoute(VSおよびVSR)リソース向けの設定スニペットを導入しました。これにより、HTTPベースのクライアント用NGINX Ingress設定をネイティブに拡張できます。リリース1.11.0ではTSリソース向けのスニペットが導入され、NGINXおよびNGINX Plusのあらゆる機能を容易に活用して、TCP/UDPベースのサービスを提供できます。たとえば、スニペットを使用して、サービスにアクセスできるクライアントをIPアドレスと範囲で定義するdenyおよびallowディレクティブを追加できます。

apiVersion: k8s.nginx.org/v1alpha1kind: TransportServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  serverSnippets: |
    deny  192.168.1.1;
    allow 192.168.1.0/24;
  upstreams:
  - name: tea
    service: tea-svc
    port: 80

ヘルスチェック

Kubernetesクラスターの健全性を監視するため、NGINX Ingress Controllerは、Kubernetesプローブ(アプリケーションPodに対してローカルに実行される)だけでなく、TCP/UDPベースのアップストリームサービス間のネットワーク状態も監視します。パッシブヘルスチェックで処理中のトランザクションの健全性を評価し、NGINX Plus専用のアクティブヘルスチェックで、疑似接続リクエストを使用してエンドポイントを定期的にプローブします。

ヘルスチェックは、サーキットブレーカーやアプリケーションエラーの処理に非常に役立ちます。ヘルスチェックは、TSリソースの「healthCheck」フィールドのパラメーターを使用してカスタマイズできます。これらのパラメーターでは、プローブの実行間隔、タイムアウト、プローブ間の遅延時間などを設定できます。

さらに、NGINX Ingress Controllerから送信されるヘルスプローブの送信先として、アップストリームサービスとポートを設定できます。これは、アプリケーションの複数のダウンストリームコンポーネントを監視する別のプロセスまたはサブシステムによって、アップストリームアプリケーションのヘルス情報が別のリスナーで公開されている場合に役立ちます。

複数のTransportServerリソースをサポートするingressClassName

TSリソースを更新して適用する際は、構成が有効であり、対応するIngress Controllerデプロイメントに正常に適用されたことを確認すると便利です。リリース1.11.0では、TSリソース向けにingressClassNameフィールドとステータスレポートが導入されました。複数のデプロイメントが存在する環境では、ingressClassNameフィールドにより、特定のIngress ControllerデプロイメントでTSリソースが処理されるようになります。

1つまたはすべてのTSリソースのステータスを表示するには、kubectl get transportserverコマンドを実行します。出力には、状態(ValidまたはInvalid)、直近の更新理由、および(単一のTSの場合)カスタムメッセージが含まれます。

$ kubectl get transportserver  NAME      STATE   REASON           AGE
  dns-tcp   Valid   AddedOrUpdated   47m

$ kubectl describe transportserver dns-tcp
. . .
Status:
  Message:  Configuration for default/dns-tcp was added or updated
  Reason:   AddedOrUpdated
  State:    Valid

複数のTSリソースが同じホスト/リスナーを使用しようと競合する場合、NGINX Ingress Controllerはタイムスタンプが最も古いTSリソースを選択し、その状況で結果が一意に決まるようにします。

ネイティブのNGINX App Protectサポートを使用したWAFポリシーの定義

NGINX Ingressリソースを使用すると、構成が容易かつ柔軟になるだけでなく、トラフィック制御を複数のチームに委任し、VirtualServerRoute(VSR)リソースで定義されているアプリケーションのサブルートを所有するユーザーに対して、より厳格な権限制限を適用できます。適切なチームに適切なKubernetesリソースへのアクセス権を付与することで、ネットワークリソースをきめ細かく制御し、ユーザーのアカウントが侵害されたり、ハッキングされたりした場合にアプリケーションが受ける可能性のある損害を軽減できます。

リリース1.11.0では、ネイティブのWebアプリケーションファイアウォール(WAF)Policyオブジェクトが導入され、Kubernetes環境におけるNGINX App Protectの設定にも、これらのメリットが拡張されました。このポリシーでは、APLogConfおよびAPPolicyオブジェクトを活用します。これらはリリース1.8.0で導入されており、VirtualServer(VS)リソースとVSRリソースの両方に関連付けることができます。これにより、セキュリティ管理者はVSリソースを使用してIngress設定全体を管理しながら、VSRリソースを参照することで、セキュリティに関する責任を他のチームに委任できます。

次の例では、waf-prodポリシーが、webapp-prodアップストリームにルーティングされるユーザーに適用されます。異なるチームが所有する名前空間間で/v2ルートのセキュリティ責任を委任するため、強調表示されたrouteディレクティブはVSRリソースを参照します。

apiVersion: k8s.nginx.org/v1kind: VirtualServer
metadata:
  name: webapp
spec:
  host: webapp.example.com
  policies:
  - name: waf-prod 
  tls:
    secret: app-secret
  upstreams:
  - name: webapp-prod
    service: webapp-svc
    port: 80
  routes:
  - path: /v2
    route: test/test
  - path: /v1
    action:
      pass: webapp-prod

The teams that manage the test名前空間を管理するチームは、その名前空間内のVSRリソースを使用して、独自のパラメーターとWAFポリシーを設定できます。

apiVersion: k8s.nginx.org/v1kind: VirtualServerRoute
metadata:
  name: test 
  namespace: test
spec:
  host: webapp.example.com
  upstreams:
  - name: webapp 
    service: webapp-test-svc
    port: 80
  subroutes:
  - path: /v2
    policies:
    - name: waf-test
    action:
      pass: webapp

この例では、テナントを名前空間ごとに分離し、webapp-test-svcサービスに対して、test名前空間内で異なるWAFポリシーを適用しています。また、リソースを各チームに委任し、オブジェクトでカプセル化することで、本番環境のアプリケーションに影響を与えることなく、新機能のテストを簡素化できることを示しています。

リリース1.11.0のその他の新機能

NGINX Ingress Controller 1.11.0でも、柔軟かつ高機能で使いやすい、本番環境向けのIngressコントローラーを提供するという取り組みを継続しています。WAFとTSの改善に加え、リリース1.11.0には以下の機能強化が含まれています。

追加アノテーションの検証

リリース1.10.0で導入されたアノテーション検証の改善を基盤として、以下のアノテーションも検証するようになりました:

アノテーションの検証nginx.org/client-max-body-size 有効なオフセットである必要がありますnginx.org/fail-timeout 有効な時間である必要がありますnginx.org/max-conns 有効な非負整数である必要がありますnginx.org/max-fails 有効な非負整数である必要がありますnginx.org/proxy-buffer-size 有効なサイズである必要がありますnginx.org/proxy-buffers 有効なプロキシバッファ仕様である必要がありますnginx.org/proxy-connect-timeout 有効な時間である必要がありますnginx.org/proxy-max-temp-file-size 有効なサイズである必要がありますnginx.org/proxy-read-timeout 有効な時間である必要がありますnginx.org/proxy-send-timeout 有効な時間である必要がありますnginx.org/upstream-zone-size 有効なサイズである必要があります

Ingressリソースの適用時にアノテーションの値が無効な場合、Ingress Controllerはそのリソースを拒否し、対応する設定をNGINXから削除します。

ポリシーのステータス情報

The kubectl get policyコマンドで、ポリシーの状態(ValidまたはInvalid)に加え、単一のTSの場合はカスタムメッセージと最新の更新理由が報告されるようになりました。

$ kubectl get policy  NAME              STATE   AGE
  webapp-policy     Valid   30s

$ kubectl describe policy webapp-policy
. . .
Status:
  Message:  Configuration for default/webapp-policy was added or updated
  Reason:   AddedOrUpdated
  State:    Valid

Istioとの互換性

NGINX Ingress Controllerを、Istioサービスメッシュ内で実行されるアプリのIngressコントローラーとして使用できるようになりました。これにより、回避策を講じることなく、Istioベースの環境でもNGINX Ingress Controllerが提供する高度な機能を引き続き利用できます。この統合には、次の2つの要件があります。

  • NGINX Ingress ControllerデプロイメントへのIstioサイドカーのインジェクション
  • バックエンドに送信されるHTTP Hostヘッダーは1つだけです

最初の要件を満たすには、NGINX Ingress Deploymentファイルのannotationsフィールドに以下の項目を含めます。

annotations:   traffic.sidecar.istio.io/includeInboundPorts: "" 
  traffic.sidecar.istio.io/excludeInboundPorts: "80,443"         
  traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.90.0.0/16,10.45.0.0/16"     sidecar.istio.io/inject: 'true'

2つ目の要件は、requestHeadersフィールドの動作を変更することで満たされます。以前のリリースでは、以下の設定により、2つのHostヘッダー($hostと指定値のbar.example.com)がバックエンドに送信されていました。

apiVersion: k8s.nginx.org/v1kind: VirtualServer
metadata:
  name: foo 
spec:
  host: foo.example.com
  upstreams:
  - name: foo
    port: 8080
    service: backend-svc
    use-cluster-ip: true
  routes:
  - path: "/"
    action:
      proxy:
        upstream: foo
        requestHeaders: set: - name: Host value: bar.example.com

リリース1.11.0以降では、指定した値のみが送信されます。$hostを送信するには、requestHeadersフィールドを完全に省略してください。

アップストリームエンドポイントのCluster-IPアドレス

NGINX Ingress Controllerの設定では、アップストリームエンドポイントに、Podエンドポイントの個別のIPアドレスではなく、サービス/Cluster-IPアドレスを指定できるようになりました。NGINX Ingress ControllerがCluster-IPサービスにトラフィックをルーティングできるようにするには、VSまたはVSR設定のuse-cluster-ip: trueフィールドをupstreamsセクションに含めます。

upstreams:  - name: tea
    service: tea-svc
    port: 80
    use-cluster-ip: true
  - name: coffee
    service: coffee-svc
    port: 80
    use-cluster-ip: true

リソース

リリース1.11.0の完全な変更履歴については、「リリースノート」を参照してください。

NGINX PlusおよびNGINX App Protectを搭載したNGINX Ingress Controller for Kubernetesをお試しいただくには、30日間の無料トライアルを今すぐ開始するか、ユースケースについてご相談ください。

NGINX Open SourceでNGINX Ingress Controllerをお試しいただくには、リリース版のソースコードを入手するか、DockerHubからビルド済みコンテナをダウンロードできます。

Ingressコントローラーの違いについては、F5のブログ記事「待って、私が使っているKubernetes向けNGINX Ingress Controllerはどれ?」をご覧ください。


共有

著者について

Amir Rawdat
Amir Rawdatソリューションエンジニア

Amir Rawdatのその他のブログ記事

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります