十二,k8s集群访问控制之RBAC

Posted peng-zone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十二,k8s集群访问控制之RBAC相关的知识,希望对你有一定的参考价值。

角色访问控制RBAC (Role-Based Access Control)

常用的授权插件:

  1. Node:节点认证
  2. ABAC:基于属性的访问控制
  3. RBAC:基于角色的访问控制
  4. Webhook:基于HTTP回调机制

RBAC控制:

技术图片

技术图片

RBAC 主要的功能是提供基于角色(Role)的访问控制许可(permission)

解释: 让一个用户扮演一个角色(Role),而角色(Role)拥有某些操作的权限,那么这么用户就拥有了该角色的操作权限。

所以说,之后的所有的操作许可,都是直接授权给角色(Role),而不是直接授权给用户。

对象
对象列表
虚拟对象,通常是URL,非对象资源,

对某个对象施加的一种行为,成为 Action。

role 和 clusterrole

在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由命名空间(namespace)内的Role对象定义,而整个Kubernetes集群范围内有效的角色则通过ClusterRole对象实现。

role中,定义对象和动作,决定此role的权限边界。
在role中,只能定义那些对象的动作被允许,不能定义决绝。
意思就是说,只要没有定义允许的,都会被拒绝。

角色分为两种:

1. role         名称空间级别角色
2. clusterrole  集群级别角色

rolebinding 和 clusterrolebinding

用于用户和角色之间的绑定关系。role和useraccount火service account之间的绑定

绑定分为两种:

1. rolebinding          名称空间界别的角色绑定,针对的边界是名称空间
2. clusterrolebinding   集群级别的基色绑定,针对的变边界是集群

问题: 当使用rolebinding 来对 user1 绑定 clusterrole,那么 user1 的权限是?

解答: user1 的权限还是局限于名称空间,因为使用的是 rolebinding 来绑定的,突破不来名称空间。

公共角色 clusterrole

常规做法

每个名称空间下,user都通过rolebinding绑定role,定义一个ClusterRole拥有集群级别的操作权限,通过ClusterRolebinding与user绑定,该用户user就有了集群级别的操作权限

便捷做法

假设再有多个pod情况下,如果此时定义好一个 clusterrole 集群角色和对应的权限,使用 Rolebinding 对集群角色 clusterrole 进行绑定,那么所有的名称空间都可以不用定义自己的 role ,直接使用 clusterrole即可。

以上几种关系的示意图

技术图片

user 创建测试

创建role案例

帮助:

[root@master ~]# kubectl create role --help
Create a role with single rule.

Examples:
  # Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
  kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
  
  # Create a Role named "pod-reader" with ResourceName specified
  kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
  
  # Create a Role named "foo" with API Group specified
  kubectl create role foo --verb=get,list,watch --resource=rs.extensions
  
  # Create a Role named "foo" with SubResource specified
  kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
  1. 通过 --dry-run 参数,使命令不是真正执行,只是模拟测试命令是否正常。
  2. 通过 -o yaml 以 yaml 格式输出

那么下面使用这两个参数,导出一个 yaml 格式的文件。

[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run
role.rbac.authorization.k8s.io/pods-reader created (dry run)
[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master rbac]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml
[root@master rbac]# ll
total 4
-rw-r--r-- 1 root root 193 Aug 21 16:56 role-demo.yaml
[root@master rbac]# cat role-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

创建 role

[root@master rbac]# kubectl apply -f role-demo.yaml 
role.rbac.authorization.k8s.io/pods-reader created
[root@master rbac]# kubectl get role
NAME          AGE
pods-reader   2s
[root@master rbac]# kubectl describe role pods-reader
Name:         pods-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"default"},"rules...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]    # 这里显示的权限等详细信息

在之前创建了一个用户 jerry,此时就可以来绑定刚刚创建的role了。

rolebinding 绑定 jerry用户

使用相同的方式:

