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,42 @@
---
title: API Gateway
keywords:
- Apache APISIX
- API 网关
- 网关
description: 本文主要介绍了 API 网关的作用以及为什么需要 API 网关。
---
<!--
#
# 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.
#
-->
## 描述
API 网关是位于客户端与后端服务集之间的 API 管理工具。API 网关相当于反向代理,用于接受所有 API 的调用、整合处理这些调用所需的各种服务并返回相应的结果。API 网关通常会处理**跨 API 服务系统使用**的常见任务,并统一接入进行管理。通过 API 网关的统一拦截,可以实现对 API 接口的安全、日志等共性需求,如用户身份验证、速率限制和统计信息。
## 为什么需要 API 网关?
与传统的 API 微服务相比API 网关有很多好处。比如:
- 它是所有 API 请求的唯一入口。
- 可用于将请求转发到不同的后端,或根据请求头将请求转发到不同的服务。
- 可用于执行身份验证、授权和限速。
- 它可用于支持分析,例如监控、日志记录和跟踪。
- 可以保护 API 免受 SQL 注入、DDOS 攻击和 XSS 等恶意攻击媒介的攻击。
- 它可以降低 API 和微服务的复杂性。

View File

@@ -0,0 +1,124 @@
---
title: Consumer Groups
keywords:
- API 网关
- Apache APISIX
- Consumer Groups
description: 本文介绍了 Apache APISIX Consumer Group 对象的概念及使用方法。
---
<!--
#
# 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.
#
-->
## 描述
通过 Consumer Groups你可以在同一个消费者组中启用任意数量的[插件](./plugin.md),并在一个或者多个[消费者](./consumer.md)中引用该消费者组。
## 配置示例
以下示例展示了如何创建消费者组并将其绑定到消费者中。
创建一个共享相同限流配额的消费者组:
:::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/consumer_groups/company_a \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"limit-count": {
"count": 200,
"time_window": 60,
"rejected_code": 503,
"group": "grp_company_a"
}
}
}'
```
在消费者组中创建消费者:
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "auth-one"
}
},
"group_id": "company_a"
}'
```
当 APISIX 无法找到 `group_id` 中定义的消费者组时,创建或者更新消费者的请求将会终止,并返回错误码 `404`
如果消费者已经配置了 `plugins` 字段,那么消费者组中配置的插件将与之合并。
:::tip
此处需要注意两点:
1. 当在同一个插件分别配置在[消费者](./consumer.md)[路由](./route.md)[插件配置](./plugin-config.md)[服务](./service.md)中时,只有一份配置是生效的,并且消费者的优先级最高。更多信息,请参考 [Plugin](./plugin.md)
2. 如果消费者和消费者组配置了相同的插件,则消费者中的插件配置优先级更高。对于第一点,因为消费者组需要配置在消费者中,因此你只需关心消费者中插件的优先级。
:::
如下示例,假如你配置了一个消费者组:
```json title="Consumer Group"
{
"id": "bar",
"plugins": {
"response-rewrite": {
"body": "hello"
}
}
}
```
并配置了消费者:
```json title="Consumer"
{
"username": "foo",
"group_id": "bar",
"plugins": {
"basic-auth": {
"username": "foo",
"password": "bar"
},
"response-rewrite": {
"body": "world"
}
}
}
```
那么 `response-rewrite` 中的 `body` 将保留 `world`。

View File

