kubernetes(19):k8s基于RBAC的授权
K8s基于RBAC的授权
https://www.cnblogs.com/wzlinux/p/10159467.html#kubectl-create-clusterrolebinding
https://www.cnblogs.com/panwenbin-logs/p/10046572.html
https://www.cnblogs.com/linuxk/p/9772117.html
https://www.kubernetes.org.cn/4062.html
基本上都是参考这几篇
1 RBAC简介
在Kubernetes中,授权有ABAC(基于属性的访问控制)、RBAC(基于角色的访问控制)、Webhook(基于http回调机制的访问控制)、Node(节点认证)、AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式。
RBAC(Role-Based Access Control,基于角色的访问控制)在k8s v1.5中引入,在v1.6版本时升级为Beta版本,并成为kubeadm安装方式下的默认选项,相对于其他访问控制方式,新的RBAC具有如下优势:
- 对集群中的资源和非资源权限均有完整的覆盖
整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作
可以在运行时进行调整,无需重启API Server
要使用RBAC授权模式,需要在API Server的启动参数中加上--authorization-mode=RBAC
在RABC API中,通过如下的步骤进行授权:
定义角色:在定义角色时会指定此角色对于资源的访问控制的规则;
绑定角色:将主体与角色进行绑定,对用户进行访问授权。
基于角色的访问控制(Role-Based Access Control, 即”RBAC”)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过Kubernetes API动态配置策略。
在k8s的授权机制当中,采用RBAC的方式进行授权,其工作逻辑是 把对对象的操作权限定义到一个角色当中,再将用户绑定到该角色,从而使用户得到对应角色的权限。此种方式仅作用于名称空间当中,这是什么意思呢?当User1绑定到Role角色当中,User1就获取了对该NamespaceA的操作权限,但是对NamespaceB是没有权限进行操作的,如get,list等操作。
另外,k8s为此还有一种集群级别的授权机制,就是定义一个集群角色(ClusterRole),对集群内的所有资源都有可操作的权限,从而将User2,User3通过ClusterRoleBinding到ClusterRole,从而使User2、User3拥有集群的操作权限。Role、RoleBinding、ClusterRole和ClusterRoleBinding的关系如下图:
1.1 角色和集群角色
在RBAC API中,角色包含代表权限集合的规则。在这里,权限只有被授予,而没有被拒绝的设置。在Kubernetes中有两类角色,即普通角色和集群角色。可以通过Role定义在一个命名空间中的角色,或者可以使用ClusterRole定义集群范围的角色。一个角色只能被用来授予访问单一命令空间中的资源。
下面是在“default”命令空间中定义了一个名为“pod-reader”的角色,此角色能够对在“default”命名空间中访问Pod:
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
集群角色(ClusterRole)能够被授予如下资源的权限:
- 集群范围的资源(类似于Node)
- 非资源端点(类似于”/healthz”)
- 集群中所有命名空间的资源(类似Pod)
下面是授予集群角色读取秘密字典文件访问权限的例子:
kind:ClusterRole apiVersion:rbac.authorization.k8s.io/v1 metadata: # "namespace" omitted since ClusterRoles are not namespaced name:secret-reader rules: - apiGroups:[""] resources:["secrets"] #明确资源类型 verbs:["get","watch","list"]
1.2 角色绑定和集群角色绑定
角色绑定用于将角色与一个或一组用户进行绑定,从而实现将对用户进行授权的目的。主体分为用户、组和服务帐户。角色绑定也分为角色普通角色绑定和集群角色绑定。角色绑定只能引用同一个命名空间下的角色。
在下面的例子中,在”default”命名空间中角色绑定将‘jane’用户和“pod-reader”角色进行了绑定,这就授予了“jane”能够访问“default”命名空间下的Pod。
# This role binding allows "jane" to read pods in the "default" namespace. kind:RoleBinding apiVersion:rbac.authorization.k8s.io/v1 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
角色绑定也可以通过引用集群角色授予访问权限,当主体对资源的访问仅限与本命名空间,这就允许管理员定义整个集群的公共角色集合,然后在多个命名空间中进行复用。例如,下面的角色绑定引用了集群角色,但是“dave”用户也仅仅只能读取“development”命名空间中的secrets资源:
# This role binding allows "dave" to read secrets in the "development" namespace. kind:RoleBinding apiVersion:rbac.authorization.k8s.io/v1 metadata: name:read-secrets namespace:development# This only grants permissions within the "development" namespace. subjects: - kind:User name:dave apiGroup:rbac.authorization.k8s.io roleRef: kind:ClusterRole name:secret-reader apiGroup:rbac.authorization.k8s.io
集群角色可以被用来在集群层面和整个命名空间进行授权。下面的示例允许在“manager”组的用户能够访问所有命名空间中的保密字典资源。
# This role binding allows "dave" to read secrets in the "development" namespace. kind:RoleBinding apiVersion:rbac.authorization.k8s.io/v1 metadata: name:read-secrets namespace:development# This only grants permissions within the "development" namespace. subjects: - kind:User name:dave apiGroup:rbac.authorization.k8s.io roleRef: kind:ClusterRole name:secret-reader apiGroup:rbac.authorization.k8s.io
1.3 资源
在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"]
也可以通过resourceNamess指定特定的资源实例,以限制角色只能够对实例进行访问控制:
kind:Role apiVersion:rbac.authorization.k8s.io/v1 metadata: namespace:default name:configmap-updater rules: - apiGroups:[""] resources:["configmaps"] resourceNames:["my-configmap"] verbs:["update","get"]
1.4 主体
RBAC授权中的主体可以是组,用户或者服务帐户。用户通过字符串表示,比如“alice”、 “bob@example.com”等,具体的形式取决于管理员在认证模块中所配置的用户名。system:被保留作为用来Kubernetes系统使用,因此不能作为用户的前缀。组也有认证模块提供,格式与用户类似。
在角色绑定主体的例子:
名称为 “alice@example.com”用户:
subjects: - kind:User name:"alice@example.com" apiGroup:rbac.authorization.k8s.io
名称为“frontend-admins”的组:
subjects: - kind:User name:"alice@example.com" apiGroup:rbac.authorization.k8s.io
在kube-system命名空间中,名称为“default”的服务帐户:
subjects: - kind:ServiceAccount name:default namespace:kube-system
在“qa”命名空间中,所有的服务帐户:
subjects: - kind:Group name:system:serviceaccounts:qa apiGroup:rbac.authorization.k8s.io
所有的服务帐户:
subjects: - kind:Group name:system:serviceaccounts apiGroup:rbac.authorization.k8s.io
所有被认证的用户 (version 1.5+):
subjects: - kind:Group name:system:authenticated apiGroup:rbac.authorization.k8s.io
所有未被认证的用户 (version 1.5+):
subjects: - kind:Group name:system:authenticated apiGroup:rbac.authorization.k8s.io
所有用户(version 1.5+):
subjects: - kind:Group name:system:authenticated apiGroup:rbac.authorization.k8s.io - kind:Group name:system:unauthenticated apiGroup:rbac.authorization.k8s.io
2 简单示例
2.1 User --> Rolebinding --> Role
使用RoleBanding将用户绑定到Role
一个Role对象只能用于授予对某一单一命名空间中资源的访问权限
2.1.1 查看命令帮助及格式
[root@k8s-master ~]# 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@k8s-master ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml [root@k8s-master ~]#
2.1.2 创建role
[root@k8s-master ~]# kubectl apply -f role-demo.yaml Error from server (Forbidden): error when retrieving current configuration of: Resource: "rbac.authorization.k8s.io/v1, Resource=roles", GroupVersionKind: "rbac.authorization.k8s.io/v1, Kind=Role" Name: "pods-reader", Namespace: "default" Object: &{map["apiVersion":"rbac.authorization.k8s.io/v1" "kind":"Role" "metadata":map["annotations":map["kubectl.kubernetes.io/last-applied-configuration":""] "creationTimestamp":<nil> "name":"pods-reader" "namespace":"default"] "rules":[map["apiGroups":[""] "resources":["pods"] "verbs":["get" "list" "watch"]]]]} from server for: "role-demo.yaml": roles.rbac.authorization.k8s.io "pods-reader" is forbidden: User "wx" cannot get resource "roles"in API group "rbac.authorization.k8s.io" in the namespace "default" [root@k8s-master ~]# echo $? 1 #这里是提示,我的用户没权限,我这里是wx,需要切一下service account [root@k8s-master ~]# kubectl config use-context kubernetes-admin@kubernetes Switched to context "kubernetes-admin@kubernetes". [root@k8s-master ~]# kubectl get role NAME AGE leader-locking-nfs-client-provisioner 4d [root@k8s-master ~]# kubectl apply -f role-demo.yaml role.rbac.authorization.k8s.io/pods-reader created [root@k8s-master ~]# [root@k8s-master ~]# kubectl get role #查看role的信息 NAME AGE leader-locking-nfs-client-provisioner 4d pods-reader 14s [root@k8s-master ~]# kubectl describe role pods-reader #查看pods-reader 的详细信息 Name: pods-reader Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"creationTimestamp":null,"name":"pods-reader","nam... PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch] #Resources:资源类别,表示对该资源类别下的所有资源进行操作 #Non-Resource URLs:非资源URL,对某些资源进行某种特殊操作的存在 #Resource Names:对资源类别下某个或多个资源进行操作 #Verbs:操作的类型
2.1.3 创建RoleBinding,绑定用户
将用户wx(该用户在上一章节serviceaccount中已经被创建)绑定到pods-reader 这个role上去
[root@k8s-master ~]# kubectl create rolebinding wx-read-pods --role=pods-reader --user=wx --dry-run -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: wx-read-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pods-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wx [root@k8s-master ~]# kubectl create rolebinding wx-read-pods --role=pods-reader --user=wx --dry-run -o yaml > wx-role.yaml [root@k8s-master ~]# kubectl create -f wx-role.yaml rolebinding.rbac.authorization.k8s.io/wx-read-pods created [root@k8s-master ~]# kubectl describe rolebindings.rbac.authorization.k8s.io wx-read-pods Name: wx-read-pods Labels: <none> Annotations: <none> Role: Kind: Role Name: pods-reader Subjects: Kind Name Namespace ---- ---- --------- User wx [root@k8s-master ~]#
2.1.4 验证绑定
[root@k8s-master ~]# kubectl config use-context wx@kubernetes Switched to context "wx@kubernetes". [root@k8s-master ~]# kubectl get pods #获取当前名称空间的pod信息,可以看到能够正常显示 NAME READY STATUS RESTARTS AGE sa-demo 1/1 Running 0 3h40m [root@k8s-master ~]# kubectl get pods -n kube-system #查看其它空间pod的信息,可以看到提示没有权限,即验证RoleBanding的权限只对当前的名称空间生效 Error from server (Forbidden): pods is forbidden: User "wx" cannot list resource "pods" in API group "" in the namespace "kube-system" [root@k8s-master ~]# kubectl get role Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden: User "wx" cannot list resource "roles" in API group "rbac.authorization.k8s.io" in the namespace "default" [root@k8s-master ~]#
2.2 User --> ClusterRolebinding --> ClusterRole
使用ClusterRoleBanding将用户绑定到ClusterRole上
对用户wx进行集群角色绑定,用户将会获取对集群内所有资源的对应权限。
clusterrole定义
ClusterRole
对象可以授予与Role
对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:
- 集群范围资源(例如节点,即node)
- 非资源类型endpoint(例如”/healthz”)
- 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令
kubectl get pods --all-namespaces
来查询集群中所有的pod)
2.2.1 创建一个ClusterRole
[root@k8s-master ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-runapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: cluster-reader # #ClusterRole属于集群级别,所有不可以定义namespace rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch [root@k8s-master ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run > clusterrole-cluster.yaml [root@k8s-master ~]# kubectl apply -f clusterrole-cluster.yaml clusterrole.rbac.authorization.k8s.io/cluster-reader configured [root@k8s-master ~]# [root@k8s-master ~]# useradd admin useradd:用户“admin”已存在 [root@k8s-master ~]# cp -rp ~/.kube/ /home/admin [root@k8s-master ~]# chown -R admin:admin /home/admin [root@k8s-master ~]# su - admin 上一次登录:一 9月 9 14:32:54 CST 2019从 10.6.76.27pts/0 上 [admin@k8s-master ~]$ kubectl config use-context wx@kubernetes Switched to context "wx@kubernetes". [admin@k8s-master ~]$ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://10.6.76.25:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: wx name: wx@kubernetes current-context: wx@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED - name: wx user: client-certificate-data: REDACTED client-key-data: REDACTED [admin@k8s-master ~]$
2.2.2 创建一个ClusterRoleBinding,将用户wx绑定到cluster-reader这个ClusterRole上面去
[root@k8s-master ~]# kubectl create clusterrolebinding wx-read-all-pods --clusterrole=cluster-reader --user=wx --dry-run -o yamlapiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: creationTimestamp: null name: wx-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wx [root@k8s-master ~]# kubectl create clusterrolebinding wx-read-all-pods --clusterrole=cluster-reader --user=wx --dry-run -o yaml > clusterrolebinding-demo.yaml [root@k8s-master ~]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/wx-read-all-pods created [root@k8s-master ~]# kubectl get clusterrolebindings.rbac.authorization.k8s.io |grep wx wx-read-all-pods 19s [root@k8s-master ~]#
2.2.3 验证
#切换到admin用户终端下
[admin@k8s-master ~]$ kubectl get pods #可以查看当前名称空间pod信息 NAME READY STATUS RESTARTS AGE sa-demo 1/1 Running 0 3h56m [admin@k8s-master ~]$ kubectl get pods -n ingress-nginx #可以查看其他空间的pod信息 NAME READY STATUS RESTARTS AGE nginx-ingress-controller-79f6884cf6-v5cdj 1/1 Running 1 7d4h [admin@k8s-master ~]$ kubectl delete pod sa-demp #无法删除pod Error from server (Forbidden): pods "sa-demp" is forbidden: User "wx" cannot delete resource "pods" in API group "" in the namespace"default" [admin@k8s-master ~]$
2.3 User --> Rolebinding --> ClusterRole
使用RoleBinding绑定ClusterRole
将WX通过rolebinding到集群角色wx-read-pods当中,此时,wx仅作用于当前名称空间的所有pods资源的权限
创建一个RoleBinding(ClusterRole使用以及存在的),并将用户绑定到ClusterRole上
[root@k8s-master ~]# kubectl delete clusterrolebinding wx-read-all-pods #为了避免冲突,先将之前的clusterrolebinding删除 clusterrolebinding.rbac.authorization.k8s.io "wx-read-all-pods" deleted [root@k8s-master ~]# kubectl create rolebinding wx-read-pods --clusterrole=cluster-reader --user=wx --dry-run -o yaml > rolebinding-cluster-demo.yaml [root@k8s-master ~]# kubectl apply -f rolebinding-cluster-demo.yaml rolebinding.rbac.authorization.k8s.io/wx-read-pods configured [root@k8s-master ~]# [root@k8s-master ~]# kubectl get rolebindings.rbac.authorization.k8s.io | grep wx wx-read-pods 2m32s [root@k8s-master ~]#
验证
#admin用户终端下 [admin@k8s-master ~]$ kubectl get pods #可以获取当前名称空间的pod信息 NAME READY STATUS RESTARTS AGE sa-demo 1/1 Running 0 4h9m [admin@k8s-master ~]$ kubectl get pods -n ingress-nginx #不可用获取其他名称空间的信息 Error from server (Forbidden): pods is forbidden: User "wx" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
2.4 使用RoleBinding绑定集群自带的ClusterRole
创建一个RoleBinding(ClusterRole使用以及存在的),并将用户绑定到ClusterRole上
[root@k8s-master ~]#kubectl get clusterrole #查看当前集群存在的clusterrole [root@k8s-master ~]# kubectl create rolebinding default-ns-admin --clusterrole=admin --user=wx --dry-run -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: default-ns-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: admin subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: wx [root@k8s-master ~]# kubectl create rolebinding default-ns-admin --clusterrole=admin --user=wx --dry-run -o yaml > wx-rolebinding.yaml [root@k8s-master ~]# kubectl apply -f wx-rolebinding.yaml rolebinding.rbac.authorization.k8s.io/default-ns-admin created [root@k8s-master ~]# kubectl describe rolebinding default-ns-admin Name: default-ns-admin Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name":"default-ns... Role: Kind: ClusterRole Name: admin Subjects: Kind Name Namespace ---- ---- --------- User wx [root@k8s-master ~]#
验证
[admin@k8s-master ~]$ kubectl get pods #可以获取当前名称空间的pod信息 NAME READY STATUS RESTARTS AGE sa-demo 1/1 Running 0 4h16m [admin@k8s-master ~]$ kubectl delete pod sa-demo #可以删除当前名称空间的pod pod "sa-demo" deleted [admin@k8s-master ~]$ kubectl get pods -n ingress-nginx #对其名称空间没有任何权限 Error from server (Forbidden): pods is forbidden: User "wx" cannot list resource "pods" in API group "" in the namespace "ingress-nginx" [admin@k8s-master ~]$