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,44 @@
---
title: API Gateway
keywords:
- Apache APISIX
- API Gateway
- Gateway
description: This article mainly introduces the role of the API gateway and why it is needed.
---
<!--
#
# 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.
#
-->
## Description
An API gateway is a software pattern that sits in front of an application programming interface (API) or group of microservices, to facilitate requests and delivery of data and services. Its primary role is to act as a single entry point and standardized process for interactions between an organization's apps, data, and services and internal and external customers. The API gateway can also perform various other functions to support and manage API usage, from authentication to rate limiting to analytics.
An API gateway also acts as a gateway between the API and the underlying infrastructure. It can be used to route requests to different backends, such as a load balancer, or route requests to different services based on the request headers.
## Why use an API gateway?
An API gateway comes with a lot of benefits over a traditional API microservice. The following are some of the benefits:
- It is a single entry point for all API requests.
- It can be used to route requests to different backends, such as a load balancer, or route requests to different services based on the request headers.
- It can be used to perform authentication, authorization, and rate-limiting.
- It can be used to support analytics, such as monitoring, logging, and tracing.
- It can protect the API from malicious attack vectors such as SQL injections, DDOS attacks, and XSS.
- It decreases the complexity of the API and microservices.

View File

@@ -0,0 +1,122 @@
---
title: Consumer Group
keywords:
- API gateway
- Apache APISIX
- Consumer Group
description: Consumer Group in Apache 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.
#
-->
## Description
Consumer Groups are used to extract commonly used [Plugin](./plugin.md) configurations and can be bound directly to a [Consumer](./consumer.md).
With consumer groups, you can define any number of plugins, e.g. rate limiting and apply them to a set of consumers,
instead of managing each consumer individually.
## Example
The example below illustrates how to create a Consumer Group and bind it to a Consumer.
Create a Consumer Group which shares the same rate limiting quota:
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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"
}
}
}'
```
Create a Consumer within the Consumer Group:
```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"
}'
```
When APISIX can't find the Consumer Group with the `group_id`, the Admin API is terminated with a status code of `400`.
:::tip
1. When the same plugin is configured in [consumer](./consumer.md), [routing](./route.md), [plugin config](./plugin-config.md) and [service](./service.md), only one configuration is in effect, and the consumer has the highest priority. Please refer to [Plugin](./plugin.md).
2. If a Consumer already has the `plugins` field configured, the plugins in the Consumer Group will effectively be merged into it. The same plugin in the Consumer Group will not override the one configured directly in the Consumer.
:::
For example, if we configure a Consumer Group as shown below:
```json
{
"id": "bar",
"plugins": {
"response-rewrite": {
"body": "hello"
}
}
}
```
To a Consumer as shown below.
```json
{
"username": "foo",
"group_id": "bar",
"plugins": {
"basic-auth": {
"username": "foo",
"password": "bar"
},
"response-rewrite": {
"body": "world"
}
}
}
```
Then the `body` in `response-rewrite` keeps `world`.

View File

@@ -0,0 +1,174 @@
---
title: Consumer
keywords:
- Apache APISIX
- API Gateway
- APISIX Consumer
- Consumer
description: This article describes the role of the Apache APISIX Consumer object and how to use the 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.
#
-->
## Description
For an API gateway, it is usually possible to identify the type of the requester by using things like their request domain name and client IP address. A gateway like APISIX can then filter these requests using [Plugins](./plugin.md) and forward it to the specified [Upstream](./upstream.md).
It has the highest priority: Consumer > Route > Plugin Config > Service.
But this level of depth can be insufficient on some occasions.
![consumer-who](../../../assets/images/consumer-who.png)
An API gateway should know who the consumer of the API is to configure different rules for different consumers. This is where the **Consumer** construct comes in APISIX.
### Configuration options
The fields for defining a Consumer are defined as below.
| Field | Required | Description |
| ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `username` | True | Name of the consumer. |
| `plugins` | False | Plugin configuration of the **Consumer**. For specific Plugin configurations, please refer the [Plugins](./plugin.md). |
## Identifying a Consumer
The process of identifying a Consumer in APISIX is described below:
![consumer-internal](../../../assets/images/consumer-internal.png)
1. The first step is Authentication. This is achieved by Authentication Plugins like [key-auth](../plugins/key-auth.md) and [JWT](../plugins/jwt-auth.md).
2. After authenticating, you can obtain the `id` of the Consumer. This `id` will be the unique identifier of a Consumer.
3. The configurations like Plugins and Upstream bound to the Consumer are then executed.
Consumers are useful when you have different consumers requesting the same API and you need to execute different Plugin and Upstream configurations based on the consumer. These need to be used in conjunction with the user authentication system.
Authentication plugins that can be configured with a Consumer include `basic-auth`, `hmac-auth`, `jwt-auth`, `key-auth`, `ldap-auth`, and `wolf-rbac`.
Refer to the documentation for the [key-auth](../plugins/key-auth.md) authentication Plugin to further understand the concept of a Consumer.
:::note
For more information about the Consumer object, you can refer to the [Admin API Consumer](../admin-api.md#consumer) object resource introduction.
:::
## Example
The example below shows how you can enable a Plugin for a specific Consumer.
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. Create a Consumer, specify the authentication plugin `key-auth`, and enable the specific plugin `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. Create a Router, set routing rules and enable plugin configuration.
```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. Send a test request, the first two return to normal, did not reach the speed limit threshold.
```shell
curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
```
The third test returns `503` and the request is restricted.
```shell
HTTP/1.1 503 Service Temporarily Unavailable
...
```
We can use the [consumer-restriction](../plugins/consumer-restriction.md) Plugin to restrict our user "Jack" from accessing the API.
1. Add Jack to the blacklist.
```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. Repeated tests, all return `403`; Jack is forbidden to access this API.
```shell
curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
```
```shell
HTTP/1.1 403
...
```