@@ -0,0 +1,177 @@
---
title: Consumer
keywords:
- APISIX
- API 网关
- 消费者
- Consumer
description: 本文介绍了 Apache APISIX Consumer 对象的作用以及如何使用 Consumer。
---
<!--
#
# 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.
#
-->
## 描述
Consumer 是某类服务的消费者,需要与用户认证配合才可以使用。当不同的消费者请求同一个 API 时APISIX 会根据当前请求的用户信息,对应不同的 Plugin 或 Upstream 配置。如果 [Route](./route.md)[Service](./service.md)[Consumer](./consumer.md)[Plugin Config](./plugin-config.md) 都绑定了相同的插件只有消费者的插件配置会生效。插件配置的优先级由高到低的顺序是Consumer > Route > Plugin Config > Service。
对于 API 网关而言,一般情况可以通过请求域名、客户端 IP 地址等字段识别到某类请求方,然后进行插件过滤并转发请求到指定上游。但有时候该方式达不到用户需求,因此 APISIX 支持了 Consumer 对象。
![Consumer](../../../assets/images/consumer-who.png)
如上图所示,作为 API 网关,需要知道 API Consumer消费方具体是谁这样就可以对不同 API Consumer 配置不同规则。
## 配置选项
定义 Consumer 的字段如下:
| 名称 | 必选项 | 描述 |
| -------- | ---- | ------------------------------------------------------------------------------|
| username | 是 | Consumer 名称。 |
| plugins | 否 | Consumer 对应的插件配置。详细信息,请参考 [Plugins](./plugin.md)。 |
## 识别消费者
在 APISIX 中,识别 Consumer 的过程如下图:
![Consumer Internal](../../../assets/images/consumer-internal.png)
1. 授权认证:比如有 [key-auth](../plugins/key-auth.md)[JWT](../plugins/jwt-auth.md) 等;
2. 获取 consumer_name通过授权认证即可自然获取到对应的 Consumer name它是 Consumer 对象的唯一识别标识;
3. 获取 Consumer 上绑定的 Plugin 或 Upstream 信息:完成对不同 Consumer 做不同配置的效果。
当有不同的使用者请求相同的 API并且需要根据使用者执行不同的插件和上游配置时使用 Consumer 是非常合适的。需要与用户身份验证系统结合使用。
目前,可以与 Consumer 配置的身份验证插件包括 `basic-auth``hmac-auth``jwt-auth``key-auth``ldap-auth``wolf-rbac`
你可以参考 [key-auth](../plugins/key-auth.md) 认证授权插件的调用逻辑,进一步理解 Consumer 概念和使用。
:::note 注意
如需了解更多关于 Consumer 对象的信息,你可以参考 [Admin API Consumer](../admin-api.md#consumer) 资源介绍。
:::
## 使用示例
以下示例介绍了如何对某个 Consumer 开启指定插件:
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. 创建 Consumer指定认证插件 `key-auth`,并开启特定插件 `limit-count`
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "auth-one"
},
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
}
}'
```
2. 创建路由,设置路由规则和启用插件配置。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}'
```
3. 测试插件。
连续发送三次测试请求,前两次返回正常,没达到限速阈值。
```shell
curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
```
第三次测试返回 `503`,请求被限制:
```shell
HTTP/1.1 503 Service Temporarily Unavailable
...
```
通过 [consumer-restriction](../plugins/consumer-restriction.md) 插件,限制用户 `jack` 对该 Route 的访问。
1. 设置黑名单,禁止 jack 访问该 API。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {},
"consumer-restriction": {
"blacklist": [
"jack"
]
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}'
```
2. 通过以下命令访问该路由,均返回 `403``jack` 被禁止访问。
```shell
curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
```
返回结果:
```
HTTP/1.1 403
...
```

View File

@@ -0,0 +1,152 @@
---
title: Credential
keywords:
- APISIX
- API 网关
- 凭证
- Credential
description: 本文介绍了 Apache APISIX Credential 对象的作用以及如何使用 Credential。
---
<!--
#
# 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.
#
-->
## 描述
Credential 是存放 [Consumer](./consumer.md) 凭证配置的对象。
一个 Consumer 可以使用不同类型的多个凭证。
当你需要为一个 Consumer 配置不同类型的多个凭证时,就会用到 Credential。
目前Credential 可以配置的身份认证插件包括 `basic-auth``hmac-auth``jwt-auth` 以及 `key-auth`
## 配置选项
定义 Credential 的字段如下:
| 名称 | 必选项 | 描述 |
|---------|-----|-----------------------------------------------------|
| desc | 否 | Credential 描述。 |
| labels | 否 | Credential 标签。 |
| plugins | 否 | Credential 对应的插件配置。详细信息,请参考 [Plugins](./plugin.md)。 |
:::note
如需了解更多关于 Credential 对象的信息,你可以参考 [Admin API Credential](../admin-api.md#credential) 资源介绍。
:::
## 使用示例
[Consumer 使用示例](./consumer.md#使用示例) 介绍了如何对 Consumer 配置认证插件,并介绍了如何配合其他插件使用。
在该示例中,该 Consumer 只有一个 key-auth 类型的凭证。
现在假设用户需要为该 Consumer 配置多个凭证,你可以使用 Credential 来支持这一点。
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. 创建 Consumer。不指定认证插件而是稍后使用 Credential 来配置认证插件。
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack"
}'
```
2. 为 Consumer 配置 2 个 启用 `key-auth` 的 Credential。
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials/key-auth-one \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {
"key": "auth-one"
}
}
}'
```
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials/key-auth-two \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {
"key": "auth-two"
}
}
}'
```
3. 创建路由,设置路由规则和启用插件配置。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}'
```
4. 测试插件
分别使用 `auth-one` 和 `auth-two` 两个 key 来测试请求,都响应正常。
```shell
curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
curl http://127.0.0.1:9080/hello -H 'apikey: auth-two' -I
```
为该 Consumer 启用 `limit-count` 插件。
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
}
}'
```
分别使用这两个 key 连续 3 次以上请求该路由,测试返回 `503`,请求被限制。

View File