[root@master rbac]# kubectl create rolebinding jerry-read-pods --role=pods-reader --user=jerry --dry-run -o yaml > rolebinding-demo.yaml
[root@master rbac]# cat rolebinding-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: jerry-read-pods
roleRef:            #  表示引用那个角色(role)
  apiGroup: rbac.authorization.k8s.io
  kind: Role            #表示绑定角色为role
  name: pods-reader     # 绑定的role名称
subjects:               # 绑定的用户账号
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: jerry           # 绑定的具体用户名

创建:

[root@master rbac]# kubectl apply -f rolebinding-demo.yaml 
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created
[root@master rbac]# kubectl get rolebinding
NAME              AGE
jerry-read-pods   5s
[root@master rbac]# kubectl describe rolebinding/jerry-read-pods
Name:         jerry-read-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name":"jerry-read...
Role:
  Kind:  Role
  Name:  pods-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  jerry

测试 jerry 权限

此时切换到 jerry 用户下进行测试权限:

[root@master rbac]# kubectl config use-context jerry@kubernetes
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d3h
[root@master rbac]# kubectl delete pods/pod-sa-demo
Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "jerry" cannot delete resource "pods" in API group "" in the namespace "default"
[root@master rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system"

从上面演示可以看出,只有查看名称空间为default 的权限,没有其它等删除的权限,也查看不来其它名称空间的资源。

clusterrole 测试

定义方式和 role 几乎相同,查看帮助如下:

[root@master ~]# kubectl create clusterrole --help
Create a ClusterRole.

Examples:
  # Create a ClusterRole named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
  kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
  
  # Create a ClusterRole named "pod-reader" with ResourceName specified
  kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod
--resource-name=anotherpod
  
  # Create a ClusterRole named "foo" with API Group specified
  kubectl create clusterrole foo --verb=get,list,watch --resource=rs.extensions
  
  # Create a ClusterRole named "foo" with SubResource specified
  kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
  
  # Create a ClusterRole name "foo" with NonResourceURL specified
  kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
  
  # Create a ClusterRole name "monitoring" with AggregationRule specified
  kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"

创建 clusterrole

[root@master rbac]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > clusterrole-demo.yaml
[root@master rbac]# cat clusterrole-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master rbac]# kubectl apply -f clusterrole-demo.yaml 
clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@master rbac]# kubectl describe clusterrole/cluster-reader
Name:         cluster-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"creationTimestamp":null,"name":"cluster-re...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

测试绑定jerry用户

之前jerry绑定了一个role,此时需要把这个rolebinding删除,然后在绑定clusterrole

[root@master rbac]# kubectl create clusterrolebinding jerry-read-all-pods --clusterrole=cluster-reader --user=jerry --dry-run -o yaml > clusterrolebinding-demo.yaml
[root@master rbac]# cat clusterrolebinding-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: jerry-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: jerry
[root@master rbac]# kubectl apply -f clusterrolebinding-demo.yaml 
clusterrolebinding.rbac.authorization.k8s.io/jerry-read-all-pods created
[root@master rbac]# kubectl describe clusterrolebinding/jerry-read-all-pods
Name:         jerry-read-all-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name"...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  jerry

测试jerry权限

切换至 jerry,然后进行访问测试:

