如何通过resourceNames限制对指定customresourcedefinitions的访问?
问题原因与解决方案
为什么添加resourceNames后创建CRD被拒绝?
Kubernetes RBAC的resourceNames字段仅对已存在的集群资源生效。当执行create操作创建CRD时,该资源尚未在集群中注册,kube-apiserver无法匹配resourceNames中指定的名称,因此会直接拒绝请求。
正确的权限配置方式
要实现对特定名称CRD的创建、更新、删除权限控制,需要拆分RBAC规则,并结合准入控制严格限制创建的CRD名称:
1. 拆分RBAC ClusterRole规则
将创建操作与更新/删除操作分开配置:创建操作不指定resourceNames(允许创建CRD),更新、删除等操作指定目标CRD名称,确保仅能操作指定的CRD:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: restricted-crd-manager rules: # 允许创建CRD(无resourceNames限制,因为创建时资源未存在) - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] verbs: ["create"] # 仅允许对指定名称的CRD执行更新、删除等操作 - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] resourceNames: ["example.acme.com"] verbs: ["update", "delete", "patch", "get", "list", "watch"]
2. 用准入控制限制创建的CRD名称(可选但推荐)
如果需要严格限制用户只能创建指定名称的CRD,可通过ValidatingAdmissionPolicy实现集群级别的名称校验:
# 定义准入校验规则 apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: restrict-crd-name spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apiextensions.k8s.io"] apiVersions: ["v1"] operations: ["CREATE"] resources: ["customresourcedefinitions"] validations: - expression: "object.metadata.name == 'example.acme.com'" message: "仅允许创建名称为example.acme.com的CRD" --- # 绑定校验规则到集群范围 apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: restrict-crd-name-binding spec: policyName: restrict-crd-name matchResources: namespaceSelector: {} # 对所有命名空间(集群范围)生效
验证配置
将上述ClusterRole绑定到目标用户/角色后,用户将:
- 仅能创建名称为
example.acme.com的CRD(如果配置了准入控制) - 仅能对
example.acme.com这个CRD执行更新、删除等操作
内容的提问来源于stack exchange,提问作者austinheiman
相关产品推荐
相关产品推荐

