使用 Kubernetes RBAC 委派 Gateway API 访问权限
Gateway API 的面向角色的安全模型把基础设施、Gateway 与 Route 配置分层,使不同团队可以独立管理各层。在共享集群中,Kubernetes 基于角色的访问控制(RBAC)可将这种职责分离变成可强制执行的权限,而无需给每个团队集群级访问权。
本指南展示如何在基础设施提供方、网关运维、应用开发者和后端所有者之间委派这些权限。示例使用标准 Kubernetes 与 Gateway API 资源,同时适用于 APISIX Ingress Controller 和 API7 Ingress Controller。
前置条件
请完成以下前置条件:
- 设置 Ingress Controller 和网关。
- 安装计划委派的 Route 类型所需的 Gateway API 自定义资源定义(CRD)。
- 创建 Gateway、Route 和后端资源使用的命名空间。
- 确认集群身份提供方所提供的用户或组名称。
- 使用集群管理员,或其他有权创建和授予本指南中 RBAC 资源的账号。
Kubernetes 会阻止用户授予自己不具备的权限。仅当委派的 RBAC 管理员已拥有 Role 或 ClusterRole 中包含的全部权限,或拥有 escalate 权限时,才能创建该角色;仅当其拥有被引用角色中的权限,或拥有 bind 权限时,才能创建绑定。完整授权规则请参阅防止权限提升。
规划权限委派
Kubernetes RBAC 控制谁能管理 Kubernetes 资源,但不会决定 Route 能否挂载到 Gateway,或能否引用其他命名空间中的资源。Gateway 所有者使用监听器的 allowedRoutes 选择允许的 Route 类型和命名空间;后端所有者使用 ReferenceGrant 批准跨命名空间引用。
控制器 ServiceAccount 与这些用户角色彼此独立。安装 Ingress Controller 时会授予其 ServiceAccount 监听资源和更新状态的权限;不要把该身份复用于用户。
示例使用以下委派模型:
| 团队 | 组 | 管理对象 | 范围 |
|---|---|---|---|
| 基础设施提供方 | infrastructure-providers | GatewayClass | 集群 |
| 网关运维团队 | gateway-operators | Gateway | aic 命名空间 |
| 应用开发团队 | tenant-a-developers | Route 资源和共享 Gateway 的只读权限 | tenant-a 命名空间和 Gateway aic/apisix |
| 后端所有者 | backend-owners | ReferenceGrant | backend-ns 命名空间 |
请根据身份提供方和集群设计替换示例中的组、命名空间和 Gateway 名称。如果 Gateway 名称不是 apisix,尤其需要更新 shared-gateway-reader Role 中的 resourceNames 值。
不要向这些团队授予更新 Gateway API */status 资源的权限。Ingress Controller 会写入状态,以报告资源的 Accepted、Programmed 和引用解析情况。
本指南仅委派标准 Gateway API 资源。如果应用团队还管理 BackendTrafficPolicy 或 HTTPRoutePolicy 等 APISIX 自定义资源,请根据每种自定义资源的归属单独授予权限。
配置 RBAC
为委派模型中的各团队创建并应用 RBAC 资源。
委派 GatewayClass 管理权限
GatewayClass 是集群范围的资源,可以选择由 Gateway API 实现管理的基础设施。应仅允许基础设施提供方管理该资源。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: gatewayclass-editor
rules:
- apiGroups:
- gateway.networking.k8s.io
resources:
- gatewayclasses
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: infrastructure-providers-gatewayclass-editor
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gatewayclass-editor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: infrastructure-providers
应用清单:
kubectl apply -f gatewayclass-rbac.yaml
委派 Gateway 管理权限
仅授予网关运维团队管理其负责命名空间中 Gateway 的权限。本示例不允许他们管理 GatewayClass 或 Route。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gateway-editor
namespace: aic
rules:
- apiGroups:
- gateway.networking.k8s.io
resources:
- gateways
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gateway-operators-gateway-editor
namespace: aic
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gateway-editor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: gateway-operators
应用清单:
kubectl apply -f gateway-rbac.yaml
委派 Route 管理权限
授予应用开发团队管理其应用命名空间中 Route 的权限。他们不能创建或修改共享 Gateway。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gateway-api-route-editor
namespace: tenant-a
rules:
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes
- httproutes
- tcproutes
- tlsroutes
- udproutes
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tenant-a-developers-route-editor
namespace: tenant-a
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gateway-api-route-editor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: tenant-a-developers
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: shared-gateway-reader
namespace: aic
rules:
- apiGroups:
- gateway.networking.k8s.io
resourceNames:
- apisix
resources:
- gateways
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tenant-a-developers-shared-gateway-reader
namespace: aic
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: shared-gateway-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: tenant-a-developers
应用清单:
kubectl apply -f route-rbac.yaml
该只读 Role 允许应用团队查看 aic 命名空间中的共享 apisix Gateway,但不允许列出其他 Gateway 或修改共享 Gateway。
委派 ReferenceGrant 管理权限
ReferenceGrant 创建在被引用资源所在的命名空间中,可以授权其他命名空间中的资源引用指定的 Service、Secret 或其他目标。应把管理权限授予目标命名空间中可信的所有者,而不是请求访问的团队。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: referencegrant-editor
namespace: backend-ns
rules:
- apiGroups:
- gateway.networking.k8s.io
resources:
- referencegrants
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-owners-referencegrant-editor
namespace: backend-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: referencegrant-editor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: backend-owners
应用清单:
kubectl apply -f referencegrant-rbac.yaml
后端所有者现在可以批准特定的跨命名空间引用。除非应用开发者同时拥有后端命名空间,否则不能批准自己的请求。
验证委派的访问权限
以下检查会模拟示例用户和组。运行模拟检查需要拥有模拟这些身份的权限。
验证预期权限:
kubectl auth can-i create gatewayclasses.gateway.networking.k8s.io \
--all-namespaces \
--as=infra-user \
--as-group=infrastructure-providers
kubectl auth can-i create gateways.gateway.networking.k8s.io \
-n aic \
--as=gateway-user \
--as-group=gateway-operators
kubectl auth can-i create httproutes.gateway.networking.k8s.io \
-n tenant-a \
--as=app-user \
--as-group=tenant-a-developers
kubectl auth can-i get gateways.gateway.networking.k8s.io/apisix \
-n aic \
--as=app-user \
--as-group=tenant-a-developers
kubectl auth can-i create referencegrants.gateway.networking.k8s.io \
-n backend-ns \
--as=backend-user \
--as-group=backend-owners
每条命令都应返回 yes。
验证职责边界是否生效:
kubectl auth can-i create gateways.gateway.networking.k8s.io \
-n aic \
--as=app-user \
--as-group=tenant-a-developers
kubectl auth can-i create referencegrants.gateway.networking.k8s.io \
-n backend-ns \
--as=app-user \
--as-group=tenant-a-developers
kubectl auth can-i update gateways.gateway.networking.k8s.io \
--subresource=status \
-n aic \
--as=gateway-user \
--as-group=gateway-operators
每条命令都应返回 no。
RBAC 验证只能确认某个身份是否可以执行 API 操作。若要授权 Route 挂载和跨命名空间引用,还需配置 allowedRoutes 和 ReferenceGrant。