a6-recipe-multi-tenant
概览
API 网关的多租户模式是指通过同一个网关实例为多个相互隔离的租户(客户、团队或应用)提供服务,并为每个租户配置独立的限流、身份认证和路由规则。
APISIX 通过以下机制实现多租户:
- 消费者组——将消费者按租户分组,并共享插件配置。
- 基于 Host、路径或请求头的路由——将请求路由到指定租户的上游。
- 租户级限流——为每个消费者组执行独立配额。
proxy-rewrite——通过请求头将租户上下文转发给后端。
适用场景
- 共享单一 API 网关的多个客户
- 为不同团队服务的内部平台
- SaaS 应用,要求每租户费率限额和认证
- 需要将租户身份转给后端服务
方法 A:使用消费者组隔离租户
按租户对消费者进行分组。每个租户通过消费者组获得共享的插件配置,例如限流和请求转换。
1. 为每个租户创建消费者组
# Free tier — 100 requests/day
a6 consumer-group create -f - <<'EOF'
{
"id": "tenant-free",
"desc": "Free tier tenant",
"plugins": {
"limit-count": {
"count": 100,
"time_window": 86400,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Free tier quota exceeded"
}
}
}
EOF
# Pro tier — 10000 requests/day
a6 consumer-group create -f - <<'EOF'
{
"id": "tenant-pro",
"desc": "Pro tier tenant",
"plugins": {
"limit-count": {
"count": 10000,
"time_window": 86400,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Pro tier quota exceeded"
}
}
}
EOF
2. 创建消费者并分配到组
a6 consumer create -f - <<'EOF'
{
"username": "acme-corp",
"group_id": "tenant-pro",
"plugins": {
"key-auth": { "key": "acme-secret-key" }
}
}
EOF
a6 consumer create -f - <<'EOF'
{
"username": "startup-xyz",
"group_id": "tenant-free",
"plugins": {
"key-auth": { "key": "startup-xyz-key" }
}
}
EOF
3. 创建启用身份认证的共享路由
a6 route create -f - <<'EOF'
{
"id": "api-v1",
"uri": "/api/v1/*",
"upstream": {
"type": "roundrobin",
"nodes": { "api-backend:8080": 1 }
},
"plugins": {
"key-auth": {}
}
}
EOF
现在,acme-corp 每天可发送 10,000 个请求,startup-xyz 每天可发送 100 个请求,
两者都通过同一路由。
方法 B:基于 Host 的租户路由
根据 Host 请求头,将每个租户的流量路由到各自的后端。
1. 为每个租户创建上游
a6 upstream create -f - <<'EOF'
{
"id": "upstream-tenant-a",
"type": "roundrobin",
"nodes": { "tenant-a-backend:8080": 1 }
}
EOF
a6 upstream create -f - <<'EOF'
{
"id": "upstream-tenant-b",
"type": "roundrobin",
"nodes": { "tenant-b-backend:8080": 1 }
}
EOF
2. 创建基于 Host 的路由
a6 route create -f - <<'EOF'
{
"id": "tenant-a-route",
"host": "tenant-a.example.com",
"uri": "/*",
"upstream_id": "upstream-tenant-a",
"plugins": { "key-auth": {} }
}
EOF
a6 route create -f - <<'EOF'
{
"id": "tenant-b-route",
"host": "tenant-b.example.com",
"uri": "/*",
"upstream_id": "upstream-tenant-b",
"plugins": { "key-auth": {} }
}
EOF