一 RBAC介绍
1.1 RBAC授权
基于角色的访问控制(RBAC)是一种基于个人用户的角色来管理对计算机或网络资源的访问的方法。
RBAC使用rbac.authorization.k8s.io API组来推动授权决策,允许管理员通过Kubernetes API动态配置策略。
使用--authorization-mode=RBAC开启RBAC授权模块功能。
RBAC API定义了四个资源对象用于描述RBAC中用户和资源之间的连接权限:
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
二 RBAC详解
2.1 Role 和 ClusterRole
RBAC API声明了四种类型。
在RBAC API中,角色包含表示一组权限的规则。权限都是叠加的,没有deny规则(没有“拒绝”规则)。可以使用参数role在一个namespace中定义一个普通角色,或者在集群范围内使用ClusterRole定义集群角色。
一个Role只能用于授予对单个命名空间内的资源的访问权限。
示例1:在“default”命令空间中定义了一个名为“pod-reader”的角色,此角色能够对在“default”命名空间中访问Pod。
1 [root@k8smaster01 study]# vi pod-reader-Role.yaml 2 apiVersion: rbac.authorization.k8s.io/v1 3 kind: Role 4 metadata: 5 namespace: default 6 name: pod-reader 7 rules: 8 - apiGroups: [""] # "" indicates the core API group 9 resources: ["pods"] #资源类型 10 verbs: ["get", "watch", "list"] #操作类型
解释:名为pod-reader的角色授予对“default”命名空间中的pod的读取权限。
一个ClusterRole可用于授予与一个Role相同的权限,同时由于它们是群集范围的,因此它们还可用于授予对以下内容的访问权限:
- 集群范围的资源(如nodes);
- non-resource endpoints(如“/healthz”);
- 跨所有命名空间(可通过kubectl get pods --all-namespaces查看)的命名空间资源(如pods)。
示例2:
1 [root@k8smaster01 study]# vi secret-reader-ClusterRole.yaml 2 apiVersion: rbac.authorization.k8s.io/v1 3 kind: ClusterRole 4 metadata: 5 # 因为ClusterRoles是针对所有命名空间,因此省略了“命名空间”。 6 name: secret-reader 7 rules: 8 - apiGroups: [""] 9 resources: ["secrets"] #资源类型 10 verbs: ["get", "watch", "list"] #操作类型
解释:名为secret-reader的ClusterRole,授予对所有命名空间中的secrets资源的读访问权限。
2.2 RoleBinding 和 ClusterRoleBinding
角色绑定用于将角色与一个或一组用户进行绑定,从而实现将对用户进行授权的目的。它包含由(用户)users、groups(组)、或service accounts(服务帐户)组成的列表。
角色绑定也分为普通角色绑定和集群角色绑定。
集群角色是跨命名空间的,但普通角色有命名空间属性,因此普通角色绑定只能引用同一个命名空间下的角色。
示例1:普通角色绑定示例。
1 kind: RoleBinding 2 apiVersion: rbac.authorization.k8s.io/v1 3 metadata: 4 name: read-pods 5 namespace: default #普通角色绑定指定namespace 6 subjects: #主体参数 7 - kind: User #指定主体类型为user 8 name: jane #指定user用户名 9 apiGroup: rbac.authorization.k8s.io 10 roleRef: #角色引用 11 kind: Role #类型为普通角色 12 name: pod-reader #角色名 13 apiGroup: rbac.authorization.k8s.io
解释:在“default”命名空间中,角色绑定将用户“jane”和“pod-reader”的普通角色进行绑定,从而授予“jane”具有在“default”命名空间的“pod-reader”的普通角色所定义的相应权限。如2.1示例所创建的“pod-reader”的普通角色权限为:对“default”命名空间中的pod的具有读取权限。
普通角色绑定也可以通过引用集群角色授予访问权限,当需要主体对资源的访问仅限与本命名空间。
则可以定义整个集群的公共角色集合(将相应的权限追加的一个集合所形成的集群角色),然后在多个命名空间中进行复用。
示例2:使用普通角色绑定绑定集群角色,并指明特定的命名空间。
1 [root@k8smaster01 study]# vi dave_RoleBinding.yaml 2 kind: RoleBinding 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 name: read-secrets 6 namespace: development #指定特定的命名空间 7 subjects: #主体参数 8 - kind: User #指定主体类型为user 9 name: dave #指定user用户名 10 apiGroup: rbac.authorization.k8s.io 11 roleRef: #角色引用 12 kind: ClusterRole #类型为集群角色 13 name: secret-reader #角色名 14 apiGroup: rbac.authorization.k8s.io
解释:如上的普通角色绑定,实现允许名为dave的user主体,在development的命名空间中,具有名为secret-reader的集群角色的所有权限。即普通角色绑定引用的实体为集群角色,但也只能访问特定命名空间(如上为development)的secrets资源。
集群角色绑定可以被用来在集群层面和整个命名空间进行授权,即实现集群角色在集群层面的授权。
示例3:允许在“manager”组的用户能够访问所有命名空间中的secrets资源。
1 [root@k8smaster01 study]# vi manager_ClusterRoleBinding.yaml 2 kind: ClusterRoleBinding 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 name: read-secrets-global 6 subjects: #主体参数 7 - kind: Group #指定主体类型为group 8 name: manager #指定group组名 9 apiGroup: rbac.authorization.k8s.io 10 roleRef: #角色引用 11 kind: ClusterRole #类型为集群角色 12 name: secret-reader #角色名 13 apiGroup: rbac.authorization.k8s.io
2.3 默认角色
API服务器创建了一组默认ClusterRole和ClusterRoleBinding对象。其中格式为system:前缀的表示该资源由系统基础设施所拥有。手动修改该类资源可能导致集群功能异常,若system:node的ClusterRole,定义了kubelet的权限。
提示:所有默认群集角色和角色绑定都标有kubernetes.io/bootstrapping=rbac-defaults。
三 资源与主体
3.1 资源介绍
在Kubernets中,主要的资源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。
同时,有些资源下面存在子资源,例如:Pod下就存在log子资源。
示例1:普通角色的资源列表。
1 [root@k8smaster01 study]# vi pod-and-pod_log.yaml 2 kind: Role 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 namespace: default 6 name: pod-and-pod-logs-reader 7 rules: 8 - apiGroups: [""] 9 resources: ["pods","pods/log"] 10 verbs: ["get","list"]
解释:如上限定在default的命名空间的名为pod-and-pod-logs-reader的普通角色,对pod和pods/log资资源就有get和list的权限。
示例2:更精细粒度的资源控制,可通过resourceNamess指定特定的资源实例,以限制角色只能够对具体的某个实例进行访问控制。
1 [root@k8smaster01 study]# vi updater_configmap.yaml 2 kind: Role 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 namespace: default 6 name: configmap-updater 7 rules: 8 - apiGroups: [""] 9 resources: ["configmaps"] 10 resourceNames: ["my-configmap"] 11 verbs: ["update","get"]
解释:如上限定在default的命名空间的名为configmap-updater的普通角色,对名为my-configmap的configmaps类型的特定资源,具有update和get权限。
3.2 主体介绍
RBAC授权中的主体可以是组,用户或者服务帐户。用户通过字符串表示,比如“alice”、“bob@example.com”等,具体的形式取决于管理员在认证模块中所配置的用户名。
system: 被保留作为用来Kubernetes系统内部使用,因此不能作为用户的前缀。组也有认证模块提供,格式与用户类似。
示例1:类型为user(用户)。
1 subjects: 2 - kind: User 3 name: "alice@example.com" 4 apiGroup: rbac.authorization.k8s.io
示例2:类型为group(组)。
1 subjects: 2 - kind: Group 3 name: "frontend-admins" 4 apiGroup: rbac.authorization.k8s.io
示例3:查看default的服务账户。
1 subjects: 2 - kind: ServiceAccount 3 name: default 4 namespace: kube-system
示例4:设置所有qa命名空间的服务账户。
1 subjects: 2 - kind: Group 3 name: system:serviceaccounts:qa 4 apiGroup: rbac.authorization.k8s.io
示例5:设置所有命名空间的所有服务账户。
1 subjects: 2 - kind: Group 3 name: system:serviceaccounts 4 apiGroup: rbac.authorization.k8s.io
示例6:所有被认证的用户。
1 subjects: 2 - kind: Group 3 name: system:authenticated 4 apiGroup: rbac.authorization.k8s.io
示例7:所有未被认证的用户。
1 subjects: 2 - kind: Group 3 name: system:unauthenticated 4 apiGroup: rbac.authorization.k8s.io
示例8:所有用户。
1 subjects: 2 - kind: Group 3 name: system:authenticated 4 apiGroup: rbac.authorization.k8s.io 5 - kind: Group 6 name: system:unauthenticated 7 apiGroup: rbac.authorization.k8s.io
四 角色相关命令
4.1 创建角色
[root@master ~]# kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
解释:创建一个名为“pod-reader”的Role,允许用户在pod上执行“get”,“watch”和“list”。
[root@master ~]# kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --namespace=anotherpod
解释:创建一个指定了namespace为anotherpod的名为“pod-reader”的Role,对资源名为readablepod的pod具有get权限。
[root@master ~]# kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
解释:创建一个role名为“foo”的Role,允许用户在replicasets.apps上执行“get”,“watch”和“list”。
[root@master ~]# kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
解释:创建一个role名为“foo”的Role,允许用户在pods及pods/status子资源上上执行“get”,“watch”和“list”。
4.2 创建集群角色
[root@master ~]# kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
解释:创建一个名为“pod-reader”的clusterrole,允许集群角色在pod上执行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --namespace=anotherpod
解释:创建一个指定了namespace为anotherpod的名为“pod-reader”的Rclusterrole,对资源名为readablepod的pod具有get权限。
[root@master ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
解释:创建一个clusterrole名为“foo”的clusterrole,允许集群角色在replicasets.apps上执行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
解释:创建一个clusterrole名为“foo”的clusterrole,允许集群角色在pods及pods/status子资源上上执行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
解释:创建一个clusterrole名为“foo”的clusterrole,指定了non-resource为/logs/*的“get”权限。
4.3 权限和角色绑定
[root@master ~]# kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
解释:在acme的namespace中,将admin的clusterrole和bob用户进行绑定。
[root@master ~]# kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
解释:在acme的namespace中,将view的clusterrole和myapp服务账号进行绑定。
[root@master ~]# kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
解释:在acme的namespace中,将view的clusterrole和myapp的namespace中的服务账号进行绑定。
4.4 权限和集群角色绑定
[root@master ~]# kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
解释:在整个集群中,将cluster-admin的clusterrole和root用户进行绑定。
[root@master ~]# kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
解释:在整个集群中,将system:node-proxier的clusterrole和system:kube-proxy用户进行绑定。
[root@master ~]# kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
解释:在整个集群中,将view的clusterrole和myapp中的acme服务账户进行绑定。
提示:roles和clusterroles的区别在于roles只能对某个命令空间内的资源定义权限。而集群角色定义的权限都是针对整个集群的命名空间的。
更多RBAC参考:https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole
4.5 相关对比
ClusterRole和ClusterRoleBinding是针对整个Cluster范围内有效的,无论用户或资源所在的namespace是什么;
Role和RoleBinding的作用范围是局限在某个k8s namespace中的。
kubernetes在安装之初就已经生成了许多role、rolebinding、clusterrole和clusterrolebinding,它们也是属于kubernetes资源的一部分,可通过get、describe等命令查看,如下:
[root@master ~]# kubectl get role -n kube-system
[root@master ~]# kubectl describe role extension-apiserver-authentication-reader -n kube-system
五 服务账户权限
5.1 服务账户
默认情况下,RBAC策略授予控制板组件、Node和控制器作用域的权限,但是未授予“kube-system”命名空间外服务帐户的访问权限。同时允许管理员按照需要将特定角色授予服务帐户。
5.2 服务账号授权
- 授予角色给一个指定Pod的服务帐户
需要在Pod规格中指定serviveAccountName,同时此服务帐户已被创建(通过API、kubectl create serviceaccount等已经成功创建)。
示例1:在“my-namespace”命名空间内,授予”my-sa”服务帐户“view”集群角色。
1 kubectl create rolebinding my-sa-view 2 --clusterrole=view 3 --serviceaccount=my-namespace:my-sa 4 --namespace=my-namespace
- 在一个命名空间授予“view”集群角色给“default”服务帐户
如果Pod没有指定serviceAccountName,它将使用”default” 服务帐户。
示例2:在“my-namespace”命名空间内,授予”default”服务帐户“view”集群角色
1 kubectl create rolebinding default-view 2 --clusterrole=view 3 --serviceaccount=my-namespace:default 4 --namespace=my-namespace
提示:在”kube-system“命名空间中,很多插件作为”default“服务帐户进行运行。为了允许default能访问这些插件,在“kube-system”命名空间中授予”cluster-admin“角色给”default”帐户。
1 kubectl create clusterrolebinding add-on-cluster-admin 2 --clusterrole=cluster-admin 3 --serviceaccount=kube-system:default
- 在一个命名空间中,授予角色给所有的服务帐户
如果希望在一个命名空间中的所有Pod都拥有一个角色,而不管它们所使用的服务帐户,可以授予集群角色给服务帐户组。
示例3:在“my-namespace”命名空间中,将”view“集群角色授予“system:serviceaccounts:my-namespace“组。
1 kubectl create rolebinding serviceaccounts-view 2 --clusterrole=view 3 --group=system:serviceaccounts:my-namespace 4 --namespace=my-namespace
- 在整个集群中授予一个角色给所有的服务帐户 (不推荐)
如果不想按照每个命名空间管理权限,可以在整个集群的访问进行授权。
示例4:在整个集群层面,将”view“集群角色授予“sytem:serviceaccounts“。
1 kubectl create clusterrolebinding serviceaccounts-view 2 --clusterrole=view 3 --group=system:serviceaccounts
- 在整个集群中授予超级用户访问所有的服务帐户 (强烈不推荐)
如果对访问权限不太重视,可以授予超级用户访问所有的服务帐户。
1 kubectl create clusterrolebinding serviceaccounts-cluster-admin 2 --clusterrole=cluster-admin 3 --group=system:serviceaccounts
- 宽松的RBAC权限(致命危险)
下面的策略允许所有的服务帐户作为集群管理员。在容器中运行的Pod将自动的收取到服务帐户证书,并执行所有的API行为。包括查看保密字典恩将和修改权限,这是不被推荐的访问策略。
1 kubectl create clusterrolebinding permissive-binding 2 --clusterrole=cluster-admin 3 --user=admin 4 --user=kubelet 5 --group=system:serviceaccounts
参考:https://www.cnblogs.com/linuxk/p/9772117.html
http://docs.kubernetes.org.cn/148.html
https://www.kubernetes.org.cn/4062.html