配置跨命名空间引用
在生产环境中,跨命名空间引用可以支持集中式基础设施管理,同时让应用团队独立运维。例如,平台团队可以在专用命名空间中管理共享后端服务,应用团队则在各自命名空间中部署路由。启用跨命名空间引用后,可以在命名空间之间受控共享资源,而无需复制配置,从而提升安全边界、治理能力和运维扩展性。
跨命名空间引用仅通过 Gateway API 资源支持。Ingress 资源和 APISIX CRD 不支持跨命名空间引用。跨命名空间引用能力依赖两个机制:
- ReferenceGrant:当一个命名空间中的路由引用另一个命名空间中的后端资源时需要配置。支持的路由类型包括 HTTPRoute、GRPCRoute、TCPRoute、UDPRoute 和 TLSRoute。
- Gateway 监听器的
allowedRoutes:当不同命名空间中的路由需要挂载到 Gateway 监听器时需要配置。
本指南通过 Gateway API 资源演示如何配置跨命名空间引用,如下图所示。示例假设 Ingress Controller 已部署在 aic 命名空间中。如果你使用不同命名空间,请根据实际部署调整配置。
创建命名空间
创建租户命名空间和后端命名空间:
kubectl create namespace backend-ns
kubectl create namespace tenant-a
为 tenant-a 命名空间添加标签,以便 Gateway 通过 selector 选择路由:
kubectl label namespace tenant-a tenant=tenant-a
创建后端服务
在后端命名空间中创建 Deployment 和 Service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: backend-ns
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: backend-ns
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: httpbin
将配置应用到集群:
kubectl apply -f httpbin-deployment.yaml
创建 ReferenceGrant
在 ReferenceGrant 中,from 字段指定允许哪些资源引用目标命名空间中的对象,to 字段定义该命名空间中的哪些资源可以被引用。
在后端命名空间 backend-ns 中创建 ReferenceGrant,允许来自租户命名空间 tenant-a 的引用:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-from-tenant-a
namespace: backend-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: tenant-a
to:
- group: ""
kind: Service
name: httpbin
❶ from.group:发起引用资源的 API group。
❷ from.kind:发起引用资源的 kind。支持的资源 kind 包括 HTTPRoute、GRPCRoute、TCPRoute、UDPRoute 和 TLSRoute。
❸ from.namespace:发起引用资源所在命名空间。
❹ to.group:目标资源的 API group。对于 Service 等 core 资源,使用 ""。
❺ to.kind:目标资源的 kind,例如 Service 或 Secret。
❻ to.name:允许被引用的资源名称。
to.name 是可选字段。如果省略,ReferenceGrant 将允许引用目标命名空间内所有匹配 to.group 和 to.kind 的资源。
将 配置应用到集群:
kubectl apply -f referencegrant.yaml
创建路由
在租户命名空间 tenant-a 中创建 HTTPRoute,并引用 backend-ns 中的后端服务。该 HTTPRoute 会挂载到 aic 命名空间中的 apisix Gateway 资源。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: tenant-a
spec:
parentRefs:
- name: apisix
namespace: aic
rules:
- matches:
- path:
type: PathPrefix
value: /ip
backendRefs:
- kind: Service
name: httpbin
namespace: backend-ns
port: 80
weight: 1
将配置应用到集群:
kubectl apply -f httpbin-route.yaml
配置 Gateway 允许跨命名空间路由
默认情况下,Gateway 监听器只允许来自 Gateway 所在命名空间的路由(from: Same)挂载。如需允许其他命名空间中的路由,请通过 allowedRoutes 更新 Gateway 监听器:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: aic
name: apisix
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
tenant: tenant-a
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: apisix-config
❶ allowedRoutes:定义允许哪些路由挂载到该监听器的配置。
❷ namespaces:用于判断可用路由的命名空间选择机制。
❸ from: Selector:基于 selector 过滤命名空间,只允许匹配的命名空间。
❹ selector:用于匹配命名空间的标签选择条件。
❺ matchLabels:命名空间必须满足的键值标签要求。
❻ tenant:表示成员关系的命名空间标签。
将配置应用到集群:
kubectl apply -f gateway.yaml
你也可以配置 Gateway 监听器,允许来自所有命名空间的路由:
allowedRoutes:
namespaces:
from: All
在多租户或不受信任的环境中使用 from: All,会允许任何命名空间将 HTTPRoute 挂载到该 Gateway 监听器。这可能导致不受信任的命名空间劫持流量,或暴露其无权访问的后端。
验证
将网关 Service 端口暴露到本地机器:
# 替换为你的网关 Service 名称
kubectl port-forward svc/<gateway-service-name> 9080:80 &
向路由发送请求:
curl -i "http://127.0.0.1:9080/ip"
你应收到类似如下的 HTTP/1.1 200 OK 响应:
{
"origin": "127.0.0.1"
}
这表示请求已成功跨命名空间路由。