ユーザーがアプリケーションを見つけられなければ、その目的を果たすことはできません。ドメインネームシステム(DNS)は、ドメイン名をIPアドレスに変換してアプリケーションやWebサイトを「見つける」ためのインターネット技術です。DNSは広く普及し、安定して機能しているため、普段は意識することがほとんどありません。しかし、DNSに問題が発生すると、すべてが停止します。DNSが確実に機能することは、最新のアプリケーションにとって極めて重要です。特に、サービスが絶えず起動と停止を繰り返すマイクロサービスアーキテクチャでは欠かせません。
In a 以前の記事では、同じクラスターで実行されているアプリケーションに対応し、同じクラスターエントリーポイントを名前解決先とする2つのサブドメインのDNSレコードを定義する方法について説明しました(unit-demo.marketing.netはMarketingアプリ、unit-demo.engineering.netはEngineeringアプリに対応)。このエントリーポイントは、クラスターのNGINX Ingress Controllerの外部IPアドレスです。NGINX Ingress ControllerにはServer Name Indication(SNI)ルーティングが設定されており、ユーザーがリクエストしたドメイン名に基づいて接続を認証し、適切なアプリケーションにルーティングします。
しかし、多くの組織では、このユースケースを拡張し、クラウドプロバイダーの複数のリージョンにまたがる可能性がある複数のKubernetesクラスターにアプリケーションをデプロイする必要があります。外部トラフィックが新しいクラスターリージョンに到達できるようにするには、それらのリージョンに名前解決されるDNSゾーンを作成する必要があります。
以前は、このプロセスを実行するために、サードパーティープロバイダー(GoDaddyやDNSExitなど)を利用してドメインレジストリを手動で作成し、ホストレコードを適切に更新する必要がありました。現在では、ExternalDNS Kubernetesプロジェクトにより、KubernetesリソースをパブリックDNSサーバー経由で検出できるようになり、このプロセスが自動化されています。つまり、Kubernetes APIを使用してDNSプロバイダーのリストを設定できます。
ExternalDNSとNGINX Ingress Controllerを統合すると、標準のKubernetes IngressリソースまたはNGINX Aレコードを管理し、NGINX VirtualServerカスタムリソースで宣言されたホスト名からDNS名を生成できます。開発者やDevOpsチームは、この統合をCI/CDパイプラインで活用することで、通常DNSを管理するNetOpsチームを介さずに、異なるクラスター上のアプリケーションを自動的に検出できます。
この記事では、F5のGitHubリポジトリにあるサンプル構成ファイルを使用して、ExternalDNSとNGINX Ingress Controllerを統合する方法を紹介します。
基本アーキテクチャ
NGINX Ingress ControllerでExternalDNSを実装するにあたり、まずは、開発者がIngressコントローラーを構成してKubernetesアプリを外部に公開する基本的なケースから説明します。構成したドメイン名がKubernetesクラスターのパブリックエントリーポイントに名前解決されるまで、クライアントはアプリに接続できません。
NGINX Ingress Controllerは、仲介役となるExternalDNS Kubernetesデプロイメントを介してDNSプロバイダーと連携し、外部DNSレコードを使用したKubernetesアプリケーションの自動検出を可能にします。図中の黒線は、外部ユーザーがKubernetesクラスター内のアプリケーションにアクセスする際のデータパスを示しています。紫線は、アプリケーション所有者がNGINX Ingress Controller構成内のVirtualServerリソースを使用して外部DNSレコードを管理し、ExternalDNSがDNSプロバイダーにアクセスする際の制御パスを示しています。

