目录
-
RBAC API 概览
- Role and ClusterRole
- RoleBingding and ClusterRoleBingding
- Referring to Resources
- Aggregated ClusterRoles
- Referring to Subject
-
Default Roles and Role Bingdings
- Auto-reconciliation
- user-facing roles
-
Command-line Utilities
-
Service--Account Permissions
RBAC API 概览
在Kubernetes中,RBAC(基于角色的访问控制)。从1.6版本起,Kubernetes 默认启用RBAC(Role Base Access Control)访问控制策略。从1.8开始,RBAC已作为稳定的功能。通过设置–authorization-mode=RBAC,启用RABC。在RABC API中,通过如下的步骤进行授权:1)定义角色:在定义角色时会指定此角色对于资源的访问控制的规则;2)绑定角色:将主体与角色进行绑定,对用户进行访问授权。
![](https://img.haomeiwen.com/i11800123/9ae8d46af05f594c.png)
RBAC 权限定义部分主要有三个层级
apiGroups: 指定那个 API 组下的权限
resources: 该组下具体资源,如 pod namespace node
verbs: 指对该资源具体执行哪些动作 get list update delete
Role & ClusterRole
在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由命名空间(namespace)内的Role
对象定义,而整个Kubernetes集群范围内有效的角色则通过ClusterRole
对象实现。
role限定于单个namespace
一个Role
对象只能用于授予对某一单一命名空间中资源的访问权限。 以下示例描述了”default”命名空间中的一个Role对象的定义,用于授予对pod的读访问权限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # 空字符串""表明使用core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
Role:基础服务使用
ClusterRole
对象可以授予与Role
对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:
- 集群范围资源(例如节点,即node)
- 非资源类型endpoint(例如”/healthz”)
- 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod)
下面示例中的ClusterRole定义可用于授予用户对某一特定命名空间,或者所有命名空间中的secret(取决于其绑定方式)的读访问权限:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
# 鉴于ClusterRole是集群范围对象,所以这里不需要定义"namespace"字段
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding与ClusterRoleBinding
RoleBingding & ClusterRolerRoleBingding:角色绑定与集群角色绑定
角色绑定将一个角色中定义的各种权限授予一个或者一组用户。 角色绑定包含了一组相关主体(即subject, 包括用户——User、用户组——Group、或者服务账户——Service Account)以及对被授予角色的引用。 在命名空间中可以通过RoleBinding
对象授予权限,而集群范围的权限授予则通过ClusterRoleBinding
对象完成。
RoleBinding
可以引用在同一命名空间内定义的Role
对象。 下面示例中定义的RoleBinding
对象在”default”命名空间中将”pod-reader”角色授予用户”jane”。 这一授权将允许用户”jane”从”default”命名空间中读取pod。
# 以下角色绑定定义将允许用户"jane"从"default"命名空间中读取pod。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding
对象也可以引用一个ClusterRole
对象用于在RoleBinding
所在的命名空间内授予用户对所引用的ClusterRole
中 定义的命名空间资源的访问权限。这一点允许管理员在整个集群范围内首先定义一组通用的角色,然后再在不同的命名空间中复用这些角色。
例如,尽管下面示例中的RoleBinding
引用的是一个ClusterRole
对象,但是用户”dave”(即角色绑定主体)还是只能读取”development” 命名空间中的secret(即RoleBinding所在的命名空间)。
以下角色绑定允许用户"dave"读取"development"命名空间中的secret。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets
namespace: development # 这里表明仅授权读取"development"命名空间中的资源。
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
···
最后,可以使用ClusterRoleBinding在集群级别和所有命名空间中授予权限。下面示例中所定义的ClusterRoleBinding 允许在用户组”manager”中的任何用户都可以读取集群中任何命名空间中的secret。
···
# 以下`ClusterRoleBinding`对象允许在用户组"manager"中的任何用户都可以读取集群中任何命名空间中的secret。
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Referring to Resources
在Kubernets中,主要的资源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。另外,有些资源下面存在子资源,例如:Pod下就存在log子资源:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
下面的例子显示,“pod-and-pod-logs-reader”角色能够对“pods”和“pods/log”进行访问:
kind:Role
apiVersion:rbac.authorization.k8s.io/v1
metadata:
namespace:default
name:pod-and-pod-logs-reader
rules:
- apiGroups:[""]
resources:["pods","pods/log"]
verbs:["get","list"]
也可以通过 resourceName 指定单个资源(而不是一类资源)。如下Role指定的是对 my-configmap 这个cm的在namespace default里的 get和update 权限。
kind:Role
apiVersion:rbac.authorization.k8s.io/v1
metadata:
namespace:default
name:configmap-updater
rules:
- apiGroups:[""]
resources:["configmaps"]
resourceNames:["my-configmap"]
verbs:["update","get"]
注意,指定了单个资源后,verbs里就不能由 list, watch, create, or deletecollection 了,因为这几个verbs对应的API URL里不会出现resource name。
Aggregated ClusterRoles
1.9版本以后,可以用 aggregationRule 来聚合其他ClusterRole,从而创建一个新的具有更多权限的ClusterRole。聚合的方法是通过matchLabels(即rbac.example.com/aggregate-to-monitoring: "true"),来匹配所有metadata符合该label的ClusterRole。aggregationRule不需要配置 rules 段,它是由controller收集所有匹配的ClusterRole的rules后填充的。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Rules are automatically filled in by the controller manager.
注意,创建新的符合matchLabel的clusterRole,controller会将新的rules添加到aggregationRule。如下会将 monitoring-endpoints的rules添加到上面的ClusterRole monitoring。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
# These rules will be added to the "monitoring" role.
rules:
- apiGroups: [""]
Resources: ["services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]
默认的面向用户的role使用了aggregationRule。这样admin可以自动拥有 CustomResourceDefinitions CRD的权限。
如下,集群范围内的 ClusterRole admin会聚合所有label为rbac.authorization.k8s.io/aggregate-to-admin: "true"的ClusterRole,而 view 则会聚合所有label为rbac.authorization.k8s.io/aggregate-to-view: "true"的ClusterRole。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: view
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
例如下面这两个。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aggregate-cron-tabs-edit
labels:
# Add these permissions to the "admin" and "edit" default roles.
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aggregate-cron-tabs-view
labels:
# Add these permissions to the "view" default role.
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch"]
Referring to Subjects
RoleBinding、ClusterRoleBinding将Role、ClusterRole绑定到 subject。subject可以是 user,group,serviceAccount。
user:k8s并不管理user,而是authenticator(例如我们用的是dex)在管理。user可以是字符串(如”jane”),email(如bob@example.com),ID。这取决于管理员配置认证的时候,--oidc-username-claim配置的是什么。我们这里用的是name。system:开头的用户是保留给k8s用的。
group:group是由 Authenticator modules 在管理。可以是像user一样的普通group,也可以是 system:开头的k8s的组。
serviceaccount:由k8s管理。sa区别于user,其代表的是service,用来供service之间访问用,例如service A调用 service B的API,那么可以为service A创建一个 sa ,然后赋予该sa访问 service B API的权限。sa类似appid的概念。sa可以用 kubectl get sa来查看。
这里有一些RoleBinding的例子。注意group的两个例子。
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
---
# namespace qa下的sa
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
---
# 所有sa
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
---
# 所有已认证用户
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
---
# 所有未认证用户
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
# 所有用户
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
Default Roles and Role Bindings
API Server内置了若干clusterRole和clusterRoleBinding,一般是以system:开头,label为kubernetes.io/bootstrapping=rbac-defaults。尽量不要去修改他们,否则会引起系统级别的问题,因为可能某些服务会因为权限不足而无法正常运行。
Auto-reconciliation
万一不小心把上面的clusterRole或者clusterRoleBinding给改错了呢?API Master具备 Auto-reconciliation的功能,即,API Master每次重启的时候,都会重新恢复默认的clusterRole/ClusterRoleBiding。
如果确实要改,可以修改其rbac.authorization.kubernetes.io/autoupdate为false,这样API Server就不会恢复其默认值了。
user-facing roles
API Server还内置了一些不以system:开头的clusterRole。
cluster-admin:集群超级管理员。resources、verbs匹配全是 *
admin/edit/view:在某namespace中授权。
Command-line Utilities
除了按上面的编排文件来创建roleBiding/clusterRoleBinding,也可以用kubectl。举几个例子。
创建某一namespace下的roleBinding。
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
创建clusterRoleBiding。
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
相对来说kubectl更方便一些。
Service Account Permissions
默认RBAC不会给 kube-system 之外的sa授予权限。这里详细描述了权限管理从严格到宽松的各种sa授权方式。总之,管理越严格,管理员越忙。
网友评论