目录
3、角色绑定 (RoleBinding和ClusterRoleBinding)
2、在命名空间中为“默认”服务帐户(service account)授予角色
4、对集群范围内的所有服务帐户(不鼓励)授予权限(role)
4、kubectl create clusterrolebinding
k8s RBAC 权限管理详解
一、简介
基于角色(Role)的访问控制(RBAC Role Base Access Control)是一种基于组织中用户的角色来调节控制对计算机或者网络资源的访问的方法。RBAC鉴权机制使用 rbac.authorization.k8s.io API组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。
k8s 集群相关所有的交互都通过apiserver来完成,对应这样集中式管理的系统来说,权限管理尤为重要,在1.5版本时候引入了RBAC的权限控制机制
让一个用户(Users)扮演一个角色(Role),角色拥有权限,从而让用户拥有这样的权限,随后在 授权机制当中,只需要将权限授予某个角色,此时用户将获取对应角色的权限,从而实现角色的访问 控制
在 k8s 的授权机制当中,采用 RBAC 的方式进行授权,其工作逻辑是,把对对象的操作权限定义到 一个角色当中,再将用户绑定到该角色,从而使用户得到对应角色的权限。如果通过 rolebinding 绑定 role,只能对 rolebingding 所在的名称空间的资源有权限。另外,k8s 为此还有一种集群级别的授权机制,就是定义一个集群角色(ClusterRole),对集群内 的所有资源都有可操作的权限,从而将 User2 通过 ClusterRoleBinding 到 ClusterRole,从而使 User2 拥有集群的操作权限。
启用RBAC,需要在 apiserver 中添加参数–authorization-mode=RBAC,如果使用的kubeadm安装的集群,1.6+版本都默认开启了RBAC。
[root@k8s-master-1 cfg]# cat kube-apiserver.conf | grep authorization
--authorization-mode=RBAC,Node \
API Server 目前支持一下集中授权策略
- Webhook:通过调用外部REST服务对用户进行授权。
- RBAC:Role-Based Access Control,基于角色的访问控制(本章讲解)。
- Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
二、用户分类
k8s的用户分两种,一种是普通用户,一种是ServiceAccount(服务账户)
1、普通用户
- 普通用户是假定被外部或独立服务管理的,管理员分配私钥,平时常用的kubectl命令都是普通用户执行的
- 如果是用户需求权限,则将Role与User(或Group)绑定(需要创建User/Group),是给用户使用的。
2、ServiceAccount
- ServiceAccount(服务帐户)是由Kubernetes API管理的用户。它们绑定到特定的命名空间,并由API服务器自动创建或通过API调用手动创建。服务帐户与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。(登录dashboard时我们使用的就是ServiceAccount)
- 如果是程序需求权限,将Role与ServiceAccount指定(这需要创建ServiceAccount并且在deployment中指定ServiceAccount),是给程序使用的。
工作流程图:
三、k8s角色&角色绑定
k8s引入了4个资源对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding
1、授权介绍:
在RBAC API中,通过如下步骤进行授权
1.1 定义角色:
在定义角色时会指定此角色对于资源的访问控制规则
Role:角色,包含一组权限的规则,没有拒绝规则,只是附加运行,namespaces隔离,只作用于命名空间。授权特定命名空间的访问权限
ClusterRole:和Role的区别,Role只作用于命名空间内,ClusterRole作用于整个集群,也就是所有Namespace
1.2 绑定角色:
将主体与角色进行绑定,对用户进行访问授权
RoleBinding:作用于命名空间内,将ClusterRole或Role绑定于主体(User、Group或ServiceAccount)
ClusterRoleBinding:作用于整个集群,将ClusterRole或Role绑定于主体(User、Group或ServiceAccount)
1.3主体(subject)
User:用户
Group:用户组
ServiceAccount:服务账户
2、角色(Role和ClusterRole)
角色Role是权限的定义,在k8s中角色分为两种,
1、Role针对特定的命名空间的访问权限,
2、ClusterRole在整个集群范围内都生效。为啥要用两种资源?因为k8s对象作用域已经被划分为集群和命名空间两部分了。
需要注意:角色只有授权,没有禁止。
授权词 |
说明 |
get |
列出单个资源 |
list |
列出资源类型的集合 |
create |
创建 |
update |
修改全部资源 |
patch |
修改部分资源 |
watch |
动态监控 |
proxy |
代理 |
redirect |
重定向 |
use |
调用 |
delete |
删除 |
deletecollection |
级联删除 |
相关参数:构成一个role 需要三部分
- Verbs:设置允许对资源对象操作的方法列表,如:{“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”, “exec”}
- resources:需要操作的资源类型列表,如:{“services”, “endpoints”, “pods”,“secrets”,“configmaps”,“crontabs”,“deployments”,“jobs”,“nodes”,“rolebindings”,“clusterroles”,“daemonsets”,“replicasets”,“statefulsets”,“horizontalpodautoscalers”,“replicationcontrollers”,“cronjobs”}
- apiGroups:资源对象的API组列表:"" 缺省为 core 组资源,如: “”,“apps”, “autoscaling”, “batch”
1、Role示例:
1、命令行方式创建
kubectl create role <RoleName> [options]
常用的options 如上
示例:创建一个名为pod-role的role,可以操作的资源为pod,可以进行的操作为get, watch, list
[root@k8s-master-1 rbac]# kubectl create role pod-role --resource=pod --verb=get,watch,list
role.rbac.authorization.k8s.io/pod-role created
2、yaml文件方式创建
[root@k8s-master-1 rbac]# vim role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-role
namespace: default
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
[root@k8s-master-1 rbac]# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/pod-role created
[root@k8s-master-1 rbac]# kubectl get role
NAME CREATED AT
pod-role 2023-06-19T07:51:55Z
[root@k8s-master-1 rbac]# kubectl describe role pod-role
Name: pod-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get watch list]
- - - - - - -对资源的引用 - - - - - - - - -
kubernetes API中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。例如pod 应使用"pods",有一些kubernetes API涉及子资源,
在RBAC角色表达资资源时,使用斜线(/)来分隔资源和子资源。
1、要允许某主体读取pod 同时访问这些pod的log子资源
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
2、对于某些请求,也可以通过resourceNames列表按名称引用资源,在指定时,可以将请求限定为资源的单个实例,
下面的例子中可以get和update 一个名为my-configmap 的 ConfigMap
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
注意:
如果resources:填写的资源是["pods", "services"]等,apiGroups:可以直接用空来表示所有 [""],但是如果resources中添加了["deployments"],绑定的用户在创建deployment时候就会报错,没有权限。这是为啥?
因为apiGroups 为空的话,他只是针对单级的资源生效,
比方说 xx 例如 apiServer: v1,就是单级的,有pod、svc、ep...
还有两级的 比如:xx/yy 例如ap