上游发现
upstream.discovery 插件通过服务注册中心、容器编排系统或云 API,把一个服务解析为当前支撑它的服务器。用户把 nginx upstream 绑定到一个服务后,Nginx UI 按绑定的刷新间隔调用插件,把结果写成 upstream 块保存到自己的文件中,并在服务器变化时重载 nginx。
| 方法 | 必需 | 用途 |
|---|---|---|
discovery.resolve | 是 | 把一个服务解析为它当前的服务器。 |
插件必须请求 network 权限。
声明提供方
"capabilities": ["upstream.discovery"],
"permissions": ["network"],
"discovery": {
"providers": [
{
"code": "registry",
"name": "Service registry",
"configuration": {
"fields": [
{ "key": "address", "display_name": "Registry address", "required": true },
{ "key": "token", "display_name": "ACL token", "secret": true },
{ "key": "healthy_only", "type": "bool", "display_name": "Only healthy instances" }
]
}
}
]
}code、name 和 configuration.fields 的用法与通知渠道相同。
解析
{
"jsonrpc": "2.0", "id": 50, "method": "discovery.resolve",
"params": { "provider": "registry", "config": { "address": "https://registry.example.com:8500", "token": "tok_live_xxx" }, "service": "api" }
}service 使用提供方自己的术语:服务名、标签选择器或标记。回复当前支撑它的每一台服务器:
{
"jsonrpc": "2.0", "id": 50,
"result": {
"targets": [
{ "address": "10.0.1.12", "port": 8080, "weight": 1, "tags": ["zone-a"] },
{ "address": "10.0.2.7", "port": 8080, "weight": 2, "tags": ["zone-b", "canary"] },
{ "address": "2001:db8::17", "port": 8443 }
],
"ttl_seconds": 30
}
}| 字段 | 含义 |
|---|---|
targets[].address | 不带方括号的 IPv4 或 IPv6 地址,或主机名。不含端口或协议。 |
targets[].port | TCP 端口,1 到 65535。 |
targets[].weight | 相对权重,1 到 1000。0 或不填表示 1。 |
targets[].tags | 仅供显示的标签。 |
ttl_seconds | 结果的有效期。0 表示由间隔决定。 |
空列表表示该服务当前没有服务器。无法解析服务时,回复错误,使 Nginx UI 保留现有的服务器:原因在于配置(包括凭据被拒绝,以及提供方不认识的 service,此时指出 service)时回复带 data.field 的 -32003,其他情况回复 -32000。请把 config 的每个值都当作机密。
Nginx UI 如何处理结果
它只保留地址能解析为 IP 地址或有效主机名、端口和权重都在范围内的目标,丢弃其余目标并报告数量。其他文本(包括
tags)都不会进入配置。没有有效目标时,它保留当前文件并记录失败,因为没有服务器的 upstream 是无效的。它把每个绑定写入
<nginx 配置目录>/upstreams/<名称>.conf,upstream 名称由用户选择:nginx# generated by nginx-ui upstream api { server 10.0.1.12:8080 weight=1; server 10.0.2.7:8080 weight=2; server [2001:db8::17]:8443 weight=1; keepalive 32; }最后几行是用户为该绑定输入的额外指令。
只有文件变化时才重载 nginx,重载前先测试配置,测试失败时恢复之前的文件。
它向用户显示需要在
http层添加的那一行:include upstreams/<名称>.conf;。
绑定默认每 60 秒刷新一次,最短间隔为 10 秒;上次结果的 ttl_seconds 更短时会提前刷新。discovery.resolve 最多等待 30 秒,最近一次解析的结果显示在绑定旁边。