跳到主要内容

使用 Kubernetes RBAC 委派 Gateway API 访问权限

使用 Kubernetes 基于角色的访问控制(RBAC),在基础设施、网关、应用和后端团队之间划分 Gateway API 资源管理职责。本指南中的示例仅向每个团队授予其所负责资源的访问权限。

示例使用标准 Kubernetes 和 Gateway API 资源,同时适用于 APISIX Ingress Controller 与 API7 Ingress Controller,并遵循 Gateway API 的面向角色的安全模型

前提条件

请完成以下前提条件:

  • 设置 Ingress Controller 和网关
  • 安装计划委派的 Route 类型所需的 Gateway API 自定义资源定义(CRD)。
  • 创建 Gateway、Route 和后端资源使用的命名空间。
  • 确认集群身份提供方所提供的用户或组名称。
  • 使用集群管理员,或其他有权创建和授予本指南中 RBAC 资源的账号。
委派的 RBAC 管理员

Kubernetes 会阻止用户授予自己不具备的权限。仅当委派的 RBAC 管理员已拥有 Role 或 ClusterRole 中包含的全部权限,或拥有 escalate 权限时,才能创建该角色;仅当其拥有被引用角色中的权限,或拥有 bind 权限时,才能创建绑定。完整授权规则请参阅防止权限提升

规划权限委派

Kubernetes RBAC 控制谁能管理 Kubernetes 资源,但不会决定 Route 能否挂载到 Gateway,或能否引用其他命名空间中的资源。Gateway 所有者使用监听器的 allowedRoutes 选择允许的 Route 类型和命名空间;后端所有者使用 ReferenceGrant 批准跨命名空间引用。

控制器 ServiceAccount 与这些用户角色彼此独立。安装 Ingress Controller 时会授予其 ServiceAccount 监听资源和更新状态的权限;不要把该身份复用于用户。

示例使用以下委派模型:

团队管理对象范围
基础设施提供方infrastructure-providersGatewayClass集群
网关运维团队gateway-operatorsGatewayaic 命名空间
应用开发团队tenant-a-developersRoute 资源和共享 Gateway 的只读权限tenant-a 命名空间和 Gateway aic/apisix
后端所有者backend-ownersReferenceGrantbackend-ns 命名空间

请根据身份提供方和集群设计替换示例中的组、命名空间和 Gateway 名称。如果 Gateway 名称不是 apisix,尤其需要更新 shared-gateway-reader Role 中的 resourceNames 值。

不要向这些团队授予更新 Gateway API */status 资源的权限。Ingress Controller 会写入状态,以报告资源的 AcceptedProgrammed 和引用解析情况。

本指南仅委派标准 Gateway API 资源。如果应用团队还管理 BackendTrafficPolicyHTTPRoutePolicy 等 APISIX 自定义资源,请根据每种自定义资源的归属单独授予权限。

配置 RBAC

为委派模型中的各团队创建并应用 RBAC 资源。

委派 GatewayClass 管理权限

GatewayClass 是集群范围的资源,可以选择由 Gateway API 实现管理的基础设施。应仅允许基础设施提供方管理该资源。

gatewayclass-rbac.yaml
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。

gateway-rbac.yaml
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。

route-rbac.yaml
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 或其他目标。应把管理权限授予目标命名空间中可信的所有者,而不是请求访问的团队。

referencegrant-rbac.yaml
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