[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d4h
[root@master rbac]# kubectl get pods -n kube-system
NAME                                        READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-8mzfz                    1/1     Running   0          43d
coredns-5c98db65d4-spjx8                    1/1     Running   0          43d
etcd-master.kubernetes                      1/1     Running   0          43d
kube-apiserver-master.kubernetes            1/1     Running   0          43d
kube-controller-manager-master.kubernetes   1/1     Running   0          43d
kube-flannel-ds-amd64-4szk7                 1/1     Running   0          43d
kube-flannel-ds-amd64-b4ssp                 1/1     Running   1          43d
kube-flannel-ds-amd64-nmklz                 1/1     Running   0          43d
kube-flannel-ds-amd64-wjczq                 1/1     Running   0          43d
kube-proxy-8fqsz                            1/1     Running   0          43d
kube-proxy-bkrw4                            1/1     Running   0          43d
kube-proxy-n75g8                            1/1     Running   1          43d
kube-proxy-rmckk                            1/1     Running   0          43d
kube-scheduler-master.kubernetes            1/1     Running   0          43d
kubernetes-dashboard-7d75c474bb-8kzrl       1/1     Running   0          9d
[root@master rbac]# kubectl get service
Error from server (Forbidden): services is forbidden: User "jerry" cannot list resource "services" in API group "" in the namespace "default"
[root@master rbac]# kubectl get service -n kube-system
Error from server (Forbidden): services is forbidden: User "jerry" cannot list resource "services" in API group "" in the namespace "kube-system"

从上面测试可以看出:

  1. 可以访问default名称空间的pods资源,但不能访问service资源。
  2. 可以访问 kube-system 名称空间的资源, 也不能访问 kube-system 名称空间 service资源。

测试rolebinding绑定clusterrole

先删除jerry刚刚binding的clusterrolebinding

[root@master rbac]# kubectl delete -f clusterrolebinding-demo.yaml 
clusterrolebinding.rbac.authorization.k8s.io "jerry-read-all-pods" deleted
[root@master rbac]# kubectl config use-context jerry@kubernetes
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "default"

可以看到,删除clusterrolebinding后,jerry用户没有get权限。

下面使用rolebinding绑定clusterrole

[root@master rbac]# kubectl create rolebinding jerry-read-pods --clusterrole=cluster-reader --user=jerry --dry-run
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created (dry run)
[root@master rbac]# kubectl create rolebinding jerry-read-pods --clusterrole=cluster-reader --user=jerry --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
[root@master rbac]# cat rolebinding-clusterrole-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding                           # 这里的类型是rolebinding
metadata:
  name: jerry-read-pods
  namespace: default                        # 编辑增加可访问的名称空间
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole                         # 而这里绑定的是clusterrole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: jerry                               # 绑定的用户
[root@master rbac]# kubectl apply -f rolebinding-clusterrole-demo.yaml 
rolebinding.rbac.authorization.k8s.io/jerry-read-pods created

测试访问

[root@master rbac]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d19h
[root@master rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system"

测试只能访问 default 名称空间的资源,而不能访问其他名称空间的资源。

clusterrole admin 默认角色

在clusterrole 中,有两个默认的admin角色,admin、cluster-admin

这两个都是集群角色的管理员,那么当集群中有多个名称空间的时候,就不需要手动去创建管理员角色,直接可以使用admin的角色机型rolebinding,这样省去了很多重复工作。

测试绑定

测试把 clusterrole 的 admin 角色绑定到 jerry 用户上。

之前已经绑定了一个clusterrole,此时再次绑定,不受影响,相当于一人身兼多职。

[root@master rbac]# kubectl create rolebinding defult-ns-admin --clusterrole=admin --user=jerry
rolebinding.rbac.authorization.k8s.io/defult-ns-admin created
[root@master rbac]# kubectl config use-context jerry@kubernetes         # 切换到jerry用户
Switched to context "jerry@kubernetes".
[root@master rbac]# kubectl get pods                                    # 能够读
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          5d20h
[root@master rbac]# kubectl delete pods pod-sa-demo
pod "pod-sa-demo" deleted                                               # 删除成功
[root@master rbac]# kubectl get pods
No resources found.
[root@master rbac]# kubectl get pods -n kube-system                     # 但这里不能访问其他名称空间
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "kube-system" 

以上是关于十二,k8s集群访问控制之RBAC的主要内容,如果未能解决你的问题,请参考以下文章

k8s APIserver 安全机制之 rbac 授权

十二 K8S细粒度权限控制

干货 | K8S 1.6新增特性之RBAC

k8s安全框架-rbac授权--网络访问限制

在kubernetes 集群内访问k8s API服务

Kubernetes访问控制之RBAC