使用NGINX Ingress Controller实现多集群DNS自动化

NGINX | 2022年10月25日

如果用户找不到应用,应用就无法发挥作用。域名系统(DNS)是一项互联网技术,通过将域名转换为IP地址来“查找”应用和网站。DNS应用广泛且十分可靠,因此大多数时候您甚至不会留意它。但一旦DNS出现问题,一切都会停摆。确保DNS正常运行对现代应用至关重要,尤其是在服务不断启动和停止的微服务架构中。

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

但许多组织需要扩展这一用例,将应用部署到多个Kubernetes集群中,而这些集群可能分布在云服务提供商的不同区域。要让外部流量到达新的集群区域,需要创建解析到这些区域的DNS区域。

过去,此过程需要使用第三方提供商(如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控制器,将Kubernetes应用对外公开。只有当配置的域名解析到Kubernetes集群的公共入口点后,客户端才能连接到这些应用。

NGINX Ingress Controller通过作为中介的ExternalDNS Kubernetes部署与DNS提供商交互,从而能够使用外部DNS记录自动发现Kubernetes应用。在图中,黑线表示外部用户访问Kubernetes集群中应用的数据路径。紫线表示控制路径,应用所有者通过该路径使用NGINX Ingress Controller配置中的VirtualServer资源管理外部DNS记录,ExternalDNS也通过该路径访问DNS提供商。

ExternalDNS Kubernetes部署如何在NGINX Ingress Controller与DNS提供商之间进行交互的示意图

集成ExternalDNS与NGINX Ingress Controller

按照以下各节中的步骤集成ExternalDNS和NGINX Ingress Controller。

先决条件

  1. 创建至少一个已注册的域名。在以下步骤中,使用该域名替换<my‑domain>。(有许多文章介绍如何注册域名,其中包括这篇PCMag指南。)
  2. 使用清单或Helm charts部署NGINX Ingress Controller。在部署规范中添加与以下命令行参数等效的参数:
    • -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‑IP或MetalLB。
  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
  1. 更新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(对于该示例部署是唯一的)。
  2. 在集群中部署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资源,并设置一条Ingress负载均衡规则,将外部连接路由到Kubernetes应用。

  1. 在app-virtual-server.yaml中,设置host字段(第 6 行):
 6    host: ingress.external-dns.<my-domain>
  1. 此值与domain-filter在external-dns-gcloud.yaml第59行中的值(已在上一节的第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
  1. 验证是否已向DNS区域添加一条类型为A的记录。特别是,DATA字段中的IP地址必须与上一步中kubectl get vs命令输出的IP字段一致(即公开NGINX Ingress Controller的LoadBalancer类型服务的外部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
  1. 要验证是否可以在本地计算机上解析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
  1. 将上一步检索到的DNS记录用作已注册域名的专用名称服务器。这样会将已注册域名设置为前提条件的第4步中所创建DNS区域的父区域。
  2. 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集群1和Kubernetes集群2),可以快速扩展架构并自动发现多个集群。请重复执行部署NGINX Ingress Controller和ExternalDNS以及配置NGINX Ingress Controller中的说明。

自动创建外部DNS记录并将其解析到新集群入口点的示意图

还可以在CI/CD流水线中使用基础设施即代码工具,通过ExternalDNS和NGINX Ingress Controller创建新集群,并使其能够接收外部流量。此外,还可以根据服务发现的启用方式管理多个DNS区域,甚至多个DNS提供商。

总结

在生产力与降低安全事件风险的安全措施之间取得平衡并非易事。对DevOps团队施加限制,往往会导致其与NetOps/SecOps团队之间产生摩擦。每个组织的理想平衡点各不相同,NGINX可提供灵活性,帮助组织根据自身优先事项和要求实现平衡。

过去,应用所有者依赖NetOps团队将应用连接到外部系统。通过使用ExternalDNS与NGINX的集成,开发人员和DevOps团队可以自行部署可被发现的应用,从而帮助缩短创新成果的上市时间。

如需全面了解如何在Kubernetes中开始使用NGINX,请下载免费电子书《使用F5 NGINX管理Kubernetes流量:实用指南》。

还可以立即申请30天免费试用,体验搭载NGINX App Protect WAF和DoS的NGINX Ingress Controller,或联系我们,讨论您的用例。


分享

关于作者

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。