View File

@@ -0,0 +1,151 @@
---
title: Credential
keywords:
- APISIX
- API Gateway
- Consumer
- Credential
description: This article describes what the Apache APISIX Credential object does and how to use it.
---
<!--
#
# 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.
#
-->
## Description
Credential is the object that holds the [Consumer](./consumer.md) credential configuration.
A Consumer can use multiple credentials of different types.
Credentials are used when you need to configure multiple credentials for a Consumer.
Currently, Credential can be configured with the authentication plugins `basic-auth`, `hmac-auth`, `jwt-auth`, and `key-auth`.
### Configuration options
The fields for defining a Credential are defined as below.
| Field | Required | Description |
|---------|----------|---------------------------------------------------------------------------------------------------------|
| desc | False | Decriptiion of the Credential. |
| labels | False | Labels of the Credential. |
| plugins | False | The plugin configuration corresponding to Credential. For more information, see [Plugins](./plugin.md). |
:::note
For more information about the Credential object, you can refer to the [Admin API Credential](../admin-api.md#credential) resource guide.
:::
## Example
[Consumer Example](./consumer.md#example) describes how to configure the auth plugin for Consumer and how to use it with other plugins.
In this example, the Consumer has only one credential of type key-auth.
Now suppose the user needs to configure multiple credentials for that Consumer, you can use Credential to support this.
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. Create the Consumer without specifying the auth plug-n, but use Credential to configure the auth plugin later.
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack"
}'
```
2. Create 2 `key-auth` Credentials for the Consumer.
```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. Create a route and enable `key-auth` plugin on it.
```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. Test.
Test the request with the `auth-one` and `auth-two` keys, and they both respond correctly.
```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
```
Enable the `limit-count` plugin for the Consumer.
```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"
}
}
}'
```
Requesting the route more than 3 times in a row with each of the two keys, the test returns `503` and the request is restricted.

View File

@@ -0,0 +1,70 @@
---
title: Global Rules
keywords:
- API Gateway
- Apache APISIX
- Global Rules
description: This article describes how to use global rules.
---
<!--
#
# 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.
#
-->
## Description
A [Plugin](./plugin.md) configuration can be bound directly to a [Route](./route.md), a [Service](./service.md) or a [Consumer](./consumer.md). But what if we want a Plugin to work on all requests? This is where we register a global Plugin with Global Rule.
Compared with the plugin configuration in Route, Service, Plugin Config, and Consumer, the plugin in the Global Rules is always executed first.
## Example
The example below shows how you can use the `limit-count` Plugin on all requests:
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
```shell
curl -X PUT \
http://{apisix_listen_address}/apisix/admin/global_rules/1 \
-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
}
}
}'
```
You can also list all the Global rules by making this request with the Admin API:
```shell
curl http://{apisix_listen_address}/apisix/admin/global_rules -H "X-API-KEY: $admin_key"
```

View File

@@ -0,0 +1,171 @@
---
title: Plugin Config
keywords:
- API Gateway
- Apache APISIX
- Plugin Config
description: Plugin Config in Apache 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.
#
-->
## Description
Plugin Configs are used to extract commonly used [Plugin](./plugin.md) configurations and can be bound directly to a [Route](./route.md).
While configuring the same plugin, only one copy of the configuration is valid. Please read the [plugin execution order](../terminology/plugin.md#plugins-execution-order) and [plugin merging order](../terminology/plugin.md#plugins-merging-precedence).
## Example
The example below illustrates how to create a Plugin Config and bind it to a Route:
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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_configs/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"desc": "blah",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503
}
}
}'
```
```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY:edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
"uris": ["/index.html"],
"plugin_config_id": 1,
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
When APISIX can't find the Plugin Config with the `id`, the requests reaching this Route are terminated with a status code of `503`.
:::note
If a Route already has the `plugins` field configured, the plugins in the Plugin Config will effectively be merged to it.
The same plugin in the Plugin Config will not override the ones configured directly in the Route. For more information, see [Plugin](./plugin.md).
:::
For example, if you configure a Plugin Config as shown below:
```shell
curl http://127.0.0.1:9180/apisix/admin/plugin_configs/1 \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"desc": "I am plugin_config 1",
"plugins": {
"ip-restriction": {
"whitelist": [
"127.0.0.0/24",
"113.74.26.106"
]
},
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503
}
}
}'
```
to a Route as shown below,
```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"
}
}
}'
```
the effective configuration will be as the one shown below:
```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
}
}
}'
```

View File

@@ -0,0 +1,83 @@
---
title: Plugin Metadata
keywords:
- API Gateway
- Apache APISIX
- Plugin Metadata
description: Plugin Metadata in Apache 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.
#
-->
## Description
In this document, you will learn the basic concept of plugin metadata in APISIX and why you may need them.
Explore additional resources at the end of the document for more information on related topics.
## Overview
In APISIX, a plugin metadata object is used to configure the common metadata field(s) of all plugin instances sharing the same plugin name. It is useful when a plugin is enabled across multiple objects and requires a universal update to their metadata fields.
The following diagram illustrates the concept of plugin metadata using two instances of [syslog](https://apisix.apache.org/docs/apisix/plugins/syslog/) plugins on two different routes, as well as a plugin metadata object setting a [global](https://apisix.apache.org/docs/apisix/plugins/syslog/) `log_format` for the syslog plugin:
![plugin_metadata](https://static.apiseven.com/uploads/2023/04/17/Z0OFRQhV_plugin%20metadata.svg)
Without otherwise specified, the `log_format` on plugin metadata object should apply the same log format uniformly to both `syslog` plugins. However, since the `syslog` plugin on the `/orders` route has a different `log_format`, requests visiting this route will generate logs in the `log_format` specified by the plugin in route.
Metadata properties set at the plugin level is more granular and has a higher priority over the "global" metadata object.
Plugin metadata objects should only be used for plugins that have metadata fields. Check the specific plugin documentation to know more.
## Example usage
The example below shows how you can configure through the Admin API:
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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"
}
}'
```
With this configuration, your logs would be formatted as shown below:
```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"}
```
## Additional Resource(s)
Key Concepts - [Plugins](https://apisix.apache.org/docs/apisix/terminology/plugin/)

View File

@@ -0,0 +1,346 @@
---
title: Plugin
keywords:
- API Gateway
- Apache APISIX
- Plugin
- Filter
- Priority
description: This article introduces the related information of the APISIX Plugin object and how to use it, and introduces how to customize the plugin priority, customize the error response, and dynamically control the execution status of the 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.
#
-->
## Description
APISIX Plugins extend APISIX's functionalities to meet organization or user-specific requirements in traffic management, observability, security, request/response transformation, serverless computing, and more.
A **Plugin** configuration can be bound directly to a [`Route`](route.md), [`Service`](service.md), [`Consumer`](consumer.md) or [`Plugin Config`](plugin-config.md). You can refer to [Admin API plugins](../admin-api.md#plugin) for how to use this resource.
If existing APISIX Plugins do not meet your needs, you can also write your own plugins in Lua or other languages such as Java, Python, Go, and Wasm.
## Plugins installation
By default, most APISIX plugins are [installed](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",
...
},
...
}
```
If you would like to make adjustments to plugins installation, add the customized `plugins` configuration to `config.yaml`. For example:
```yaml
plugins:
- real-ip # installed
- ai
- real-ip
- ai
- client-control
- proxy-control
- request-id
- zipkin
- ext-plugin-pre-req
- fault-injection
# - mocking # not install
- serverless-pre-function
... # other plugins
```
See `config.yaml.example`(https://github.com/apache/apisix/blob/master/conf/config.yaml.example) for a complete configuration reference.
You should reload APISIX for configuration changes to take effect.
## Plugins execution lifecycle
An installed plugin is first initialized. The configuration of the plugin is then checked against the defined [JSON Schema](https://json-schema.org) to make sure the plugins configuration schema is correct.
When a request goes through APISIX, the plugin's corresponding methods are executed in one or more of the following phases : `rewrite`, `access`, `before_proxy`, `header_filter`, `body_filter`, and `log`. These phases are largely influenced by the [OpenResty directives](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 />
## Plugins execution order
In general, plugins are executed in the following order:
1. Plugins in [global rules](./global-rule.md)
1. plugins in rewrite phase
2. plugins in access phase
2. Plugins bound to other objects
1. plugins in rewrite phase
2. plugins in access phase
Within each phase, you can optionally define a new priority number in the `_meta.priority` field of the plugin, which takes precedence over the default plugins priority during execution. Plugins with higher priority numbers are executed first.
For example, if you want to have `limit-count` (priority 1002) run before `ip-restriction` (priority 3000) when requests hit a route, you can do so by passing a higher priority number to `_meta.priority` field of `limit-count`:
```json
{
...,
"plugins": {
"limit-count": {
...,
"_meta": {
"priority": 3010
}
}
}
}
```
To reset the priority of this plugin instance to the default, simply remove the `_meta.priority` field from your plugin configuration.
## Plugins merging precedence
When the same plugin is configured both globally in a global rule and locally in an object (e.g. a route), both plugin instances are executed sequentially.
However, if the same plugin is configured locally on multiple objects, such as on [Route](./route.md), [Service](./service.md), [Consumer](./consumer.md), [Consumer Group](./consumer-group.md), or [Plugin Config](./plugin-config.md), only one copy of configuration is used as each non-global plugin is only executed once. This is because during execution, plugins configured in these objects are merged with respect to a specific order of precedence:
`Consumer` > `Consumer Group` > `Route` > `Plugin Config` > `Service`
such that if the same plugin has different configurations in different objects, the plugin configuration with the highest order of precedence during merging will be used.
## Plugin common configuration
Some common configurations can be applied to plugins through the `_meta` configuration items, the specific configuration items are as follows:
| Name | Type | Description |
|----------------|--------------- |-------------|
| disable | boolean | When set to `true`, the plugin is disabled. |
| error_response | string/object | Custom error response. |
| priority | integer | Custom plugin priority. |
| filter | array | Depending on the requested parameters, it is decided at runtime whether the plugin should be executed. Something like this: `{{var, operator, val}, {var, operator, val}, ...}}`. For example: `{"arg_version", "==", "v2"}`, indicating that the current request parameter `version` is `v2`. The variables here are consistent with NGINX internal variables. For details on supported operators, please see [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list). |
### Disable the plugin
Through the `disable` configuration, you can add a new plugin with disabled status and the request will not go through the plugin.
```json
{
"proxy-rewrite": {
"_meta": {
"disable": true
}
}
}
```
### Custom error response
Through the `error_response` configuration, you can configure the error response of any plugin to a fixed value to avoid troubles caused by the built-in error response information of the plugin.
The configuration below means to customize the error response of the `jwt-auth` plugin to `Missing credential in request`.
```json
{
"jwt-auth": {
"_meta": {
"error_response": {
"message": "Missing credential in request"
}
}
}
}
```
### Custom plugin priority
All plugins have default priorities, but through the `priority` configuration item you can customize the plugin priority and change the plugin execution order.
```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"]
}
}
```
The default priority of serverless-pre-function is 10000, and the default priority of serverless-post-function is -2000. By default, the serverless-pre-function plugin will be executed first, and serverless-post-function plugin will be executed next.
The above configuration means setting the priority of the serverless-pre-function plugin to -2000 and the priority of the serverless-post-function plugin to 10000. The serverless-post-function plugin will be executed first, and serverless-pre-function plugin will be executed next.
:::note
- Custom plugin priority only affects the current object(route, service ...) of the plugin instance binding, not all instances of that plugin. For example, if the above plugin configuration belongs to Route A, the order of execution of the plugins serverless-post-function and serverless-post-function on Route B will not be affected and the default priority will be used.
- Custom plugin priority does not apply to the rewrite phase of some plugins configured on the consumer. The rewrite phase of plugins configured on the route will be executed first, and then the rewrite phase of plugins (exclude auth plugins) from the consumer will be executed.
:::
### Dynamically control whether the plugin is executed
By default, all plugins specified in the route will be executed. But we can add a filter to the plugin through the `filter` configuration item, and control whether the plugin is executed through the execution result of the filter.
The configuration below means that the `proxy-rewrite` plugin will only be executed if the `version` value in the request query parameters is `v2`.
```json
{
"proxy-rewrite": {
"_meta": {
"filter": [
["arg_version", "==", "v2"]
]
},
"uri": "/anything"
}
}
```
Create a complete route with the below configuration:
```json
{
"uri": "/get",
"plugins": {
"proxy-rewrite": {
"_meta": {
"filter": [
["arg_version", "==", "v2"]
]
},
"uri": "/anything"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
```
When the request does not have any parameters, the `proxy-rewrite` plugin will not be executed, the request will be proxy to the upstream `/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"
}
```
When the parameter `version=v2` is carried in the request, the `proxy-rewrite` plugin is executed, and the request will be proxy to the upstream `/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"
}
```
## Hot reload
APISIX Plugins are hot-loaded. This means that there is no need to restart the service if you add, delete, modify plugins, or even if you update the plugin code. To hot-reload, you can send an HTTP request through the [Admin API](../admin-api.md):
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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
If a configured Plugin is disabled, then its execution will be skipped.
:::
### Hot reload in standalone mode
For hot-reloading in standalone mode, see the plugin related section in [stand alone mode](../deployment-modes.md#standalone).

View File

@@ -0,0 +1,91 @@
---
title: Route
keywords:
- API Gateway
- Apache APISIX
- Route
description: This article describes the concept of Route and how to use it.
---
<!--
#
# 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.
#
-->
## Description
Routes match the client's request based on defined rules, load and execute the corresponding [plugins](./plugin.md), and forwards the request to the specified [Upstream](./upstream.md).
A Route mainly consists of three parts:
1. Matching rules (`uri`, `host`, `remote address`)
2. Plugin configuration (current-limit, rate-limit)
3. Upstream information
The image below shows some example Route rules. Note that the values are of the same color if they are identical.
![routes-example](../../../assets/images/routes-example.png)
All the parameters are configured directly in the Route. It is easy to set up, and each Route has a high degree of freedom.
When Routes have repetitive configurations (say, enabling the same plugin configuration or Upstream information), to update it, we need to traverse all the Routes and modify them. This adds a lot of complexity, making it difficult to maintain.
These shortcomings are independently abstracted in APISIX by two concepts: [Service](service.md) and [Upstream](upstream.md).
## Example
The Route example shown below proxies the request with the URL `/index.html` to the Upstream service with the address `127.0.0.1:1980`.
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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": "/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}}
```
A successful response indicates that the route was created.
## Configuration
For specific options of Route, please refer to the [Admin API](../admin-api.md#route).

View File

@@ -0,0 +1,56 @@
---
title: Router
keywords:
- API Gateway
- Apache APISIX
- Router
description: This article describes how to choose a router for Apache 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.
#
-->
## Description
A distinguishing feature of Apache APISIX from other API gateways is that it allows you to choose different Routers to better match free services, giving you the best choices for performance and freedom.
You can set the Router that best suits your needs in your configuration file `conf/config.yaml`.
## Configuration
A Router can have the following configurations:
- `apisix.router.http`: The HTTP request route. It can take the following values:
- `radixtree_uri`: Only use the `uri` as the primary index. To learn more about the support for full and deep prefix matching, check [How to use router-radixtree](../router-radixtree.md).
- `Absolute match`: Match completely with the given `uri` (`/foo/bar`, `/foo/glo`).
- `Prefix match`: Match with the given prefix. Use `*` to represent the given `uri` for prefix matching. For example, `/foo*` can match with `/foo/`, `/foo/a` and `/foo/b`.
- `match priority`: First try an absolute match, if it didn't match, try prefix matching.
- `Any filter attribute`: This allows you to specify any Nginx built-in variable as a filter, such as URL request parameters, request headers, and cookies.
- `radixtree_uri_with_parameter`: Like `radixtree_uri` but also supports parameter match.
- `radixtree_host_uri`: (Default) Matches both host and URI of the request. Use `host + uri` as the primary index (based on the `radixtree` engine).
:::note
In version 3.2 and earlier, APISIX used `radixtree_uri` as the default Router. `radixtree_uri` has better performance than `radixtree_host_uri`, so if you have higher performance requirements and can live with the fact that `radixtree_uri` only use the `uri` as the primary index, consider continuing to use `radixtree_uri` as the default Router.
:::
- `apisix.router.ssl`: SSL loads the matching route.
- `radixtree_sni`: (Default) Use `SNI` (Server Name Indication) as the primary index (based on the radixtree engine).

View File

@@ -0,0 +1,39 @@
---
title: 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.
#
-->
## Description
Scripts lets you write arbitrary Lua code or directly call existing plugins and execute them during the HTTP request/response lifecycle.
A Script configuration can be directly bound to a [Route](./route.md).
Scripts and [Plugins](./plugin.md) are mutually exclusive, and a Script is executed before a Plugin. This means that after configuring a Script, the Plugin configured on the Route will **not** be executed.
Scripts also have a concept of execution phase which supports the `access`, `header_filter`, `body_filter`, and the `log` phase. The corresponding phase will be executed automatically by the system in the 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,349 @@
---
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.
#
-->
## Description
Secrets refer to any sensitive information required during the running process of APISIX, which may be part of the core configuration (such as the etcd's password) or some sensitive information in the plugin. Common types of Secrets in APISIX include:
- username, the password for some components (etcd, Redis, Kafka, etc.)
- the private key of the certificate
- API key
- Sensitive plugin configuration fields, typically used for authentication, hashing, signing, or encryption
APISIX Secret allows users to store secrets through some secrets management services (Vault, etc.) in APISIX, and read them according to the key when using them to ensure that **Secrets do not exist in plain text throughout the platform**.
Its working principle is shown in the figure:
![secret](../../../assets/images/secret.png)
APISIX currently supports storing secrets in the following ways:
- [Environment Variables](#use-environment-variables-to-manage-secrets)
- [HashiCorp Vault](#use-hashicorp-vault-to-manage-secrets)
- [AWS Secrets Manager](#use-aws-secrets-manager-to-manage-secrets)
- [GCP Secrets Manager](#use-gcp-secrets-manager-to-manage-secrets)
You can use APISIX Secret functions by specifying format variables in the consumer configuration of the following plugins, such as `key-auth`.
:::note
If a key-value pair `key: "$ENV://ABC"` is configured in APISIX and the value of `$ENV://ABC` is unassigned in the environment variable, `$ENV://ABC` will be interpreted as a string literal, instead of `nil`.
:::
## Use environment variables to manage secrets
Using environment variables to manage secrets means that you can save key information in environment variables, and refer to environment variables through variables in a specific format when configuring plugins. APISIX supports referencing system environment variables and environment variables configured through the Nginx `env` directive.
### Usage
```
$ENV://$env_name/$sub_key
```
- env_name: environment variable name
- sub_key: get the value of a property when the value of the environment variable is a JSON string
If the value of the environment variable is of type string, such as:
```
export JACK_AUTH_KEY=abc
```
It can be referenced as follows:
```
$ENV://JACK_AUTH_KEY
```
If the value of the environment variable is a JSON string like:
```
export JACK={"auth-key":"abc","openid-key": "def"}
```
It can be referenced as follows:
```
# Get the auth-key of the environment variable JACK
$ENV://JACK/auth-key
# Get the openid-key of the environment variable JACK
$ENV://JACK/openid-key
```
### Example: use in key-auth plugin
Step 1: Create environment variables before the APISIX instance starts
```
export JACK_AUTH_KEY=abc
```
Step 2: Reference the environment variable in the `key-auth` plugin
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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"
}
}
}'
```
Through the above steps, the `key` configuration in the `key-auth` plugin can be saved in the environment variable instead of being displayed in plain text when configuring the plugin.
## Use HashiCorp Vault to manage secrets
Using HashiCorp Vault to manage secrets means that you can store secrets information in the Vault service and refer to it through variables in a specific format when configuring plugins. APISIX currently supports [Vault KV engine version V1](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v1).
### Usage
```
$secret://$manager/$id/$secret_name/$key
```
- manager: secrets management service, could be the HashiCorp Vault, AWS, etc.
- id: APISIX Secrets resource ID, which needs to be consistent with the one specified when adding the APISIX Secrets resource
- secret_name: the secret name in the secrets management service
- key: the key corresponding to the secret in the secrets management service
### Example: use in key-auth plugin
Step 1: Create the corresponding key in the Vault, you can use the following command:
```shell
vault kv put apisix/jack auth-key=value
```
Step 2: Add APISIX Secrets resources through the Admin API, configure the Vault address and other connection information:
```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"
}'
```
If you use APISIX Standalone mode, you can add the following configuration in `apisix.yaml` configuration file:
```yaml
secrets:
- id: vault/1
prefix: apisix
token: root
uri: 127.0.0.1:8200
```
:::tip
It now supports the use of the [`namespace` field](../admin-api.md#request-body-parameters-11) to set the multi-tenant namespace concepts supported by [HashiCorp Vault Enterprise](https://developer.hashicorp.com/vault/docs/enterprise/namespaces#vault-api-and-namespaces) and HCP Vault.
:::
Step 3: Reference the APISIX Secrets resource in the `key-auth` plugin and fill in the key information:
```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"
}
}
}'
```
Through the above two steps, when the user request hits the `key-auth` plugin, the real value of the key in the Vault will be obtained through the APISIX Secret component.
## Use AWS Secrets Manager to manage secrets
Managing secrets with AWS Secrets Manager is a secure and convenient way to store and manage sensitive information. This method allows you to save secret information in AWS Secrets Manager and reference these secrets in a specific format when configuring APISIX plugins.
APISIX currently supports two authentication methods: using [long-term credentials](https://docs.aws.amazon.com/sdkref/latest/guide/access-iam-users.html) and [short-term credentials](https://docs.aws.amazon.com/sdkref/latest/guide/access-temp-idc.html).
### Usage
```
$secret://$manager/$id/$secret_name/$key
```
- manager: secrets management service, could be the HashiCorp Vault, AWS, etc.
- id: APISIX Secrets resource ID, which needs to be consistent with the one specified when adding the APISIX Secrets resource
- secret_name: the secret name in the secrets management service
- key: get the value of a property when the value of the secret is a JSON string
### Required Parameters
| Name | Required | Default Value | Description |
| --- | --- | --- | --- |
| access_key_id | True | | AWS Access Key ID |
| secret_access_key | True | | AWS Secret Access Key |
| session_token | False | | Temporary access credential information |
| region | False | us-east-1 | AWS Region |
| endpoint_url | False | https://secretsmanager.{region}.amazonaws.com | AWS Secret Manager URL |
### Example: use in key-auth plugin
Here, we use the key-auth plugin as an example to demonstrate how to manage secrets through AWS Secrets Manager.
Step 1: Create the corresponding key in the AWS secrets manager. Here, [localstack](https://www.localstack.cloud/) is used for as the example environment, and you can use the following command:
```shell
docker exec -i localstack sh -c "awslocal secretsmanager create-secret --name jack --description 'APISIX Secret' --secret-string '{\"auth-key\":\"value\"}'"
```
Step 2: Add APISIX Secrets resources through the Admin API, configure the connection information such as the address of AWS Secrets Manager.
You can store the critical key information in environment variables to ensure the configuration information is secure, and reference it where it is used:
```shell
export AWS_ACCESS_KEY_ID=<access_key_id>
export AWS_SECRET_ACCESS_KEY=<secrets_access_key>
export AWS_SESSION_TOKEN=<token>
export AWS_REGION=<aws-region>
```
Alternatively, you can also specify all the information directly in the configuration:
```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"
}'
```
If you use APISIX Standalone mode, you can add the following configuration in `apisix.yaml` configuration file:
```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
```
Step 3: Reference the APISIX Secrets resource in the `key-auth` plugin and fill in the key information:
```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"
}
}
}'
```
Through the above two steps, when the user request hits the `key-auth` plugin, the real value of the key in the Vault will be obtained through the APISIX Secret component.
### Verification
You can verify this with the following command:
```shell
#Replace the following your_route with the actual route path.
curl -i http://127.0.0.1:9080/your_route -H 'apikey: value'
```
This will verify whether the `key-auth` plugin is correctly using the key from AWS Secrets Manager.
## Use GCP Secrets Manager to manage secrets
Using the GCP Secrets Manager to manage secrets means you can store the secret information in the GCP service, and reference it using a specific format of variables when configuring plugins. APISIX currently supports integration with the GCP Secrets Manager, and the supported authentication method is [OAuth 2.0](https://developers.google.com/identity/protocols/oauth2).
### Reference Format
```
$secret://$manager/$id/$secret_name/$key
```
The reference format is the same as before:
- manager: secrets management service, could be the HashiCorp Vault, AWS, GCP etc.
- id: APISIX Secrets resource ID, which needs to be consistent with the one specified when adding the APISIX Secrets resource
- secret_name: the secret name in the secrets management service
- key: get the value of a property when the value of the secret is a JSON string
### Required Parameters
| Name | Required | Default | Description |
|-------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| auth_config | True | | Either `auth_config` or `auth_file` must be provided. |
| auth_config.client_email | True | | Email address of the Google Cloud service account. |
| auth_config.private_key | True | | Private key of the Google Cloud service account. |
| auth_config.project_id | True | | Project ID in the Google Cloud service account. |
| auth_config.token_uri | False | https://oauth2.googleapis.com/token | Token URI of the Google Cloud service account. |
| auth_config.entries_uri | False | https://secretmanager.googleapis.com/v1 | The API access endpoint for the Google Secrets Manager. |
| auth_config.scope | False | https://www.googleapis.com/auth/cloud-platform | Access scopes of the Google Cloud service account. See [OAuth 2.0 Scopes for Google APIs](https://developers.google.com/identity/protocols/oauth2/scopes) |
| auth_file | True | | Path to the Google Cloud service account authentication JSON file. Either `auth_config` or `auth_file` must be provided. |
| ssl_verify | False | true | When set to `true`, enables SSL verification as mentioned in [OpenResty docs](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake). |
You need to configure the corresponding authentication parameters, or specify the authentication file through auth_file, where the content of auth_file is in JSON format.
### Example
Here is a correct configuration example:
```
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,118 @@
---
title: 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.
#
-->
## Description
A Service is an abstraction of an API (which can also be understood as a set of [Route](./route.md) abstractions). It usually corresponds to an upstream service abstraction.
The relationship between Routes and a Service is usually N:1 as shown in the image below.
![service-example](../../../assets/images/service-example.png)
As shown, different Routes could be bound to the same Service. This reduces redundancy as these bounded Routes will have the same [Upstream](./upstream.md) and [Plugin](./plugin.md) configurations.
For more information about Service, please refer to [Admin API Service object](../admin-api.md#service).
## Examples
The following example creates a Service that enables the `limit-count` Plugin and then binds it to the Routes with the ids `100` and `101`.
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
```
:::
1. Create a Service.
```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. create new Route and reference the service by 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"
}'
```
```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"
}'
```
We can also specify different Plugins or Upstream for the Routes than the ones defined in the Service. The example below creates a Route with a `limit-count` Plugin. This Route will continue to use the other configurations defined in the Service (here, the Upstream configuration).
```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"
}
}
}'
```
:::note
When a Route and a Service enable the same Plugin, the one defined in the Route is given the higher priority.
:::

View File

@@ -0,0 +1,249 @@
---
title: Upstream
keywords:
- Apache APISIX
- API Gateway
- APISIX Upstream
- Upstream
description: This article describes the role of the Apache APISIX Upstream object and how to use the 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.
#
-->
## Description
Upstream is a virtual host abstraction that performs load balancing on a given set of service nodes according to the configured rules.
Although Upstream can be directly configured to the [Route](./route.md) or [Service](./service.md), using an Upstream object is recommended when there is duplication as shown below.
![upstream-example](../../../assets/images/upstream-example.png)
By creating an Upstream object and referencing it by `upstream_id` in the Route, you can ensure that there is only a single value of the object that needs to be maintained.
An Upstream configuration can be directly bound to a Route or a Service, but the configuration in Route has a higher priority. This behavior is consistent with priority followed by the [Plugin](./plugin.md) object.
## Configuration
In addition to the equalization algorithm selections, Upstream also supports passive health check and retry for the upstream. You can learn more about this [Admin API Upstream](../admin-api.md#upstream).
To create an Upstream object, you can use the Admin API as shown below.
:::note
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
```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/upstreams/1 \
-H "X-API-KEY: $admin_key" -X PUT -d '
{
"type": "chash",
"key": "remote_addr",
"nodes": {
"127.0.0.1:80": 1,
"foo.com:80": 2
}
}'
```
After creating an Upstream object, it can be referenced by a specific Route or Service as shown below.
```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
}'
```
For convenience, you can directly bind the upstream address to a Route or Service.
```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
}
}
}'
```
## Example
The example below shows how you can configure a health check.
```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
}
}
}
}
}'
```
You can learn more about health checks [health-check](../tutorials/health-check.md).
The examples below show configurations that use different `hash_on` types.
### Consumer
Creating a Consumer object.
```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"
}
}
}'
```
Creating a Route object and enabling the `key-auth` authentication Plugin.
```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"
}'
```
To test the request, the `consumer_name` passed for authentication will be used as the hash value of the load balancing hash algorithm.
```shell
curl http://127.0.0.1:9080/server_port -H "apikey: auth-jack"
```
### Cookie
Creating a Route and an upstream object.
```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
}
}
}'
```
The client can then send a request with a cookie.
```shell
curl http://127.0.0.1:9080/hash_on_cookie \
-H "Cookie: sid=3c183a30cffcda1408daf1c61d47b274"
```
### Header
Creating a Route and an upstream object.
```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
}
}
}'
```
The client can now send requests with a header. The example below shows using the header `Content-Type`.
```shell
curl http://127.0.0.1:9080/hash_on_header \
-H "X-API-KEY: $admin_key" \
-H "Content-Type: application/json"
```