Role 和 RoleBinding
Role
和 RoleBinding
资源都是命名空间中的资源。前者决定可以针对哪些 URL 路径执行哪些操作;后者将前者与用户主体绑定(当然后者也可以与 ClusterRole
进行绑定,虽然这样还是只能操作 RoleBinding
所在命名空间的 URL 路径)。
创建 Role
Role
是 Kubernetes 中的一种资源,因此可以通过 YAML 定义来生成。如下,在 foo
命名空间中创建一个名为 service-reader
的 Role 对象,该角色规定能够对 services/test-service
资源对象执行 get
和 list
操作:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role # 类型为 Role
metadata:
namespace: foo # 所在命名空间名
name: service-reader
rules: # 重点!定义了能够对哪些 URL 路径执行哪些操作
- apiGroups: [""] # 由于 services.apiGroup=v1,即没有 "/","/" 前面是资源所属的组,所以 services 不属于任何组,所以这里为空
verbs: ["get", "list"] # 能够执行 get 和 list 操作
resources: ["services"] # 针对 Service 资源
resourceNames: ["test-service"] # 针对 Service 资源中的名为 test-service 的对象;若这里省略,则表示针对所有 Service 资源
当然也可以使用 kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run] [options]
命令来创建该资源:
kubectl create role service-reader --verb=get,list --resource=services --resource-name=test-service -n foo
创建 RoleBinding
在创建完 Role
之后,需要创建 RoleBinding
来将 用户主体 与 Role
绑定,从而限制用户主体可以对哪些 URL 路径执行哪些操作。
创建 RoleBinding
同样可以使用 YAML 定义来生成。如下,在 foo
命名空间中创建一个名为 test
的 RoleBinding 对象,其与名为 service-reader
的 Role 对象绑定,并与 foo
命名空间中名为 default
的 ServiceAccount 以及 bar
命名空间中名为 default
的 ServiceAccount 绑定:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding # 类型为 RoleBinding
metadata:
name: test
namespace: foo # 所在命名空间名
roleRef: # 绑定的 Role(也支持绑定 ClusterRole 资源)
apiGroup: rbac.authorization.k8s.io # Role 资源所属的 API 组
kind: Role # 类型为 Role
name: service-reader # Role 的名字
subjects: # 绑定的用户主体(可以是 用户名、ServiceAccount、组)
- kind: ServiceAccount # 绑定的用户主体类型为 ServiceAccount
name: default # ServiceAccount 名
namespace: foo # 用户主体所属的 命名空间
- kind: ServiceAccount
name: default
namespace: bar
当然也可以使用 kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]
命令来创建该资源:
kubectl create rolebinding test --role=service-reader --serviceaccount=foo:default --serviceaccount=bar:default -n foo
测试
根据上述的创建命令创建完后,会得到下面的关系图,由于 ServiceAccount 均为各自命名空间中的默认 ServiceAccount,因此若 Pod 的 pod.spec.serviceAccountName
没有指定的话,则默认使用其所在命名空间的 default
ServiceAccount。

在命名空间 foo
和 bar
中分别生成一个 Pod,均使用各自命名空间中的默认 ServiceAccount,那么正常情况下,这两个 Pod 将均能通过 API 服务器获得命名空间 foo
中的名为 test-service
的 Service 对象信息。在 Pod 中的测试命令如下(Pod 使用的是 luksa/kubectl-proxy 镜像,内部安装了 kubectl 组件):
curl localhost:8001/api/v1/namespaces/foo/services/test-service
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services \"test-service\" not found",
"reason": "NotFound",
"details": {
"name": "test-service",
"kind": "services"
},
"code": 404
}
从输出结果可以看出,提示的不是没有权限,而是 404 资源不存在,这是因为集群中并没有
test-service
这个资源对象,所以授权是成功的
Last updated
Was this helpful?