@@ -0,0 +1,73 @@
---
title: Global rules
keywords:
- API 网关
- Apache APISIX
- Global Rules
- 全局规则
description: 本文介绍了全局规则的概念以及如何启用全局规则。
---
<!--
#
# 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.
#
-->
## 描述
[Plugin](plugin.md) 配置可直接绑定在 [Route](route.md) 上,也可以被绑定在 [Service](service.md)[Consumer](consumer.md) 上。
如果你需要一个能作用于所有请求的 Plugin可以通过 Global Rules 启用一个全局的插件配置。
全局规则相对于 Route、Service、Plugin Config、Consumer 中的插件配置Global Rules 中的插件总是优先执行。
## 使用示例
以下示例展示了如何为所有请求启用 `limit-count` 插件:
:::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/global_rules/1 -X PUT \
-H 'Content-Type: application/json' \
-H "X-API-KEY: $admin_key" \
-d '{
"plugins": {
"limit-count": {
"time_window": 60,
"policy": "local",
"count": 2,
"key": "remote_addr",
"rejected_code": 503
}
}
}'
```
你也可以通过以下命令查看所有的全局规则:
```shell
curl http://127.0.0.1:9180/apisix/admin/global_rules -H "X-API-KEY: $admin_key"
```

View File

@@ -0,0 +1,178 @@
---
title: Plugin Config
keywords:
- API 网关
- Apache APISIX
- 插件配置
- Plugin Config
description: Plugin Config 对象,可以用于创建一组通用的插件配置,并在路由中使用这组配置。
---
<!--
#
# 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.
#
-->
## 描述
在很多情况下,我们在不同的路由中会使用相同的插件规则,此时就可以通过 Plugin Config 来设置这些规则。Plugin Config 属于一组通用插件配置的抽象。
`plugins` 的配置可以通过 [Admin API](../admin-api.md#plugin-config) `/apisix/admin/plugin_configs` 进行单独配置,在路由中使用 `plugin_config_id` 与之进行关联。
对于同一个插件的配置,只能有一个是有效的,优先级为 Consumer > Route > Plugin Config > Service。
## 使用示例
你可以参考如下步骤将 Plugin Config 绑定在路由上。
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. 创建 Plugin config。
```shell
curl http://127.0.0.1:9180/apisix/admin/plugin_configs/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"desc": "enable limit-count plugin",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503
}
}
}'
```
2. 创建路由并绑定 `Plugin Config 1`。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uris": ["/index.html"],
"plugin_config_id": 1,
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
如果找不到对应的 Plugin Config该路由上的请求会报 `503` 错误。
## 注意事项
如果路由中已经配置了 `plugins`,那么 Plugin Config 里面的插件配置将会与 `plugins` 合并。
相同的插件不会覆盖掉 `plugins` 原有的插件配置。详细信息,请参考 [Plugin](./plugin.md)。
1. 假设你创建了一个 Plugin Config。
```shell
curl http://127.0.0.1:9180/apisix/admin/plugin_configs/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"desc": "enable ip-restruction and limit-count plugin",
"plugins": {
"ip-restriction": {
"whitelist": [
"127.0.0.0/24",
"113.74.26.106"
]
},
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503
}
}
}'
```
2. 并在路由中引入 Plugin Config。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uris": ["/index.html"],
"plugin_config_id": 1,
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
"plugins": {
"proxy-rewrite": {
"uri": "/test/add",
"host": "apisix.iresty.com"
},
"limit-count": {
"count": 20,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
}
}'
```
3. 最后实现的效果如下。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uris": ["/index.html"],
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
"plugins": {
"ip-restriction": {
"whitelist": [
"127.0.0.0/24",
"113.74.26.106"
]
},
"proxy-rewrite": {
"uri": "/test/add",
"host": "apisix.iresty.com"
},
"limit-count": {
"count": 20,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
}
}'
```

View File

@@ -0,0 +1,85 @@
---
title: Plugin Metadata
keywords:
- API 网关
- Apache APISIX
- 插件元数据配置
- Plugin Metadata
description: APISIX 的插件元数据
---
<!--
#
# 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 中,插件元数据的基本概念和您可能使用到的场景。
浏览文档末尾的相关资源,获取与此相关的更多信息。
## 描述
在 APISIX 中,配置通用的元数据属性,可以作用于包含该元数据插件的所有路由及服务中。例如为`rocketmq-logger`指定了 `log_format`,则所有绑定 rocketmq-logger 的路由或服务都将使用该日志格式。
下图说明了插件元数据的概念,使用两个不同路由上的 [syslog](https://apisix.apache.org/zh/docs/apisix/plugins/syslog/) 插件的实例,以及为 [syslog](https://apisix.apache.org/zh/docs/apisix/plugins/syslog/) 插件设置全局`log_format`的插件元数据对象:
![plugin_metadata](https://static.apiseven.com/uploads/2023/04/17/Z0OFRQhV_plugin%20metadata.svg)
如果没有另外指定,插件元数据对象上的`log_format`应将相同的日志格式统一应用于两个`syslog`插件。但是,由于`/orders`路由上的`syslog`插件具有不同的`log_format`,因此访问该路由的请求将按照路由中插件指定的`log_format`生成日志。
在插件级别设置的元数据属性更加精细,并且比`全局`元数据对象具有更高的优先级。
插件元数据对象只能用于具有元数据属性的插件。有关哪些插件具有元数据属性的更多详细信息,请查看插件配置属性及相关信息。
## 配置示例
以下示例展示了如何通过 Admin API 配置插件元数据:
:::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/plugin_metadata/http-logger \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"log_format": {
"host": "$host",
"@timestamp": "$time_iso8601",
"client_ip": "$remote_addr"
}
}'
```
配置完成后,你将在日志系统中看到如下类似日志:
```json
{"host":"localhost","@timestamp":"2020-09-23T19:05:05-04:00","client_ip":"127.0.0.1","route_id":"1"}
{"host":"localhost","@timestamp":"2020-09-23T19:05:05-04:00","client_ip":"127.0.0.1","route_id":"1"}
```
## 相关资源
核心概念 - [插件](https://apisix.apache.org/docs/apisix/terminology/plugin/)

View File

@@ -0,0 +1,348 @@
---
title: Plugin
keywords:
- API 网关
- Apache APISIX
- 插件
- 插件优先级
description: 本文介绍了 APISIX Plugin 对象的相关信息及其使用方法,并且介绍了如何自定义插件优先级、自定义错误响应、动态控制插件执行状态等。
---
<!--
#
# 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 插件可以扩展 APISIX 的功能,以满足组织或用户特定的流量管理、可观测性、安全、请求/响应转换、无服务器计算等需求。
APISIX 提供了许多现有的插件,可以定制和编排以满足你的需求。这些插件可以全局启用,以在每个传入请求上触发,也可以局部绑定到其他对象,例如在 [Route](./route.md)[Service](./service.md)[Consumer](./consumer.md)[Plugin Config](./plugin-config.md) 上。你可以参考 [Admin API](../admin-api.md#plugin) 了解如何使用该资源。
如果现有的 APISIX 插件不满足需求,你还可以使用 Lua 或其他语言(如 Java、Python、Go 和 Wasm编写自定义插件。
## 插件安装
默认情况下,大多数 APISIX 插件都已[安装](https://github.com/apache/apisix/blob/master/apisix/cli/config.lua)
```lua title="apisix/cli/config.lua"
local _M = {
...
plugins = {
"real-ip",
"ai",
"client-control",
"proxy-control",
"request-id",
"zipkin",
"ext-plugin-pre-req",
"fault-injection",
"mocking",
"serverless-pre-function",
...
},
...
}
```
如果您想调整插件安装,请将自定义的 `plugins` 配置添加到 `config.yaml` 中。例如:
```yaml
plugins:
- real-ip # 安装
- ai
- real-ip
- ai
- client-control
- proxy-control
- request-id
- zipkin
- ext-plugin-pre-req
- fault-injection
# - mocking # 不安装
- serverless-pre-function
... # 其它插件
```
完整配置参考请参见 [`config.yaml.example`](https://github.com/apache/apisix/blob/master/conf/config.yaml.example)。
重新加载 APISIX 以使配置更改生效。
## 插件执行生命周期
安装的插件首先会被初始化。然后会检查插件的配置,以确保插件配置遵循定义的[JSON Schema](https://json-schema.org)。
当一个请求通过 APISIX 时,插件的相应方法会在以下一个或多个阶段中执行: `rewrite`, `access`, `before_proxy`, `header_filter`, `body_filter`, and `log`。这些阶段在很大程度上受到[OpenResty 指令](https://openresty-reference.readthedocs.io/en/latest/Directives/)的影响。
<br />
<div style={{textAlign: 'center'}}>
<img src="https://static.apiseven.com/uploads/2023/03/09/ZsH5C8Og_plugins-phases.png" alt="Routes Diagram" width="50%"/>
</div>
<br />
## 插件执行顺序
通常情况下,插件按照以下顺序执行:
1. [全局规则](./global-rule.md) 插件
1. rewrite 阶段的插件
2. access 阶段的插件
2. 绑定到其他对象的插件
1. rewrite 阶段的插件
2. access 阶段的插件
在每个阶段内,你可以在插件的 `_meta.priority` 字段中可选地定义一个新的优先级数,该优先级数优先于默认插件优先级在执行期间。具有更高优先级数的插件首先执行。
例如,如果你想在请求到达路由时,让 `limit-count`(优先级 1002先于 `ip-restriction`(优先级 3000运行可以通过将更高的优先级数传递给 `limit-count` 的 `_meta.priority` 字段来实现:
```json
{
...,
"plugins": {
"limit-count": {
...,
"_meta": {
"priority": 3010
}
}
}
}
```
若要将此插件实例的优先级重置为默认值,只需从插件配置中删除`_meta.priority`字段即可。
## 插件合并优先顺序
当同一个插件在全局规则中和局部规则(例如路由)中同时配置时,两个插件将顺序执行。
然而,如果相同的插件在多个对象上本地配置,例如在[`Route`](route.md), [`Service`](service.md), [`Consumer`](consumer.md) 或[`Plugin Config`](plugin-config.md) 上,每个非全局插件只会执行一次,因为在执行期间,针对特定的优先顺序,这些对象中配置的插件会被合并:
`Consumer` > `Consumer Group` > `Route` > `Plugin Config` > `Service`
因此,如果相同的插件在不同的对象中具有不同的配置,则合并期间具有最高优先顺序的插件配置将被使用。
## 通用配置
通过 `_meta` 配置项可以将一些通用的配置应用于插件,你可以参考下文使用这些通用配置。通用配置如下:
| 名称 | 类型 | 描述 |
|--------------- |-------------- |----------------|
| disable | boolean | 当设置为 `true` 时,则禁用该插件。可选值为 `true` 和 `false`。 |
| error_response | string/object | 自定义错误响应。 |
| priority | integer | 自定义插件优先级。 |
| filter | array | 根据请求的参数,在运行时控制插件是否执行。此配置由一个或多个 {var, operator, val} 元素组成列表,类似:`{{var, operator, val}, {var, operator, val}, ...}}`。例如 `{"arg_version", "==", "v2"}`,表示当前请求参数 `version` 是 `v2`。这里的 `var` 与 NGINX 内部自身变量命名是保持一致。操作符的使用方法,请参考 [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list)。|
### 禁用指定插件
通过 `disable` 参数,你可以将某个插件调整为“禁用状态”,即请求不会经过该插件。
```json
{
"proxy-rewrite": {
"_meta": {
"disable": true
}
}
}
```
### 自定义错误响应
通过 `error_response` 配置,可以将任意插件的错误响应配置成一个固定的值,避免因为插件内置的错误响应信息而带来不必要的麻烦。
如下配置表示将 `jwt-auth` 插件的错误响应自定义为 `Missing credential in request`。
```json
{
"jwt-auth": {
"_meta": {
"error_response": {
"message": "Missing credential in request"
}
}
}
}
```
### 自定义插件优先级
所有插件都有默认优先级,但是你仍然可以通过 `priority` 配置项来自定义插件优先级,从而改变插件执行顺序。
```json
{
"serverless-post-function": {
"_meta": {
"priority": 10000
},
"phase": "rewrite",
"functions" : ["return function(conf, ctx)
ngx.say(\"serverless-post-function\");
end"]
},
"serverless-pre-function": {
"_meta": {
"priority": -2000
},
"phase": "rewrite",
"functions": ["return function(conf, ctx)
ngx.say(\"serverless-pre-function\");
end"]
}
}
```
`serverless-pre-function` 的默认优先级是 `10000``serverless-post-function` 的默认优先级是 `-2000`。默认情况下会先执行 `serverless-pre-function` 插件,再执行 `serverless-post-function` 插件。
上面的配置则将 `serverless-pre-function` 插件的优先级设置为 `-2000``serverless-post-function` 插件的优先级设置为 `10000`,因此 `serverless-post-function` 插件会优先执行。
:::note 注意
- 自定义插件优先级只会影响插件实例绑定的主体,不会影响该插件的所有实例。比如上面的插件配置属于路由 A路由 B 上的插件 `serverless-post-function` 和 `serverless-post-function` 插件执行顺序不会受到影响,会使用默认优先级。
- 自定义插件优先级不适用于 Consumer 上配置的插件的 `rewrite` 阶段。路由上配置的插件的 `rewrite` 阶段将会优先运行,然后才会运行 Consumer 上除 `auth` 类插件之外的其他插件的 `rewrite` 阶段。
:::
### 动态控制插件执行状态
默认情况下,在路由中指定的插件都会被执行。但是你可以通过 `filter` 配置项为插件添加一个过滤器,通过过滤器的执行结果控制插件是否执行。
1. 如下配置表示,只有当请求查询参数中 `version` 值为 `v2` 时,`proxy-rewrite` 插件才会执行。
```json
{
"proxy-rewrite": {
"_meta": {
"filter": [
["arg_version", "==", "v2"]
]
},
"uri": "/anything"
}
}
```
2. 使用下述配置创建一条完整的路由。
```json
{
"uri": "/get",
"plugins": {
"proxy-rewrite": {
"_meta": {
"filter": [
["arg_version", "==", "v2"]
]
},
"uri": "/anything"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
```
3. 当请求中不带任何参数时,`proxy-rewrite` 插件不会执行,请求将被转发到上游的 `/get`。
```shell
curl -v /dev/null http://127.0.0.1:9080/get -H"host:httpbin.org"
```
```shell
< HTTP/1.1 200 OK
......
< Server: APISIX/2.15.0
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-62eb6eec-46c97e8a5d95141e621e07fe",
"X-Forwarded-Host": "httpbin.org"
},
"origin": "127.0.0.1, 117.152.66.200",
"url": "http://httpbin.org/get"
}
```
4. 当请求中携带参数 `version=v2` 时,`proxy-rewrite` 插件执行,请求将被转发到上游的 `/anything`:
```shell
curl -v /dev/null http://127.0.0.1:9080/get?version=v2 -H"host:httpbin.org"
```
```shell
< HTTP/1.1 200 OK
......
< Server: APISIX/2.15.0
<
{
"args": {
"version": "v2"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-62eb6f02-24a613b57b6587a076ef18b4",
"X-Forwarded-Host": "httpbin.org"
},
"json": null,
"method": "GET",
"origin": "127.0.0.1, 117.152.66.200",
"url": "http://httpbin.org/anything?version=v2"
}
```
## 热加载
APISIX 的插件是热加载的,不管你是新增、删除还是修改插件,都不需要重启服务。
只需要通过 Admin API 发送一个 HTTP 请求即可:
:::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/plugins/reload -H "X-API-KEY: $admin_key" -X PUT
```
:::note 注意
如果你已经在路由规则里配置了某个插件(比如在 Route 的 `plugins` 字段里面添加了它),然后在配置文件中禁用了该插件,在执行路由规则时则会跳过该插件。
:::
## Standalone 模式下的热加载
关于 Stand Alone 模式下的热加载的信息,请参考 [stand alone 模式](../../../en/latest/deployment-modes.md#standalone)

View File

@@ -0,0 +1,136 @@
---
title: Route
keywords:
- API 网关
- Apache APISIX
- Route
- 路由
description: 本文讲述了路由的概念以及使用方法。
---
<!--
#
# 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.
#
-->
## 描述
Route也称为路由是 APISIX 中最基础和最核心的资源对象APISIX 可以通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后将请求转发给到指定的上游服务。
## 配置简介
路由中主要包含三部分内容:
- 匹配规则:比如 `uri``host``remote_addr` 等等,你也可以自定义匹配规则,详细信息请参考 [Route body 请求参数](../admin-api.md#route-request-body-parameters)
- 插件配置:你可以根据业务需求,在路由中配置相应的插件来实现功能。详细信息请参考 [Plugin](./plugin.md)[plugin-config](./plugin-config.md)
- 上游信息:路由会根据配置的负载均衡信息,将请求按照规则转发至相应的上游。详细信息请参考 [Upstream](./upstream.md)
下图示例是一些 Route 规则的实例,当某些属性值相同时,图中用相同颜色标识。
![路由示例](../../../assets/images/routes-example.png)
你可以在路由中完成所有参数的配置,该方式设置容易设置,每个路由的相对独立自由度比较高。示例如下:
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
```shell
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/index.html",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key_type": "var",
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
当你的路由中有比较多的重复配置(比如启用相同的插件配置或上游信息),你也可以通过配置 [Service](service.md)[Upstream](upstream.md) 的 ID 或者其他对象的 ID 来完成路由配置。示例如下:
```shell
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/index.html",
"plugin_config_id": "123456789apacheapisix",
"upstream_id": "1"
}'
```
:::tip 提示
APISIX 所有的资源对象的 ID均使用字符串格式如果使用的上游 ID、服务 ID 或其他资源对象的 ID 大于 14 个字符时,请务必使用字符串形式表示该资源对象。例如:
```json
"plugin_config_id": "1234a67891234apisix",
"service_id": "434199918991639234",
"upstream_id": "123456789123456789"
```
:::
## 配置示例
以下示例创建的路由,是把 URI 为 `/index.html` 的请求代理到地址为 `127.0.0.1:1980` 的上游服务。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
```shell
HTTP/1.1 201 Created
Date: Sat, 31 Aug 2019 01:17:15 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX web server
{"node":{"value":{"uri":"\/index.html","upstream":{"nodes":{"127.0.0.1:1980":1},"type":"roundrobin"}},"createdIndex":61925,"key":"\/apisix\/routes\/1","modifiedIndex":61925}}
```
当接收到成功应答后,表示该路由已成功创建。
更多信息,请参考 [Admin API 的 Route 对象](../admin-api.md#route)

View File

@@ -0,0 +1,56 @@
---
title: Router
keywords:
- API 网关
- Apache APISIX
- Router
description: 本文介绍了如何选择 Apache APISIX 的 Router。
---
<!--
#
# 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 区别于其他 API 网关的一大特点是允许用户选择不同 Router 来更好匹配自由业务,在性能、自由之间做最适合选择。
你可以通过配置 `conf/config.yaml` 文件,来设置符合自身业务需求的路由。
## 配置简介
Router 具有以下配置:
- `apisix.router.http`: HTTP 请求路由。
- `radixtree_uri`:只使用 `uri` 作为主索引。基于 `radixtree` 引擎,支持全量和深前缀匹配,更多信息请参考[如何使用 router-radixtree](../../../en/latest/router-radixtree.md)
- `绝对匹配`:完整匹配给定的 `uri` ,比如 `/foo/bar``/foo/glo`
- `前缀匹配`:末尾使用 `*` 代表给定的 `uri` 是前缀匹配。比如 `/foo*`,则允许匹配 `/foo/``/foo/a``/foo/b`等。
- `匹配优先级`:优先尝试绝对匹配,若无法命中绝对匹配,再尝试前缀匹配。
- `任意过滤属性`:允许指定任何 Nginx 内置变量作为过滤条件,比如 URL 请求参数、请求头、cookie 等。
- `radixtree_uri_with_parameter`:同 `radixtree_uri` 但额外有参数匹配的功能。
- `radixtree_host_uri`:(默认)使用 `host + uri` 作为主索引(基于 `radixtree` 引擎),对当前请求会同时匹配 `host``uri`,支持的匹配条件与 `radixtree_uri` 基本一致。
::: 注意
在 3.2 及之前版本APISIX 使用 `radixtree_uri` 作为默认路由,`radixtree_uri``radixtree_host_uri` 拥有更好的性能,如果你对性能有更高的要求,并且能够接受 `radixtree_uri` 只使用 `uri` 作为主索引的特点,可以考虑继续使用 `radixtree_uri` 作为默认路由
:::
- `apisix.router.ssl`SSL 加载匹配路由。
- `radixtree_sni`:(默认)使用 `SNI` (Server Name Indication) 作为主索引(基于 radixtree 引擎)。

View File

@@ -0,0 +1,46 @@
---
title: Script
keywords:
- API 网关
- Apache APISIX
- Router
description: 本文介绍了 Apache APISIX Script 的使用方法及注意事项。
---
<!--
#
# 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.
#
-->
## 描述
Script 表示将在 `HTTP` 请求/响应生命周期期间执行的脚本。
Script 配置需要绑定在路由上。
Script 与 Plugin 不兼容,并且 Script 优先执行 Script这意味着配置 Script 后Route 上配置的 Plugin 将**不被执行**。
理论上,在 Script 中可以编写任意 Lua 代码,你也可以直接调用已有的插件以复用已有的代码。
Script 也有执行阶段概念,支持 `access``header_filter``body_filter``log` 阶段。系统会在相应阶段中自动执行 `Script` 脚本中对应阶段的代码。
```json
{
...
"script": "local _M = {} \n function _M.access(api_ctx) \n ngx.log(ngx.INFO,\"hit access phase\") \n end \nreturn _M"
}
```

View File

@@ -0,0 +1,351 @@
---
title: Secret
---
<!--
#
# 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 运行过程中所需的任何敏感信息,它可能是核心配置的一部分(如 etcd 的密码也可能是插件中的一些敏感信息。APISIX 中常见的密钥类型包括:
- 一些组件etcd、Redis、Kafka 等)的用户名、密码
- 证书的私钥
- API 密钥
- 敏感的插件配置字段通常用于身份验证、hash、签名或加密
APISIX Secret 允许用户在 APISIX 中通过一些密钥管理服务Vault 等)来存储密钥,在使用的时候根据 key 进行读取,确保密钥在整个平台中不以明文的形式存在。
其工作原理如图所示:
![secret](../../../assets/images/secret.png)
APISIX 目前支持通过以下方式存储密钥:
- [环境变量](#使用环境变量管理密钥)
- [HashiCorp Vault](#使用-vault-管理密钥)
- [AWS Secrets Manager](#使用-aws-secrets-manager-管理密钥)
- [GCP Secrets Manager](#使用-gcp-secrets-manager-管理密钥)
你可以在以下插件的 consumer 配置中通过指定格式的变量来使用 APISIX Secret 功能,比如 `key-auth` 插件。
:::note
如果某个配置项为:`key: "$ENV://ABC"`,当 APISIX Secret 中没有检索到 $ENV://ABC 对应的真实值,那么 key 的值将是 "$ENV://ABC" 而不是 `nil`
:::
## 使用环境变量管理密钥
使用环境变量来管理密钥意味着你可以将密钥信息保存在环境变量中在配置插件时通过特定格式的变量来引用环境变量。APISIX 支持引用系统环境变量和通过 Nginx `env` 指令配置的环境变量。
### 引用方式
```
$ENV://$env_name/$sub_key
```
- env_name: 环境变量名称
- sub_key: 当环境变量的值是 JSON 字符串时,获取某个属性的值
如果环境变量的值是字符串类型,如:
```
export JACK_AUTH_KEY=abc
```
则可以通过如下方式引用:
```
$ENV://JACK_AUTH_KEY
```
如果环境变量的值是一个 JSON 字符串,例如:
```
export JACK={"auth-key":"abc","openid-key": "def"}
```
则可以通过如下方式引用:
```
# 获取环境变量 JACK 的 auth-key
$ENV://JACK/auth-key
# 获取环境变量 JACK 的 openid-key
$ENV://JACK/openid-key
```
### 示例:在 key-auth 插件中使用
第一步APISIX 实例启动前创建环境变量
```
export JACK_AUTH_KEY=abc
```
第二步:在 `key-auth` 插件中引用环境变量
:::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/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "$ENV://JACK_AUTH_KEY"
}
}
}'
```
通过以上步骤,可以将 `key-auth` 插件中的 key 配置保存在环境变量中,而不是在配置插件时明文显示。
## 使用 Vault 管理密钥
使用 Vault 来管理密钥意味着你可以将密钥信息保存在 Vault 服务中在配置插件时通过特定格式的变量来引用。APISIX 目前支持对接 [Vault KV 引擎的 V1 版本](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v1)
### 引用方式
```
$secret://$manager/$id/$secret_name/$key
```
- manager: 密钥管理服务,可以是 Vault、AWS、GCP 等
- APISIX Secret 资源 ID需要与添加 APISIX Secret 资源时指定的 ID 保持一致
- secret_name: 密钥管理服务中的密钥名称
- key密钥管理服务中密钥对应的 key
### 示例:在 key-auth 插件中使用
第一步:在 Vault 中创建对应的密钥,可以使用如下命令:
```shell
vault kv put apisix/jack auth-key=value
```
第二步:通过 Admin API 添加 Secret 资源,配置 Vault 的地址等连接信息:
```shell
curl http://127.0.0.1:9180/apisix/admin/secrets/vault/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "https://127.0.0.1:8200"
"prefix": "apisix",
"token": "root"
}'
```
如果使用 APISIX Standalone 版本,则可以在 `apisix.yaml` 文件中添加如下配置:
```yaml
secrets:
- id: vault/1
prefix: apisix
token: root
uri: 127.0.0.1:8200
```
:::tip
它现在支持使用 [`namespace` 字段](../admin-api.md#secret-config-body-requset-parameters) 设置 [HashiCorp Vault Enterprise](https://developer.hashicorp.com/vault/docs/enterprise/namespaces#vault-api-and-namespaces) 和 HCP Vault 所支持的多租户命名空间概念。
:::
第三步:在 `key-auth` 插件中引用 APISIX Secret 资源,填充秘钥信息:
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "$secret://vault/1/jack/auth-key"
}
}
}'
```
通过上面两步操作,当用户请求命中 `key-auth` 插件时,会通过 APISIX Secret 组件获取到 key 在 Vault 中的真实值。
## 使用 AWS Secrets Manager 管理密钥
使用 AWS Secrets Manager 管理密钥是一种安全且便捷的方式来存储和管理敏感信息。通过这种方式,你可以将密钥信息保存在 AWS Secret Manager 中,并在配置 APISIX 插件时通过特定的格式引用这些密钥。
APISIX 目前支持两种访问方式: [长期凭证的访问方式](https://docs.aws.amazon.com/zh_cn/sdkref/latest/guide/access-iam-users.html)[短期凭证的访问方式](https://docs.aws.amazon.com/zh_cn/sdkref/latest/guide/access-temp-idc.html)
### 引用方式
在 APISIX 中引用密钥时,可以使用以下格式:
```
$secret://$manager/$id/$secret_name/$key
```
- manager: 密钥管理服务,可以是 Vault、AWS 等
- APISIX Secret 资源 ID需要与添加 APISIX Secret 资源时指定的 ID 保持一致
- secret_name: 密钥管理服务中的密钥名称
- key当密钥的值是 JSON 字符串时,获取某个属性的值
### 相关参数
| 名称 | 必选项 | 默认值 | 描述 |
| --- | --- | --- | --- |
| access_key_id | 是 | | AWS 访问密钥 ID |
| secret_access_key | 是 | | AWS 访问密钥 |
| session_token | 否 | | 临时访问凭证信息 |
| region | 否 | us-east-1 | AWS 区域 |
| endpoint_url | 否 | https://secretsmanager.{region}.amazonaws.com | AWS Secret Manager 地址 |
### 示例:在 key-auth 插件中使用
这里以 key-auth 插件的使用为例,展示如何通过 AWS Secret Manager 管理密钥:
第一步:在 AWS Secret Manager 中创建对应的密钥,这里使用 [localstack](https://www.localstack.cloud/) 模拟,可以使用如下命令:
```shell
docker exec -i localstack sh -c "awslocal secretsmanager create-secret --name jack --description 'APISIX Secret' --secret-string '{\"auth-key\":\"value\"}'"
```
第二步:通过 Admin API 添加 Secret 资源,配置 AWS Secret Manager 的地址等连接信息:
你可以在环境变量中存储关键密钥信息,保证配置信息是安全的,在使用到地方进行引用:
```shell
export AWS_ACCESS_KEY_ID=<access_key_id>
export AWS_SECRET_ACCESS_KEY=<secrets_access_key>
export AWS_SESSION_TOKEN=<token>
```
当然,你也可以通过直接在配置中指定所有信息内容:
```shell
curl http://127.0.0.1:9180/apisix/admin/secrets/aws/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"endpoint_url": "http://127.0.0.1:4566",
"region": "us-east-1",
"access_key_id": "access",
"secret_access_key": "secret",
"session_token": "token"
}'
```
如果使用 APISIX Standalone 版本,则可以在 `apisix.yaml` 文件中添加如下配置:
```yaml
secrets:
- id: aws/1
endpoint_url: http://127.0.0.1:4566
region: us-east-1
access_key_id: access
secret_access_key: secret
session_token: token
```
第三步:在 `key-auth` 插件中引用 APISIX Secret 资源,填充秘钥信息:
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "$secret://aws/1/jack/auth-key"
}
}
}'
```
通过上面两步操作,当用户请求命中 `key-auth` 插件时,会通过 APISIX Secret 组件获取到 key 在 AWS Secret Manager 中的真实值。
### 验证
你可以通过如下指令进行验证:
```shell
# 示例:将下面的 your_route 替换为实际的路由路径
curl -i http://127.0.0.1:9080/your_route -H 'apikey: value'
```
这将验证 key-auth 插件是否正确地使用 AWS Secret Manager 中的密钥。
## 使用 GCP Secrets Manager 管理密钥
使用 GCP Secret Manager 来管理密钥意味着你可以将密钥信息保存在 GCP 服务中在配置插件时通过特定格式的变量来引用。APISIX 目前支持对接 GCP Secret Manager, 所支持的验证方式是[OAuth 2.0](https://developers.google.com/identity/protocols/oauth2?hl=zh-cn)
### 引用方式
```
$secret://$manager/$id/$secret_name/$key
```
引用方式和之前保持一致:
- manager: 密钥管理服务,可以是 Vault、AWS\GCP 等
- APISIX Secret 资源 ID需要与添加 APISIX Secret 资源时指定的 ID 保持一致
- secret_name: 密钥管理服务中的密钥名称
- key当密钥的值是 JSON 字符串时,获取某个属性的值
### 必要参数
| 名称 | 必选项 | 默认值 | 描述 |
| ----------------------- | -------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| auth_config | 是 | | `auth_config``auth_file` 必须配置一个。 |
| auth_config.client_email | 是 | | 谷歌服务帐号的 email 参数。 |
| auth_config.private_key | 是 | | 谷歌服务帐号的私钥参数。 |
| auth_config.project_id | 是 | | 谷歌服务帐号的项目 ID。 |
| auth_config.token_uri | 否 | https://oauth2.googleapis.com/token | 请求谷歌服务帐户的令牌的 URI。 |
| auth_config.entries_uri | 否 | https://secretmanager.googleapis.com/v1 | 谷歌密钥服务访问端点 API。 |
| auth_config.scope | 否 | https://www.googleapis.com/auth/cloud-platform | 谷歌服务账号的访问范围,可参考 [OAuth 2.0 Scopes for Google APIs](https://developers.google.com/identity/protocols/oauth2/scopes)|
| auth_file | 是 | | `auth_config``auth_file` 必须配置一个。 |
| ssl_verify | 否 | true | 当设置为 `true` 时,启用 `SSL` 验证。 |
你需要配置相应的认证参数,或者通过 auth_file 来指定认证文件,其中 auth_file 的内容为认证参数的 json 格式。
### 示例
以下一种正确的配置实例:
```
curl http://127.0.0.1:9180/apisix/admin/secrets/gcp/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"auth_config" : {
"client_email": "email@apisix.iam.gserviceaccount.com",
"private_key": "private_key",
"project_id": "apisix-project",
"token_uri": "https://oauth2.googleapis.com/token",
"entries_uri": "https://secretmanager.googleapis.com/v1",
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
}
}'
```

View File

@@ -0,0 +1,124 @@
---
title: Service
keywords:
- API 网关
- Apache APISIX
- Router
description: 本文介绍了 Apache APISIX Service 对象的概念及其使用方法。
---
<!--
#
# 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.
#
-->
## 描述
Service也称之为服务是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,但与路由之间,通常是 1:N 即一对多的关系。参看下图。
![服务示例](../../../assets/images/service-example.png)
不同路由规则同时绑定到一个服务上,这些路由将具有相同的上游和插件配置,减少冗余配置。当路由和服务都开启同一个插件时,路由中的插件优先级高于服务中的插件。关于插件优先级的更多信息,请参考 [Plugin](./plugin.md)
更多关于 Service 的信息,请参考 [Admin API 的 Service 对象](../admin-api.md#service)
## 配置示例
以下示例创建了一个启用限流插件的服务,并且将该服务绑定到 ID 为 `100``101` 的路由上。
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. 创建服务。
```shell
curl http://127.0.0.1:9180/apisix/admin/services/200 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
2. 创建 ID 为 `100` 的路由,并绑定 ID 为 `200` 的服务。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/100 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"service_id": "200"
}'
```
3. 创建 ID 为 `101` 的路由,并绑定 ID 为 `200` 的服务。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/101 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"methods": ["GET"],
"uri": "/foo/index.html",
"service_id": "200"
}'
```
当然你也可以为路由指定不同的插件配置或上游。比如在以下示例中,我们设置了不同的限流参数,其他部分(比如上游)则继续使用上述服务中的配置参数。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/102 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/bar/index.html",
"id": "102",
"service_id": "200",
"plugins": {
"limit-count": {
"count": 2000,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
}
}'
```
:::tip 提示
当路由和服务都启用同一个插件时,路由中的插件配置会优先于服务。更多信息,请参考[Plugin](./plugin.md)
:::

View File

@@ -0,0 +1,255 @@
---
title: Upstream
keywords:
- APISIX
- API 网关
- 上游
- Upstream
description: 本文介绍了 Apache APISIX Upstream 对象的作用以及如何使用 Upstream。
---
<!--
#
# 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.
#
-->
## 描述
Upstream也称之为上游是对虚拟主机抽象即应用层服务或节点的抽象。你可以通过 Upstream 对象对多个服务节点按照配置规则进行负载均衡。
上游的地址信息可以直接配置到[路由](./route.md)(或[服务](./service.md))中。
![Upstream 示例](../../../assets/images/upstream-example.png)
如上图所示,当多个路由(或服务)使用该上游时,你可以单独创建上游对象,在路由中通过使用 `upstream_id` 的方式引用资源,减轻维护压力。
你也可以将上游的信息直接配置在指定路由或服务中,不过路由中的配置优先级更高,优先级行为与[插件](./plugin.md) 非常相似。
## 配置参数
APISIX 的 Upstream 对象除了基本的负载均衡算法外,还支持对上游做主被动健康检查、重试等逻辑。更多信息,请参考 [Admin API 中的 Upstream 资源](../admin-api.md#upstream)
:::note
您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. 创建上游对象用例。
```shell
curl http://127.0.0.1:9180/apisix/admin/upstreams/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"type": "chash",
"key": "remote_addr",
"nodes": {
"127.0.0.1:80": 1,
"httpbin.org:80": 2
}
}'
```
上游对象创建后,可以被路由或服务引用。
2. 在路由中使用创建的上游对象。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/index.html",
"upstream_id": 1
}'
```
3. 为方便使用,你也可以直接把上游信息直接配置在某个路由或服务。
以下示例是将上游信息直接配置在路由中:
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/index.html",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
## 使用示例
- 配置健康检查的示例。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/index.html",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
}
"type": "roundrobin",
"retries": 2,
"checks": {
"active": {
"http_path": "/status",
"host": "foo.com",
"healthy": {
"interval": 2,
"successes": 1
},
"unhealthy": {
"interval": 1,
"http_failures": 2
}
}
}
}
}'
```
更多信息,请参考[健康检查的文档](../tutorials/health-check.md)。
以下是使用不同 [`hash_on`](../admin-api.md#upstream-body-request-methods) 类型的配置示例:
### Consumer
1. 创建一个 Consumer 对象。
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "auth-jack"
}
}
}'
```
2. 创建路由,启用 `key-auth` 插件,配置 `upstream.hash_on` 的类型为 `consumer`。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"plugins": {
"key-auth": {}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
},
"type": "chash",
"hash_on": "consumer"
},
"uri": "/server_port"
}'
```
3. 测试请求,认证通过后的 `consumer_name` 将作为负载均衡哈希算法的哈希值。
```shell
curl http://127.0.0.1:9080/server_port -H "apikey: auth-jack"
```
### Cookie
1. 创建路由并配置 `upstream.hash_on` 的类型为 `cookie`。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/hash_on_cookie",
"upstream": {
"key": "sid",
"type": "chash",
"hash_on": "cookie",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
}
}
}'
```
2. 客户端请求携带 `Cookie`。
```shell
curl http://127.0.0.1:9080/hash_on_cookie \
-H "X-API-KEY: $admin_key" \
-H "Cookie: sid=3c183a30cffcda1408daf1c61d47b274"
```
### Header
1. 创建路由并配置 `upstream.hash_on` 的类型为 `header``key` 为 `content-type`。
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/hash_on_header",
"upstream": {
"key": "content-type",
"type": "chash",
"hash_on": "header",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
}
}
}'
```
2. 客户端请求携带 `content-type` 的 `header`。
```shell
curl http://127.0.0.1:9080/hash_on_header \
-H "X-API-KEY: $admin_key" \
-H "Content-Type: application/json"
```