NGINX.COM
Web Server Load Balancing with NGINX Plus

应用服务只有被用户发现,才能发挥作用。域名系统 (DNS) 是一项互联网技术,用于把域名转换为 IP 地址,以便“发现”应用和网站。DNS 无处不在,且稳定可靠,因此大多数时候您都不会注意到它。但当 DNS 出现问题时,一切服务都会停止。确保 DNS 正常运行对于现代应用而言至关重要,特别是在服务不断增减变化的微服务架构中。

在之前的博文中,我们介绍了如何定义两个子域的 DNS 记录,这两个子域与运行在同一集群中的应用(Marketing 应用为 unit-demo.marketing.netEngineering 应用为 unit-demo.engineering.net)相对应,并解析到同一集群入口 — 即集群的 NGINX Ingress Controller 的外部 IP 地址。服务器名称指示 (SNI) 路由在 NGINX Ingress Controller 上进行配置,可根据用户请求的域名来验证连接并将其路由到相应的应用。

但许多企业需要扩展该用例,并将应用部署至多个 Kubernetes 集群,这些集群可能分散在不同的云提供商区域中。为了让外部流量到达新的集群区域,您需要创建可解析到这些区域的 DNS 区域(zone)。

过去,该流程需要第三方提供商(如 GoDaddy 或 DNSExit)手动创建一个域注册表并同时更新主机记录。现在,ExternalDNS Kubernetes 项目借助公共 DNS 服务器使 Kubernetes 资源具有可发现性,从而将这一流程自动化。这意味着您可以使用 Kubernetes API 来配置 DNS 服务提供商列表。

借助 ExternalDNS 与 NGINX Ingress Controller 之间的集成,您可以管理 DNS A 记录,让 DNS 名称来自于标准 Kubernetes Ingress 资源,或在 NGINX VirtualServer 自定义资源中声明的主机名。开发人员和 DevOps 团队可以在其 CI/CD 流水线中利用这种集成,自动发现不同集群中的应用,而无需麻烦 NetOps 团队(通常拥有 DNS)。

在本文中,我们将展示如何使用 GitHub 仓库中的示例配置文件来集成 ExternalDNS 与 NGINX Ingress Controller。

 

基础架构

为了使用 NGINX Ingress Controller 实现 ExternalDNS,我们从开发人员配置 Ingress Controller 以将 Kubernetes 应用暴露给外部的基本操作开始。在配置的域名解析到 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。

准备工作

  1. 至少创建一个注册域名。在以下步骤中,将其名称替换为 <my‑domain>。(现有很多关于如何注册域名的文章,包括这份来自 PCMag 的指南)。
  2. 使用 manifestsHelm 图表部署 NGINX Ingress Controller。在 deployment 中添加以下命令行参数的等效参数:

    • -enable-external-dns — 启用集成 ExternalDNS。
    • -external-service=nginx-ingress — 让 NGINX Ingress Controller 公布其公共入口点,以便记录在 DNS 提供商管理的 A 记录中。公共入口点的主机名解析为外部服务 nginx-ingress
  3. 如果您在本地部署 Kubernetes 集群,请配置一个外部负载均衡器。在我们的免费电子书《与集群相伴》(Get Me to the Cluster) 中,我们提供了使用 BGP 将 NGINX 部署为外部负载均衡器的说明。另外,您可以使用 F5 BIG‑IPMetalLB
  4. 如有必要,在 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

  1. 克隆 GitHub repository 以部署示例,并部署 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 deployment 中的以下参数(该示例部署为 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 deployment 中所需添加的参数可能因所选的 DNS 服务提供商而异。关于通过不同 DNS 服务提供商将 ExternalDNS 部署到集群的教程列表,请参阅 ExternalDNS 文档

  3. 将 ExternalDNS 部署至集群,并验证部署是否成功运行(为方便阅读,输出结果分成了两行)。

    $ 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          1m
    

配置 NGINX Ingress Controller

接下来,我们使用入向负载均衡规则配置 VirtualServer 资源,该规则将外部连接路由到 Kubernetes 应用。

  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 vs 
    NAME   STATE   HOST                              IP            
    cafe   Valid   ingress.external-dns.<my-domain>  34.168.X.Y
  3. 验证 DNS 类型 A 记录是否已添加到 DNS 区域。注意,DATA 字段中的 IP 地址必须匹配上一步中 kubectl get vs 命令输出的 IP 字段(LoadBalancer 类型的服务的外部 IP 地址,用于暴露 NGINX Ingress Controller,或本地部署中的同等 IP 地址)。

    $ gcloud dns record-sets list --zone external-dns-<my-domain> -name ingress.external-dns.<my-domain> --type A
    NAME                               TYPE     TTL     DATA
    ingress.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 NS
    NAME                        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
  5. 将在上一步中检索到的 DNS 记录作为已注册域的专用域名服务器。这一操作将您的已注册域设置为在“准备工作”第 4 步中创建的 DNS 区域的父区域。
  6. 验证您能否访问 VirtualServer 主机名,因为它已暴露在公网中。

    $ curl -i --insecure https://ingress.external-dns.<my-domain>/tea
    HTTP/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 集群 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 流水线中使用基础架构即代码工具,使用 ExternalDNS 和 NGINX Ingress Controller 生成新集群并暴露给外部流量。此外,您还可管理多个 DNS 区域,甚至多个 DNS 供应商,具体取决于启用发现的方式。

 

结语

在生产效率与减少漏洞的安全措施之间取得平衡可能并非易事。对 DevOps 团队施加限制通常会导致其与 NetOps/SecOps 团队之间产生摩擦。每个企业的最佳平衡状态各不相同,NGINX 可帮助企业根据工作重点和要求灵活地建立平衡。

过去,应用所有者依靠 NetOps 团队将其应用连接到外部系统。借助 ExternalDNS 与 NGINX 的集成,开发人员和 DevOps 团队能够自行部署可发现的应用,从而帮助加快创新。

关于“在 Kubernetes 中开始使用 NGINX”的完整版全面指南,请下载我们的免费电子书《通过 F5 NGINX 管理 Kubernetes 流量:实用指南》

您可以立即申请 NGINX Ingress Controller 的 30 天免费试用版(带有 NGINX App Protect WAF 和 DoS),或者联系我们讨论您的用例

Hero image
Kubernetes:
从测试到生产

通过多种流量管理工具提升弹性、可视性和安全性

关于作者

Amir Rawdat

解决方案工程师

Amir Rawdat 是 NGINX 的技术营销工程师,专门负责各种技术内容的撰写。他在计算机网络、计算机编程、故障排除和内容撰写方面拥有深厚的背景。此前,Amir 是诺基亚(Nokia)的客户应用工程师。

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。