在 1990 年的电影《猎杀红色十月号》中,由 Sean Connery 饰演的苏联新型核潜艇舰长 Marko Ramius 打算指挥潜艇叛逃到美国。由年轻的 Alec Baldwin 饰演的中央情报局 (CIA) 分析师 Jack Ryan 凭直觉判断出了 Ramius 的动机,他必须说服美国海军相信他的推断,以防止超级大国之间爆发暴力冲突。为了证明自己的判断,Ryan 首先需要与 Ramius 对话。随着他花费过多的时间寻找 Ramius,悬念也在不断累积。
从表面上看,Ryan 的搜索如同浏览器客户端尝试在互联网上查找一个网站,只不过这些网站在域名系统 (DNS) 中注册了其位置,因此客户端可以不费吹灰之力就找到它们。如果 Ramius 公布了他的位置,这部电影就不会那么惊心动魄了,但在我们的应用上,我们还是希望能够快速、轻松地解决问题。
在本文中,我们使用了 F5 的两项 DNS 技术。借助 BIG-IP DNS,我们通过将私有地址(最初在 RFC 1918 中定义)的 DNS 记录发布到内部客户端,为它们提供一条优化路径以访问数据中心托管的服务。然后通过 DNS 负载均衡器云服务,我们可以为外部客户端提供基于云的 DNS 服务。
本文的标题灵感源自这部电影中的另一情节。一旦找到 Ramius,Ryan 就会发送一条信息,而 Ramius 则会在收到消息后发出单个 ping 作为回应。在我们的设置中,只需通过 API 发送一条 HTTP POST 消息,便可更新 DNS 记录。我们使用 NGINX Plus 和 NGINX JavaScript 模块来实现这一点。
多个名称,一个 IP 地址
我们的示例解决了跨多个数据中心的平台即服务 (PaaS) 部署的常见问题。每个位置的 DNS 记录中公布的单个 IP 地址背后通常部署了许多服务。通配符 DNS 条目的问题是,您会丢失有关每项服务的位置及其是否健康的详细信息。
在我们的示例中,我们使用 NGINX Plus 主动健康检查来跟踪多个位置的应用程序运行的健康状况,而无需重复执行监控任务,并随着应用程序的启用和下线时更新内部和外部 DNS 记录。
我们如何使用 F5 和 NGINX 技术
我们的示例同时利用了 F5 和 NGINX 软件:
-
F5 BIG-IP DNS — BIG-IP 不仅支持传统的负载均衡,而且还能够实现全局服务器负载均衡 (GSLB)。它既可作为硬件或虚拟设备部署在本地,也可作为虚拟设备部署至云环境中。
-
F5 DNS 负载均衡器云服务 — DNS 负载均衡器以云托管 SaaS 服务的形式提供 GSLB,内置 DDoS 防护和 API 优先方法。
BIG-IP DNS 和 DNS 负载均衡器都有一个用于更新 DNS 记录的声明式 API。这样,只需通过单个 POST API 即可执行更新。
-
NGINX Plus — 我们即将用到多项 NGINX Plus 功能:
-
主动健康检查,用于监控上游服务器(我们的应用)的状态。
-
NGINX Plus API,用于更新记录应用状态的键值存储。
-
NGINX Plus 区域同步,用于在多个 NGINX 实例之间同步键值存储(类似于 memcache 或 Redis 等分布式数据库)。
-
NGINX JavaScript 模块 — NGINX JavaScript (njs) 支持我们向内部 NGINX Plus API 发出子请求、解析 JSON 响应、更新内部 NGINX 变量,并将非原生函数纳入 NGINX Plus 流量处理序列中。
在详细介绍示例解决方案的工作原理之前,我们先来简要了解一下这些技术如何协同工作:
1. 我们使用 NGINX Plus 主动健康检查来获取在多个数据中心运行的后端应用的状态。
2. 接下来,我们使用 njs 函数汇总健康信息和更新键值存储。因为我们启用了 NGINX Plus 区域同步,所以键值存储会在所有 NGINX Plus 实例之间自动同步。
3. 我们向 NGINX Plus 发出经过身份验证的请求,该请求调用 njs 函数更新 DNS 记录。
有关如何配置 NGINX Plus 并处理应用程序运行状况的详细信息,请查看下文“收集、存储并更新应用程序运行状况信息”一节。有关如何将信息传递给 DNS 服务器的详细信息,请查看下文“更新 DNS 记录”一节。
(请注意,本文既不涉及 NGINX Plus 配置中的所有 location 指令,也不会对所有相关 njs 函数进行深入探讨。)
[编者按——本文是探讨 NGINX JavaScript 模块用例的系列文章之一。查看完整列表,请参阅《NGINX JavaScript 模块的用例》。]
收集、存储并更新应用程序运行状况信息
在我们的示例拓扑中,有两个数据中心,即 dc1 和 dc2 — 该解决方案可轻松推广到许多部署类型(混合云、多云、多个可用区、多个 Kubernetes 集群或单个位置或设备)。
keyval_zone zone=pools:32k state=pools.keyval sync timeout=300;
keyval "10.1.20.54" $pool zone=pools;
▼可左右滑动查看全部内容
r.subrequest('/api/5/http/upstreams' ...
▼可左右滑动查看全部内容
{"app001":3,"app002":3}
r.variables.pool = JSON.stringify(output);
▼可左右滑动查看全部内容
{
"10.1.20.54": "{"app001":3,"app002":3}",
"10.1.20.55": "{"app001":2,"app003":4}"
}
▼可左右滑动查看全部内容
location /poll {
proxy_pass http://127.0.0.1/pools/update;
health_check uri=/pools/update interval=30;
}
▼可左右滑动查看全部内容
$ curl localhost:8245/pools
{"app001.f5demo.com":{"dc1":[{"10.1.20.54":3}],
"dc2":[{"10.1.20.55":2}]},
"app002.f5demo.com":{"dc1":[{"10.1.20.54":3}]},
"app003.f5demo.com":{"dc2":[{"10.1.20.55":4}]},
"app004.f5demo.com":{"dc1":[{"10.1.20.54":0}],
"dc2":[{"10.1.20.55":3}]}}
▼可左右滑动查看全部内容
下面是当前应用健康状态的图示。
更新 DNS 记录
我们更新 BIG-IP DNS 和 DNS 负载均衡器中的记录,以反映我们后端应用的健康状况;如果某个应用在其中一个数据中心内不可用,(例如上面示例中 dc1 中的 app004),我们会将该应用的客户端转移到另一个数据中心。BIG-IP DNS 和 DNS 负载均衡器使用不同的模板和数据表示,因此要更新两个系统中的 DNS 记录,我们需要将 njs 子请求定向到不同的 URL,并调用不同的函数。
var template = {
"class": "ADC",
"schemaVersion": "3.7.0",
"id": "NGINXPLUS",
▼可左右滑动查看全部内容
"app001_domain": {
"class": "GSLB_Domain",
"domainName": "app001.f5demo.com",
"pools": [ { "use": "dc1_app001_pool" },
{ "use": "dc2_app001_pool"} ],
"resourceRecordType": "A"
},
▼可左右滑动查看全部内容
upstream bigip {
server 10.1.1.5:443;
location /mgmt/shared/appsvcs/declare {
proxy_pass https://bigip;
}
▼可左右滑动查看全部内容
r.subrequest('/mgmt/shared/appsvcs/declare',
{ method: 'POST', body: JSON.stringify(template) },
▼可左右滑动查看全部内容
curl localhost:8245/pools/push/dns -u admin:admin_password
▼可左右滑动查看全部内容
"load_balanced_records": {
"app001": {
...
"proximity_rules": [
{ ... "pool": "pools_dc1_app001" ...},
{ ... "pool": "pools_dc1_app001" ...},
],
...
▼可左右滑动查看全部内容
upstream cloud {
server api.cloudservices.f5.com:443;
#...
location /v1/svc-subscription/subscriptions {
proxy_pass https://cloud;
}
▼可左右滑动查看全部内容
r.subrequest(' /svc-subscription/subscriptions/s-aabbcc1234,
{ method: 'PUT', body: JSON.stringify(template) },
▼可左右滑动查看全部内容
"Authorization: ..." curl localhost:8245/pools/push/cloud_dns?account_id=... -H
▼可左右滑动查看全部内容
在 BIG-IP DNS GUI 中跟踪应用健康状况
虽然使用了 NGINX Plus 和 njs 子请求创建并更新 BIG-IP DNS 记录,但我们仍可使用 BIG-IP DNS GUI 来验证应用的健康状况。此截图显示,app004 在 dc1 中运行不正常,在 dc2 中运行正常(在 Status(状态)列中分别用黑色菱形和绿色圆圈表示)。因此,BIG-IP DNS 在响应 app004 的位置请求时仅包含 dc2 的地址。
此截图显示了如何在私有 (10/8) 地址空间中查找 BIG-IP DNS 记录。
在 DNS Load Balancer GUI 中跟踪应用健康状况
与 BIG-IP DNS 一样,尽管我们使用了 NGINX Plus 和 njs 子请求创建并更新 DNS 记录,但我们仍可使用 DNS 负载均衡器 GUI 来验证应用的健康状况。此截图显示,app004 在 dc1 中运行不正常,在 dc2 中运行正常(在 Status 列中分别用 Disabled(禁用)和 Enabled(启用)表示)。
下面的截图显示了如何使用 DNS 负载均衡器记录(与 BIG-IP DNS 记录不同)查找公共 IP 地址(我们只显示了前四条记录)。
结语
回顾一下,我们使用 NGINX Plus 进行了以下操作:
-
对上游应用执行主动健康检查
-
将健康信息存储至键值存储中
-
在多个 NGINX 实例之间同步键值存储
我们利用 njs 进行了以下操作:
-
以每项 DNS 技术所需的格式汇总上游应用的状态
-
对 DNS 服务进行模板化处理
-
将 DNS 服务推送到相应的 API 端点
其结果可能不像《猎杀红色十月号》的结局那样史诗般宏大,但对任何运营网站的人员来说都更有价值。
原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/35654.html