ExternalDNSとNGINX Ingress Controllerの統合
ExternalDNSとNGINX Ingress Controllerを統合するには、以下のセクションの手順を実行します。
前提条件
- 登録済みドメインを少なくとも1つ作成します。そのドメイン名を、以下の手順にある「
<my‑domain>」に置き換えてください。(ドメインの登録方法については、こちらの「PCMagのガイド」をはじめ、多くの記事が公開されています。) - NGINX Ingress ControllerをマニフェストまたはHelmチャートを使用してデプロイします。デプロイ仕様に、以下のコマンドライン引数に相当する設定を追加します:
-enable-external-dns– ExternalDNSとの統合を有効にします。-external-service=nginx-ingress– DNSプロバイダーが管理するAレコードに登録できるよう、NGINX Ingress Controllerにパブリックエントリポイントを公開するよう指示します。パブリックエントリポイントのホスト名は、外部サービスnginx-ingressに解決されます。
- Kubernetesクラスターをオンプレミスにデプロイする場合は、外部ロードバランサーをプロビジョニングします。無料のeBook「Get Me to the Cluster」では、BGPを使用してNGINXを外部ロードバランサーとしてデプロイする手順を紹介しています。または、F5 BIG‑IPやMetalLBも使用できます。
- 必要に応じて、ExternalDNSがサポートするプロバイダーにDNSゾーンを作成します。このコマンドは、サンプルデプロイで使用するプロバイダーである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のデプロイ
- サンプルデプロイ用の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- ExternalDNSのデプロイ仕様で、次の引数を更新します(サンプルデプロイの場合はexternal-dns-gcloud.yamlの59~62行目)。注:ExternalDNSのデプロイ仕様に含める必要がある引数は、選択するDNSプロバイダーによって異なる場合があります。さまざまなDNSプロバイダーを使用してExternalDNSをクラスターにデプロイするチュートリアルの一覧については、ExternalDNSドキュメントを参照してください。
--domain-filter– 前のセクションのステップ4で作成したドメインの名前(サンプルデプロイでは「external-dns.<my-domain>」)。このドメインのみが使用されるように、既存の値をすべて削除します。--provider– DNSプロバイダー(サンプルデプロイでは、Google DNS用の「google」)。--google-project– サンプルデプロイで使用するGoogleプロジェクトの名前(Googleプロジェクトが複数ある場合にのみ必須)。--txt-owner-id– 選択するID(サンプルデプロイメントに固有)。
- クラスターにExternalDNSをデプロイし、デプロイが正常に実行されることを確認します(読みやすいように、出力は2行に分けて表示しています)。
$ kubectl apply -f external-dns-gcloud.yaml$ kubectl get pods -o wide
NAME READY STATUS ...
external-dns-4hrytf7f98f-ffuffjbf7 1/1 Running ...
... RESTARTS AGE
... 0 1mNGINX Ingress Controllerの設定
次に、外部接続をKubernetesアプリケーションにルーティングするIngress負荷分散ルールを使用して、VirtualServerリソースを構成します。
- In app-virtual-server.yamlで、
hostフィールド(6行目)を設定します:
6 host: ingress.external-dns.<my-domain>- この値と、
domain-filter(external-dns-gcloud.yamlの59行目にあり、前のセクションのステップ2で設定)の値を対応付けることで、DNSレコードが自動的に更新されます。 - Apply app-virtual-server.yamlを適用し、VirtualServerが正しく構成されていることを確認します。
$ kubectl apply -f app-secret.yaml && kubectl apply -f app-virtual-server.yaml
$ kubectl get vs
NAME STATE HOST IP
cafe Valid ingress.external-dns.<my-domain> 34.168.X.Y- DNSタイプ
AのレコードがDNSゾーンに追加されていることを確認します。特に、DATAフィールドのIPアドレスは、前の手順で実行したkubectlgetvsコマンドの出力にある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 DATA
ingress.external-dns.<my-domain>. A 300 34.168.X.Y- VirtualServerのホスト名をローカルマシンで名前解決できることを確認するため、DNSゾーンに割り当てられているネームサーバー(この場合は「
my-ns-domains」)を取得します。
$ gcloud dns record-sets list --zone external-dns.<my-domain> --name external-dns.<my-domain>. --type NSNAME TYPE TTL DATA
external-dns.<my-domain>. NS 21600 my-ns-domains
$ dig +short @my-ns-domains ingress.external-dns.<my-domain>
34.168.X.Y- 前の手順で取得したDNSレコードを、登録済みドメイン専用のネームサーバーとして使用します。これにより、登録済みドメインが、前提条件のステップ4で作成したDNSゾーンの親ゾーンとして設定されます。Prerequisites.
- VirtualServerのホスト名がグローバルインターネットに公開されたため、アクセスできることを確認します。
$ curl -i --insecure https://ingress.external-dns.<my-domain>/teaHTTP/1.1 200 OK
Server: nginx/1.23.0
Date: Day, DD MM YYYY hh:mm:ss TZ
Content-Type: text/plain
Content-Length: 160
Connection: keep-alive
Expires: Day, DD MM YYYY hh:mm:ss TZ
Cache-Control: no-cache複数のKubernetesクラスターのスケールアウト
外部DNSレコードの作成を自動化し、図に示す新しいクラスターのエントリーポイント(Kubernetes Cluster 1およびKubernetes Cluster 2)に名前解決することで、アーキテクチャを迅速にスケールアウトし、複数のクラスターを自動的に検出できます。NGINX Ingress ControllerとExternalDNSのデプロイおよびNGINX Ingress Controllerの構成の手順を繰り返します。

CI/CDパイプラインでInfrastructure-as-Codeツールを使用し、ExternalDNSとNGINX Ingress Controllerを利用して新しいクラスターを作成し、外部トラフィックに公開することもできます。さらに、検出の有効化方法に応じて、複数のDNSゾーンや複数のDNSプロバイダーを管理できます。
まとめ
生産性と、侵害を軽減するためのセキュリティ対策を両立させることは容易ではありません。DevOpsチームに制約を課すと、NetOps/SecOpsチームとの間に摩擦が生じることがよくあります。最適なバランスは組織ごとに異なりますが、NGINXなら、優先事項や要件に沿ったバランスを柔軟に確立できます。
従来、アプリケーションの所有者は、アプリケーションを外部システムに接続する際にNetOpsチームに依存していました。NGINXとExternalDNSの統合を利用することで、開発者やDevOpsチームは、検出可能なアプリケーションを自らデプロイできるようになり、イノベーションの市場投入までの時間短縮につながります。
KubernetesでNGINXを使い始めるための包括的なガイドとして、無料のeBook「F5 NGINXによるKubernetesトラフィック管理:実践ガイド」をダウンロードしてください。
また、NGINX App Protect WAFおよびDoSを搭載したNGINX Ingress Controllerの30日間無料トライアルをお申し込みいただくか、ユースケースについてご相談いただくためにお問い合わせいただくことで、今すぐご利用を開始できます。
著者について

関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります