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:
@@ -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 架构图。
|
||||
|
||||

|
||||
|
||||
图中的数字代表的具体信息如下:
|
||||
|
||||
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-Seed,APISIX 的每个进程将不需要额外缓存上游服务相关信息。
|
||||
|
||||
- 更容易管理
|
||||
|
||||
服务发现配置需要为每个 APISIX 实例配置一次。通过引入 APISIX-Seed,APISIX 将对服务注册中心的配置变化无感知。
|
||||
|
||||
## 支持的服务发现类型
|
||||
|
||||
目前已经支持了 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)。
|
@@ -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”。
|
@@ -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#当前支持的注册中心) 。
|
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
@@ -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\/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user