BLOG | NGINX

NGINX Ingress ControllerによるマルチクラスタDNSの自動化

NGINX-Part-of-F5-horiz-black-type-RGB
Amir Rawdat サムネール
Amir Rawdat
Published October 25, 2022

ユーザがアプリケーションを見つけられないことには、アプリケーションはその目的を果たすことができません。ドメインネームシステム(DNS)は、ドメイン名をIPアドレスに変換することで、アプリケーションやWebサイトを「発見」するインターネットテクノロジです。DNSは非常にユビキタスで信頼性が高いため、ほとんどの場合、それについて意識することはありません。しかし、DNSに問題が発生すると、すべてが停止してしまいます。DNSが機能していることを確認することは、最新のアプリケーション、特にサービスが絶えずスピンアップ・ダウンしているマイクロサービスアーキテクチャにおいては非常に重要です。

前回の記事では、同じクラスタで実行されているアプリケーションに対応する2つのサブドメイン(Marketingアプリケーションの場合はunit-demo.marketing.netEngineeringアプリケーションの場合は unit-demo.engineering.net)のDNSレコードを定義して、同じクラスタエントリーポイント、つまりクラスタのNGINX Ingress Controllerの外部IPアドレスに解決することについて説明しました。Server Name Indication (SNI) ルーティングはNGINX Ingress Controllerで構成され、ユーザが要求したドメイン名に基づいて適切なアプリケーションへの接続を認証し、ルーティングします。

しかし、多くの組織ではそのユースケースを拡張し、複数のKubernetesクラスタにアプリケーションを導入する必要性に迫られおり、それらのクラスタはクラウドプロバイダのリージョン全体に分散している可能性があります。外部トラフィックが新しいクラスタリージョンに到達するには、それらのリージョンに解決されるDNSゾーンを作成する必要があります。

これまで、このプロセスでは、サードパーティのプロバイダ(GoDaddyやDNSExitなど)を利用して手動でドメインレジストリを作成し、ホストレコードを適切に更新する必要がありました。が、現在では ExternalDNS Kubernetesプロジェクトは、パブリックDNSサーバーを介してKubernetesリソース検出可能にすることで、プロセスを自動化しています。つまり、Kubernetes APIを使用してDNSプロバイダのリストを構成します。

ExternalDNSとNGINX Ingress Controllerの統合は、DNSの名前が標準のKubernetes IngressリソースまたはNGINX VirtualServerカスタムリソースで宣言されたホスト名から派生するように、DNS Aレコードを管理可能とします。開発者と DevOpsチームは、CI/CDパイプラインでこの統合を活用して、NetOps チーム (通常はDNSを所有するチーム) の関与なしに、さまざまなクラスタにわたってアプリケーションを自動的に検出できます。

この記事では、GitHubリポジトリのサンプル設定ファイルを使用して、ExternalDNSをNGINX Ingress Controllerと統合する方法を説明します。

基本アーキテクチャ

NGINX Ingress ControllerでExternalDNSを実装するには、開発者がKubernetesアプリケーションを外部公開するようにIngressコントローラを構成する基本ケースから始めます。構成されたドメイン名がKubernetesクラスタのパブリックエントリポイントに解決されるまで、クライアントはアプリケーションに接続できません。

NGINX Ingress Controllerは、中間的なExternalDNS Kubernetesの導入を介してDNSプロバイダとインタラクトし、外部DNSレコードを使用してKubernetesアプリケーションを自動検出できるようにします。 図の黒い線は、外部ユーザがKubernetesクラスタ内のアプリケーションにアクセスする際のデータパスを表しています。紫色の線は、アプリケーション所有者がNGINX Ingress Controller構成のVirtualServerリソースを使用して外部DNSレコードを管理し、外部DNSがDNSプロバイダにアクセスする制御パスを表しています。

Diagram how ExternalDNS Kubernetes deployment interacts NGINX Ingress Controller with DNS provider

ExternalDNSとNGINX Ingress Controllerの統合

次のセクションの手順を実行して、ExternalDNSとNGINX Ingress Controllerを統合します。

Prerequisites(前提条件)

  1. 少なくとも1つの登録済みドメインを作成します。次の手順では、その名前を <my‑domain>に置き換えます (ドメインの登録方法については、このPCMagのガイドをはじめ、多くの記事で公開されています)。
  2. NGINX Ingress ControllerをマニフェストまたはHelmチャートを使って導入します。次に示すものと同等のコマンドライン引数を導入仕様に追加します。

    • -enable-external-dns – ExternalDNSとの統合を有効にする。
    • -external-service=nginx-ingress – DNSプロバイダが管理するAレコードに記録するために、NGINX Ingress Controllerにパブリックエントリポイントをアドバタイズするように指示します。パブリックエントリポイントのホスト名は、外部サービスnginx-ingressに解決されます。
  3. Kubernetesクラスタをオンプレミスで導入する場合は、外部ロードバランサをプロビジョニングします。BGPを使用してNGINXの導入手順については、無料のeBookの『Get Me to the Cluster』を参照してください。または、F5 BIG‑IPMetalLBを使用します。
  4. 必要に応じて、DNSゾーンをExternalDNSによってサポートされているプロバイダに作成します。このコマンドは、サンプルの導入で使用されるプロバイダ、Google Cloud DNS用です。

    $ gcloud dns managed-zones create "external-dns-<my-domain>" --dns-name "external-dns.<my-domain>." --description "Zone automatically managed by ExternalDNS"

NGINX Ingress ControllerとExternalDNSのデプロイ

  1. GitHubリポジトリをクローンし、NGINX Ingress Controllerを導入します。

    $ git clone https://github.com/nginxinc/NGINX-Demos.git && cd NGINX-Demos/external-dns-nginx-ingress/$ kubectl apply -f nginx-ingress.yaml && kubectl apply -f loadbalancer.yaml
  2. 次のExternalDNSの導入仕様の引数(サンプルの導入では、 external-dns-gcloud.yamlの59〜62行目)を更新します。

    • --domain-filter – 前のセクションの手順 4で作成したドメイン名(サンプルの導入では、external-dns.<my-domain>)。このドメインのみが使用されるように、既存の値をすべて削除します。
    • --provider – DNSプロバイダ(サンプルの導入では、Google DNSの場合はgoogle)。
    • --google-project – サンプルの導入で使用しているGoogleプロジェクトの名前(複数のGoogleプロジェクトがある場合のみ必須)。
    • --txt-owner-id – 選択したID(サンプルの導入固有)。

    注:ExternalDNSの導入仕様に含める必要がある引数は、選択したDNSプロバイダによって異なる場合があります。さまざまなDNSプロバイダを使用してクラスタにExternalDNSを導入する方法を示すチュートリアル一覧については、ExternalDNSのドキュメントを参照してください。

  3. クラスタにExternalDNSを導入し、導入が正常に実行されることを確認します(出力は読みやすくするために2行に分かれています)。

    $ kubectl apply -f external-dns-gcloud.yaml$ kubectl get pods -o wideNAME                                READY  STATUS    ...external-dns-4hrytf7f98f-ffuffjbf7  1/1    Running   ...    ... RESTARTS   AGE    ... 0          1m

NGINX Ingress Controllerの構成

