feat(apisix): add Cloudron package

- Implements Apache APISIX packaging for Cloudron platform.
- Includes Dockerfile, CloudronManifest.json, and start.sh.
- Configured to use Cloudron's etcd addon.

🤖 Generated with Gemini CLI
Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
2025-09-04 09:42:47 -05:00
parent f7bae09f22
commit 54cc5f7308
1608 changed files with 388342 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
---
title: 控制面服务发现
keywords:
- API 网关
- APISIX
- ZooKeeper
- Nacos
- APISIX-Seed
description: 本文档介绍了如何在 API 网关 Apache APISIX 控制面通过 Nacos 和 Zookeeper 实现服务发现。
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
本文档介绍了如何在 APISIX 控制面通过 Nacos 和 Zookeeper 实现服务发现。
## APISIX-Seed 架构
Apache APISIX 在早期已经支持了数据面服务发现,现在 APISIX 也通过 [APISIX-Seed](https://github.com/api7/apisix-seed) 项目实现了控制面服务发现,下图为 APISIX-Seed 架构图。
![control-plane-service-discovery](../../../assets/images/control-plane-service-discovery.png)
图中的数字代表的具体信息如下:
1. 通过 Admin API 向 APISIX 注册上游并指定服务发现类型。APISIX-Seed 将监听 etcd 中的 APISIX 资源变化,过滤服务发现类型并获取服务名称(如 ZooKeeper
2. APISIX-Seed 将在服务注册中心(如 ZooKeeper订阅指定的服务名称以监控和更新对应的服务信息
3. 客户端向服务注册中心注册服务后APISIX-Seed 会获取新的服务信息,并将更新后的服务节点写入 etcd
4. 当 APISIX-Seed 在 etcd 中更新相应的服务节点信息时APISIX 会将最新的服务节点信息同步到内存中。
:::note
引入 APISIX-Seed 后如果注册中心的服务变化频繁etcd 中的数据也会频繁变化。因此,需要在启动 etcd 时设置 `--auto-compaction` 选项,用来定期压缩历史记录,避免耗尽 etcd 存储空间。详细信息请参考 [revisions](https://etcd.io/docs/v3.5/learning/api/#revisions)
:::
## 为什么需要 APISIX-Seed
- 网络拓扑变得更简单
APISIX 不需要与每个注册中心保持网络连接,只需要关注 etcd 中的配置信息即可。这将大大简化网络拓扑。
- 上游服务总数据量变小
由于 `registry` 的特性APISIX 可能会在 Worker 中存储全量的 `registry` 服务数据,例如 Consul_KV。通过引入 APISIX-SeedAPISIX 的每个进程将不需要额外缓存上游服务相关信息。
- 更容易管理
服务发现配置需要为每个 APISIX 实例配置一次。通过引入 APISIX-SeedAPISIX 将对服务注册中心的配置变化无感知。
## 支持的服务发现类型
目前已经支持了 ZooKeeper 和 Nacos后续还将支持更多的服务注册中心更多信息请参考[APISIX Seed](https://github.com/api7/apisix-seed#apisix-seed-for-apache-apisix)
- 如果你想启用控制面 ZooKeeper 服务发现,请参考:[ZooKeeper 部署教程](https://github.com/api7/apisix-seed/blob/main/docs/zh/latest/zookeeper.md)
- 如果你想启用控制面 Nacos 服务发现,请参考:[Nacos 部署教程](https://github.com/api7/apisix-seed/blob/main/docs/zh/latest/nacos.md)

View File

@@ -0,0 +1,146 @@
---
title: DNS
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
## 基于 DNS 的服务发现
某些服务发现系统如 Consul支持通过 DNS 提供系统信息。我们可以使用这种方法直接实现服务发现,七层与四层均支持。
首先我们需要配置 DNS 服务器的地址:
```yaml
# 添加到 config.yaml
discovery:
dns:
servers:
- "127.0.0.1:8600" # 使用 DNS 服务器的真实地址
```
与在 Upstream 的 `nodes` 对象中配置域名不同的是DNS 服务发现将返回所有的记录。例如按照以下的 upstream 配置:
```json
{
"id": 1,
"discovery_type": "dns",
"service_name": "test.consul.service",
"type": "roundrobin"
}
```
之后 `test.consul.service` 将被解析为 `1.1.1.1``1.1.1.2`,这个结果等同于:
```json
{
"id": 1,
"type": "roundrobin",
"nodes": [
{"host": "1.1.1.1", "weight": 1},
{"host": "1.1.1.2", "weight": 1}
]
}
```
注意所有来自 `test.consul.service` 的 IP 都有相同的权重。
解析的记录将根据它们的 TTL 来进行缓存。对于记录不在缓存中的服务,我们将默认按照 `SRV -> A -> AAAA -> CNAME` 的顺序进行查询,刷新缓存记录时,我们将从上次成功的类型开始尝试。也可以通过修改配置文件来自定义 DNS 的解析顺序。
```yaml
# 添加到 config.yaml
discovery:
dns:
servers:
- "127.0.0.1:8600" # 使用 DNS 服务器的真实地址
order: # DNS 解析的顺序
- last # "last" 表示从上次成功的类型开始
- SRV
- A
- AAAA
- CNAME
```
如果你想指定 upstream 服务器的端口,可以把以下内容添加到 `service_name`
```json
{
"id": 1,
"discovery_type": "dns",
"service_name": "test.consul.service:1980",
"type": "roundrobin"
}
```
另一种方法是通过 SRV 记录,见如下。
### SRV 记录
通过使用 SRV 记录你可以指定一个服务的端口和权重。
假设你有一条这样的 SRV 记录:
```
; under the section of blah.service
A 300 IN A 1.1.1.1
B 300 IN A 1.1.1.2
B 300 IN A 1.1.1.3
; name TTL type priority weight port
srv 86400 IN SRV 10 60 1980 A
srv 86400 IN SRV 20 20 1981 B
```
Upstream 配置是这样的:
```json
{
"id": 1,
"discovery_type": "dns",
"service_name": "srv.blah.service",
"type": "roundrobin"
}
```
效果等同于:
```json
{
"id": 1,
"type": "roundrobin",
"nodes": [
{"host": "1.1.1.1", "port": 1980, "weight": 60, "priority": -10},
{"host": "1.1.1.2", "port": 1981, "weight": 10, "priority": -20},
{"host": "1.1.1.3", "port": 1981, "weight": 10, "priority": -20}
]
}
```
注意 B 域名的两条记录均分权重。
对于 SRV 记录,低优先级的节点被先选中,所以最后一项的优先级是负数。
关于 0 权重的 SRV 记录,在 [RFC 2782](https://www.ietf.org/rfc/rfc2782.txt) 中是这么描述的:
> 当没有任何候选服务器时,域管理员应使用权重为 0 的,使 RR 更为易读(噪音更少)。当存在权重大于 0 的记录时,权重为 0 的记录被选中的可能性很小。
我们把权重为 0 的记录当作权重为 1因此节点“被选中的可能性很小”这也是处理此类记录的常用方法。
对于端口为 0 的 SRV 记录,我们会使用上游协议的默认端口。
你也可以在“service_name”字段中直接指定端口比如“srv.blah.service:8848”。

View File

@@ -0,0 +1,25 @@
---
title: eureka
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
Apache APISIX 支持使用 [Eureka](https://github.com/Netflix/eureka#eureka) 做服务发现。
详情请阅读 [支持的服务注册发现](../discovery.md#当前支持的注册中心)

View File

@@ -0,0 +1,403 @@
---
title: Kubernetes
keywords:
- Kubernetes
- Apache APISIX
- 服务发现
- 集群
- API 网关
description: 本文将介绍如何在 Apache APISIX 中基于 Kubernetes 进行服务发现以及相关问题汇总。
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
## 基于 Kubernetes 的服务发现
Kubernetes 服务发现以 [_List-Watch_](https://kubernetes.io/docs/reference/using-api/api-concepts) 方式监听 [_Kubernetes_](https://kubernetes.io) 集群 [_Endpoints_](https://kubernetes.io/docs/concepts/services-networking/service) 资源的实时变化,并将其值存储到 ngx.shared.DICT 中。
同时遵循 [_APISIX Discovery 规范_](../discovery.md) 提供了节点查询接口。
## Kubernetes 服务发现的使用
目前 Kubernetes 服务发现支持单集群和多集群模式,分别适用于待发现的服务分布在单个或多个 Kubernetes 的场景。
### 单集群模式 Kubernetes 服务发现的配置格式
单集群模式 Kubernetes 服务发现的完整配置如下:
```yaml
discovery:
kubernetes:
service:
# apiserver schema, options [http, https]
schema: https #default https
# apiserver host, options [ipv4, ipv6, domain, environment variable]
host: ${KUBERNETES_SERVICE_HOST} #default ${KUBERNETES_SERVICE_HOST}
# apiserver port, options [port number, environment variable]
port: ${KUBERNETES_SERVICE_PORT} #default ${KUBERNETES_SERVICE_PORT}
client:
# serviceaccount token or token_file
token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
#token: |-
# eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEif
# 6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEifeyJhbGciOiJSUzI1NiIsImtpZCI
default_weight: 50 # weight assigned to each discovered endpoint. default 50, minimum 0
# kubernetes discovery support namespace_selector
# you can use one of [equal, not_equal, match, not_match] filter namespace
namespace_selector:
# only save endpoints with namespace equal default
equal: default
# only save endpoints with namespace not equal default
#not_equal: default
# only save endpoints with namespace match one of [default, ^my-[a-z]+$]
#match:
#- default
#- ^my-[a-z]+$
# only save endpoints with namespace not match one of [default, ^my-[a-z]+$]
#not_match:
#- default
#- ^my-[a-z]+$
# kubernetes discovery support label_selector
# for the expression of label_selector, please refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
label_selector: |-
first="a",second="b"
# reserved lua shared memory size, 1m memory can store about 1000 pieces of endpoint
shared_size: 1m #default 1m
# if watch_endpoint_slices setting true, watch apiserver with endpointslices instead of endpoints
watch_endpoint_slices: false #default false
```
如果 Kubernetes 服务发现运行在 Pod 内,你可以使用如下最简配置:
```yaml
discovery:
kubernetes: { }
```
如果 Kubernetes 服务发现运行在 Pod 外,你需要新建或选取指定的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/), 获取其 Token 值,然后使用如下配置:
```yaml
discovery:
kubernetes:
service:
schema: https
host: # enter apiserver host value here
port: # enter apiServer port value here
client:
token: # enter serviceaccount token value here
#token_file: # enter token file path here
```
### 单集群模式 Kubernetes 服务发现的查询接口
单集群模式 Kubernetes 服务发现遵循 [_APISIX Discovery 规范_](../discovery.md) 提供节点查询接口。
**函数:**
nodes(service_name)
**说明:**
service_name 必须满足格式:[namespace]/[name]:[portName]
+ namespace: Endpoints 所在的命名空间
+ name: Endpoints 的资源名
+ portName: Endpoints 定义包含的 `ports.name` 值,如果 Endpoints 没有定义 `ports.name`,请依次使用 `targetPort`, `port` 代替。设置了 `ports.name` 的情况下,不能使用后两者。
**返回值:**
以如下 Endpoints 为例:
```yaml
apiVersion: v1
kind: Endpoints
metadata:
name: plat-dev
namespace: default
subsets:
- addresses:
- ip: "10.5.10.109"
- ip: "10.5.10.110"
ports:
- port: 3306
name: port
```
nodes("default/plat-dev:port") 调用会得到如下的返回值:
```
{
{
host="10.5.10.109",
port= 3306,
weight= 50,
},
{
host="10.5.10.110",
port= 3306,
weight= 50,
},
}
```
### 多集群模式 Kubernetes 服务发现的配置格式
多集群模式 Kubernetes 服务发现的完整配置如下:
```yaml
discovery:
kubernetes:
- id: release # a custom name refer to the cluster, pattern ^[a-z0-9]{1,8}
service:
# apiserver schema, options [http, https]
schema: https #default https
# apiserver host, options [ipv4, ipv6, domain, environment variable]
host: "1.cluster.com"
# apiserver port, options [port number, environment variable]
port: "6443"
client:
# serviceaccount token or token_file
token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
#token: |-
# eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEif
# 6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEifeyJhbGciOiJSUzI1NiIsImtpZCI
default_weight: 50 # weight assigned to each discovered endpoint. default 50, minimum 0
# kubernetes discovery support namespace_selector
# you can use one of [equal, not_equal, match, not_match] filter namespace
namespace_selector:
# only save endpoints with namespace equal default
equal: default
# only save endpoints with namespace not equal default
#not_equal: default
# only save endpoints with namespace match one of [default, ^my-[a-z]+$]
#match:
#- default
#- ^my-[a-z]+$
# only save endpoints with namespace not match one of [default, ^my-[a-z]+$]
#not_match:
#- default
#- ^my-[a-z]+$
# kubernetes discovery support label_selector
# for the expression of label_selector, please refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
label_selector: |-
first="a",second="b"
# reserved lua shared memory size,1m memory can store about 1000 pieces of endpoint
shared_size: 1m #default 1m
# if watch_endpoint_slices setting true, watch apiserver with endpointslices instead of endpoints
watch_endpoint_slices: false #default false
```
多集群模式 Kubernetes 服务发现没有为 `service` 和 `client` 域填充默认值,你需要根据集群配置情况自行填充。
### 多集群模式 Kubernetes 服务发现的查询接口
多集群模式 Kubernetes 服务发现遵循 [_APISIX Discovery 规范_](../discovery.md) 提供节点查询接口。
**函数:**
nodes(service_name)
**说明:**
service_name 必须满足格式:[id]/[namespace]/[name]:[portName]
+ id: Kubernetes 服务发现配置中定义的集群 id 值
+ namespace: Endpoints 所在的命名空间
+ name: Endpoints 的资源名
+ portName: Endpoints 定义包含的 `ports.name` 值,如果 Endpoints 没有定义 `ports.name`,请依次使用 `targetPort`, `port` 代替。设置了 `ports.name` 的情况下,不能使用后两者。
**返回值:**
以如下 Endpoints 为例:
```yaml
apiVersion: v1
kind: Endpoints
metadata:
name: plat-dev
namespace: default
subsets:
- addresses:
- ip: "10.5.10.109"
- ip: "10.5.10.110"
ports:
- port: 3306
name: port
```
nodes("release/default/plat-dev:port") 调用会得到如下的返回值:
```
{
{
host="10.5.10.109",
port= 3306,
weight= 50,
},
{
host="10.5.10.110",
port= 3306,
weight= 50,
},
}
```
## Q&A
**Q: 为什么只支持配置 token 来访问 Kubernetes APIServer?**
A: 一般情况下,我们有三种方式可以完成与 Kubernetes APIServer 的认证:
- mTLS
- Token
- Basic authentication
因为 lua-resty-http 目前不支持 mTLS, Basic authentication 不被推荐使用,所以当前只实现了 Token 认证方式。
**Q: APISIX 继承了 NGINX 的多进程模型,是否意味着每个 APISIX 工作进程都会监听 Kubernetes Endpoints**
A: Kubernetes 服务发现只使用特权进程监听 Kubernetes Endpoints然后将其值存储到 `ngx.shared.DICT` 中,工作进程通过查询 `ngx.shared.DICT` 来获取结果。
**Q: [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 需要的权限有哪些?**
A: [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 需要集群级 [ get,list,watch ] endpoints 资源的的权限,其声明式定义如下:
```yaml
kind: ServiceAccount
apiVersion: v1
metadata:
name: apisix-test
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: apisix-test
rules:
- apiGroups: [ "" ]
resources: [ endpoints,endpointslices ]
verbs: [ get,list,watch ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: apisix-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: apisix-test
subjects:
- kind: ServiceAccount
name: apisix-test
namespace: default
```
**Q: 怎样获取指定 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 的 Token 值?**
A: 假定你指定的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 资源名为“kubernetes-discovery“, 命名空间为“apisix”, 请按如下步骤获取其 Token 值。
1. 获取 _Secret_ 资源名。执行以下命令,输出的第一列内容就是目标 _Secret_ 资源名:
```shell
kubectl -n apisix get secrets | grep kubernetes-discovery
```
2. 获取 Token 值。假定你获取到的 _Secret_ 资源名为 "kubernetes-discovery-token-c64cv", 执行以下命令,输出内容就是目标 Token 值:
```shell
kubectl -n apisix get secret kubernetes-discovery-token-c64cv -o jsonpath={.data.token} | base64 -d
```
## 调试 API
它还提供了用于调试的控制 api。
### 内存 Dump API
```shell
GET /v1/discovery/kubernetes/dump
```
例子
```shell
# curl http://127.0.0.1:9090/v1/discovery/kubernetes/dump | jq
{
"endpoints": [
{
"endpoints": [
{
"value": "{\"https\":[{\"host\":\"172.18.164.170\",\"port\":6443,\"weight\":50},{\"host\":\"172.18.164.171\",\"port\":6443,\"weight\":50},{\"host\":\"172.18.164.172\",\"port\":6443,\"weight\":50}]}",
"name": "default/kubernetes"
},
{
"value": "{\"metrics\":[{\"host\":\"172.18.164.170\",\"port\":2379,\"weight\":50},{\"host\":\"172.18.164.171\",\"port\":2379,\"weight\":50},{\"host\":\"172.18.164.172\",\"port\":2379,\"weight\":50}]}",
"name": "kube-system/etcd"
},
{
"value": "{\"http-85\":[{\"host\":\"172.64.89.2\",\"port\":85,\"weight\":50}]}",
"name": "test-ws/testing"
}
],
"id": "first"
}
],
"config": [
{
"default_weight": 50,
"id": "first",
"client": {
"token": "xxx"
},
"service": {
"host": "172.18.164.170",
"port": "6443",
"schema": "https"
},
"shared_size": "1m"
}
]
}
```

View File

@@ -0,0 +1,283 @@
---
title: nacos
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
## 基于 [Nacos](https://nacos.io/zh-cn/docs/what-is-nacos.html) 的服务发现
当前模块的性能有待改进:
1. 并行发送请求。
### Nacos 配置
在文件 `conf/config.yaml` 中添加以下配置到:
```yaml
discovery:
nacos:
host:
- "http://${username}:${password}@${host1}:${port1}"
prefix: "/nacos/v1/"
fetch_interval: 30 # default 30 sec
weight: 100 # default 100
timeout:
connect: 2000 # default 2000 ms
send: 2000 # default 2000 ms
read: 5000 # default 5000 ms
```
也可以这样简洁配置(未配置项使用默认值):
```yaml
discovery:
nacos:
host:
- "http://192.168.33.1:8848"
```
### Upstream 设置
#### 七层
例如,转发 URI 匹配 "/nacos/*" 的请求到一个上游服务,
该服务在 Nacos 中的服务名是 APISIX-NACOS查询地址是 http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS创建路由时指定服务发现类型为 nacos。
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
```shell
$ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uri": "/nacos/*",
"upstream": {
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos"
}
}'
```
响应如下:
```json
{
"node": {
"key": "\/apisix\/routes\/1",
"value": {
"id": "1",
"create_time": 1615796097,
"status": 1,
"update_time": 1615799165,
"upstream": {
"hash_on": "vars",
"pass_host": "pass",
"scheme": "http",
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos"
},
"priority": 0,
"uri": "\/nacos\/*"
}
}
}
```
#### 四层
nacos 服务发现也支持在四层中使用,配置方式与七层的类似。
```shell
$ curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 -H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"remote_addr": "127.0.0.1",
"upstream": {
"scheme": "tcp",
"discovery_type": "nacos",
"service_name": "APISIX-NACOS",
"type": "roundrobin"
}
}'
```
### 参数
| 名字 | 类型 | 可选项 | 默认值 | 有效值 | 说明 |
| ------------ | ------ | ----------- | ------- | ----- | ------------------------------------------------------------ |
| namespace_id | string | 可选 | public | | 服务所在的命名空间 |
| group_name | string | 可选 | DEFAULT_GROUP | | 服务所在的组 |
#### 指定命名空间
例如,转发 URI 匹配 "/nacosWithNamespaceId/*" 的请求到一个上游服务,
该服务在 Nacos 中的服务名是 APISIX-NACOS命名空间是 test_ns查询地址是 http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&namespaceId=test_ns创建路由时指定服务发现类型为 nacos。
```shell
$ curl http://127.0.0.1:9180/apisix/admin/routes/2 -H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uri": "/nacosWithNamespaceId/*",
"upstream": {
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"namespace_id": "test_ns"
}
}
}'
```
响应如下:
```json
{
"node": {
"key": "\/apisix\/routes\/2",
"value": {
"id": "2",
"create_time": 1615796097,
"status": 1,
"update_time": 1615799165,
"upstream": {
"hash_on": "vars",
"pass_host": "pass",
"scheme": "http",
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"namespace_id": "test_ns"
}
},
"priority": 0,
"uri": "\/nacosWithNamespaceId\/*"
}
}
}
```
#### 指定组
例如,转发 URI 匹配 "/nacosWithGroupName/*" 的请求到一个上游服务,
该服务在 Nacos 中的服务名是 APISIX-NACOS组名是 test_group查询地址是 http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&groupName=test_group创建路由时指定服务发现类型为 nacos。
```shell
$ curl http://127.0.0.1:9180/apisix/admin/routes/3 -H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uri": "/nacosWithGroupName/*",
"upstream": {
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"group_name": "test_group"
}
}
}'
```
响应如下:
```json
{
"node": {
"key": "\/apisix\/routes\/3",
"value": {
"id": "3",
"create_time": 1615796097,
"status": 1,
"update_time": 1615799165,
"upstream": {
"hash_on": "vars",
"pass_host": "pass",
"scheme": "http",
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"group_name": "test_group"
}
},
"priority": 0,
"uri": "\/nacosWithGroupName\/*"
}
}
}
```
#### 同时指定命名空间和组
例如,转发 URI 匹配 "/nacosWithNamespaceIdAndGroupName/*" 的请求到一个上游服务,
该服务在 Nacos 中的服务名是 APISIX-NACOS命名空间是 test_ns组名是 test_group查询地址是 http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&namespaceId=test_ns&groupName=test_group创建路由时指定服务发现类型为 nacos。
```shell
$ curl http://127.0.0.1:9180/apisix/admin/routes/4 -H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uri": "/nacosWithNamespaceIdAndGroupName/*",
"upstream": {
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"namespace_id": "test_ns",
"group_name": "test_group"
}
}
}'
```
响应如下:
```json
{
"node": {
"key": "\/apisix\/routes\/4",
"value": {
"id": "4",
"create_time": 1615796097,
"status": 1,
"update_time": 1615799165,
"upstream": {
"hash_on": "vars",
"pass_host": "pass",
"scheme": "http",
"service_name": "APISIX-NACOS",
"type": "roundrobin",
"discovery_type": "nacos",
"discovery_args": {
"namespace_id": "test_ns",
"group_name": "test_group"
}
},
"priority": 0,
"uri": "\/nacosWithNamespaceIdAndGroupName\/*"
}
}
}
```