次に、外部接続をKubernetesアプリケーションにルーティングするIngressロードバランシングルールを使用して、VirtualServerリソースを構成します。

  1. app-virtual-server.yamlには、host(ホスト)フィールド(6行目)を設定します。

     6    host: ingress.external-dns.<my-domain>

    この値とexternal-dns-gcloud.yamlの59行目のdomain-filterの値(前のセクションの手順2で設定)とのマッピングにより、DNSレコードの自動更新が可能になります。

  2. app-virtual-server.yamlを適用し、VirtualServerが正しく構成されていることを確認します。

    $ kubectl apply -f app-secret.yaml && kubectl apply -f app-virtual-server.yaml$ kubectl get vsNAME   STATE   HOST                              IPcafe   Valid   ingress.external-dns.<my-domain>  34.168.X.Y
  3. DNSタイプAレコードがDNSゾーンに追加されていることを確認します。特に、DATA(データ)フィールドのIPアドレスは、前の手順のkubectl get vsコマンドから出力されるIPフィールドと一致する必要があります(NGINX Ingress Controllerを公開するタイプ のLoadBalancerサービスにおける外部IPアドレス、またはオンプレミスの導入において同等のIPアドレス)。

    $ gcloud dns record-sets list --zone external-dns-<my-domain> -name ingress.external-dns.<my-domain> --type ANAME                               TYPE     TTL     DATAingress.external-dns.<my-domain>.  A        300     34.168.X.Y
  4. ローカルマシンでVirtualServerのホスト名を解決できることを確認するには、DNSゾーンに割り当てられたネームサーバーを取得します(この場合は、my-ns-domains)。

    $ gcloud dns record-sets list --zone external-dns.<my-domain> --name external-dns.<my-domain>. --type NSNAME                        TYPE      TTL     DATAexternal-dns.<my-domain>.   NS        21600   my-ns-domains$ dig +short @my-ns-domains ingress.external-dns.<my-domain>34.168.X.Y
  5. 前の手順で取得したDNSレコードを、登録済みドメインの専用ネームサーバーとして使用します。 これにより、登録されたドメインが、「前提条件」の手順4で作成されたDNSゾーンの親ゾーンとして設定されます。
  6. グローバルインターネットに公開されたVirtualServerホスト名にアクセスできることを確認します。

    $ curl -i --insecure https://ingress.external-dns.<my-domain>/teaHTTP/1.1 200 OKServer: nginx/1.23.0Date: Day, DD MM YYYY hh:mm:ss TZContent-Type: text/plainContent-Length: 160Connection: keep-aliveExpires: Day, DD MM YYYY hh:mm:ss TZCache-Control: no-cache

複数のKubernetesクラスタのスケールアウト

外部DNSレコードの作成を自動化し、ダイアグラム内の新しいクラスタのエントリポイント(Kubernetesクラスタ1とKubernetesクラスタ2)を解決に導くことで、アーキテクチャをすばやくスケーリングし、複数のクラスタを自動的に検出できます。「NGINX Ingress ControllerとExternalDNSのデプロイ」「NGINX Ingress Controllerの設定」の手順を繰り返します。

Diagram automating the creation of external DNS records and resolving them to new cluster entry points

CI/CDパイプラインでInfrastructure-as-Codeツールを使って、ExternalDNSおよびNGINX Ingress Controllerで新しいクラスタを生成し、外部トラフィックに公開することもできます。さらに、検出を有効にする方法に応じて、複数のDNSゾーンまたは複数のDNSプロバイダを管理できます。

結論

高い生産性と侵害を軽減するセキュリティ対策とを両立させることは、難しい場合があります。DevOpsチームに制限を課すと、NetOps/SecOpsチームとの間に摩擦が生じることがよくあります。理想的なバランスは組織によって異なりますが、NGINXはお客様の優先順位や要件に沿ったバランスを確立する柔軟性を提供します。

これまで、アプリケーションの所有者はNetOpsチームに依存してアプリケーションを外部システムに接続していました。NGINXとExternalDNSを統合することで、開発者とDevOpsチームは検出可能なアプリケーションを独自に導入できるようになり、イノベーションを市場に投入するまでの時間を短縮できます。

KubernetesでNGINXを使い始めるための総合的な完全ガイドについては、当社の無料eBook『Managing Kubernetes Traffic with F5 NGINX: A Practical Guide(F5 NGINXによるKubernetesトラフィックの管理:実践的なガイド)』をダウンロードしてください。

また、今すぐ、NGINX App Protect WAFとDoSを備えたNGINX Ingress Controllerの30日間無料トライアルをお申し込みいただくか、具体的なユースケースについてお問合わせください。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."