这篇学习笔记是基于杜宽老师在51CTO上发布的视频课程制作的。在此,感谢杜宽老师的分享和教学。如有侵权,请及时联系我。版权归原作者所有,未经允许不得转载或使用。
一、什么是RBAC?
基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。
RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组 来驱动鉴权决定,允许你通过 Kubernetes API 动态配置策略。
要启用 RBAC,在启动 API 服务器 时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC。
文档:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
二、RBAC分类介绍(API 对象)
1、RBAC有4种顶级资源
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
2、资源介绍
Role:角色,包含一组权限的规则。没有拒绝规则,只是附加允许。Namespace隔离,只作用于命名空间内!
ClusterRole:集群角色,和Role一样。和Role的区别,Role是只作用于命名空间内,ClusterRole作用于整个集群!
RoleBinding:作用于命令空间内,将ClusterRole或者Role绑定到User、Group、ServiceAccount!
ClusterRoleBinding:作用于整个集群。
三、示例
1、Role 示例
Role 总是用来在某个名字空间内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间
kind: Role # 定义资源类型为Role
apiVersion: rbac.authorization.k8s.io/v1 # 定义该资源的API版本,建议使用v1版本,因为其它版本如beta版本在Kubernetes1.22+将被彻底启用
metadata: # 元数据定义
namespace: default # 因为Role是作用单个Namespace下的,具有命名空间隔离,所以需要制定Namespace,不指定则为default
name: pod-reader # Role的名称
rules: # 定义具体的权限,切片类型,可以配置多个
- apiGroups: [""] # 包含该资源的apiGroup名称,比如extension
resources: ["pods"] # 定义对哪些资源进行授权,切片类型,可以定义多个,比如pods、service等
verbs: ["get", "watch", "list"] # 定义可以执行的操作,切片类型,可以定义多个,比如create、delete、list、get、watch、deletecollection等
2、ClusterRole 示例
ClusterRole 有若干用法。你可以用它来:
- 定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
- 为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
- 为集群作用域的资源定义访问权限。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: []
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"]
3、RoleBinding 示例
下面的例子中的 RoleBinding 将 "pod-reader" Role 授予在 "default" 名字空间中的用户 "jane"。 这样,用户 "jane" 就具有了读取 "default" 名字空间中 pods 的权限。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects: # 配置被绑定对象,可以配置多个
- kind: User # 绑定对象的类别,当前为User,还可以是Group、ServiceAccount
name: jane # 绑定对象名称
apiGroup: rbac.authorization.k8s.io
roleRef: # 绑定的类别
kind: Role # 指定权限来源,可以是Role或ClusterRole
name: pod-reader # Role或ClusterRole的名字
apiGroup: rbac.authorization.k8s.io # API 组名
1、RoleBinding 引用 ClusterRole
RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在名字空间的资源。这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个名字空间中复用!
下面的例子中的 RoleBinding,将"secret-reader" ClusterRole授予在"development" namespace中的用户"dave"。这样,用户 "dave" 就具有了读取 "development" 名字空间中 pods 的权限。
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "default" 名字空间中的 Secrets
# 你需要一个名为 "secret-reader" 的 ClusterRole
kind: RoleBinding
metadata:
name: read-secrets
# RoleBinding 的名字空间决定了访问权限的授予范围。
# 这里仅授权在 "development" 名字空间内的访问权限。
namespace: development
subjects:
- kind: User
name: dave # 'name' 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
4、ClusterRoleBinding 示例
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。 下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问任何名字空间中的 Secrets。
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
注意:
创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的 roleRef
将导致合法性检查错误。 如果你想要改变现有绑定对象中 roleRef
字段的内容,必须删除重新创建绑定对象。
这种限制有两个主要原因:
- 针对不同角色的绑定是完全不一样的绑定。要求通过删除/重建绑定来更改
roleRef
, 这样可以确保要赋予绑定的所有主体会被授予新的角色(而不是在允许修改roleRef
的情况下导致所有现有主体胃镜验证即被授予新角色对应的权限)。 - 将
roleRef
设置为不可以改变,这使得可以为用户授予对现有绑定对象的update
权限, 这样可以让他们管理主体列表,同时不能更改被授予这些主体的角色。
命令 kubectl auth reconcile
可以创建或者更新包含 RBAC 对象的清单文件, 并且在必要的情况下删除和重新创建绑定对象,以改变所引用的角色
5、聚合的 ClusterRole
下面是一个聚合 ClusterRole 的示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 控制面自动填充这里的规则
-------
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
# 当你创建 "monitoring-endpoints" ClusterRole 时,
# 下面的规则会被添加到 "monitoring" ClusterRole 中
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]
下面的 ClusterRoles 让默认角色 "admin" 和 "edit" 拥有管理自定义资源 "CronTabs" 的权限, "view" 角色对 CronTab 资源拥有读操作权限。 你可以假定 CronTab 对象在 API 服务器所看到的 URL 中被命名为 "crontabs"
。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregate-cron-tabs-edit
labels:
# 添加以下权限到默认角色 "admin" 和 "edit" 中
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:
# 添加以下权限到 "view" 默认角色中
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch"]
四、RBAC实践
创建一个名为 deployment-clusterrole 的 clusterrole
该 clusterrole 只允许创建 Deployment、Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一步创建 clusterrole 的权限绑定到该 serviceAccount
创建 namespace 和 serviceAccount
# kubectl create ns app-team1
namespace/app-team1 created
# kubectl create sa cicd-token -n app-team1
serviceaccount/cicd-token created
创建 clusterrole
# cat dp-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: deployment-clusterrole
rules:
- apiGroups: ["extensions", "apps"]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["deployments","statefulsets","daemonsets"]
verbs: ["create"]
# kubectl create -f dp-clusterrole.yaml
clusterrole.rbac.authorization.k8s.io/deployment-clusterrole created
绑定权限
# kubectl create rolebinding deployment-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token -n app-team1
或者
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-rolebinding
namespace: app-team1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: deployment-clusterrole
subjects:
- kind: ServiceAccount
name: cicd-token
namespace: app-team1
创建 deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: app-team1
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- image: redis
imagePullPolicy: Always
name: redis
restartPolicy: Always
五、不同用户不同权限
需求:
- 用户dotbalo可以查看default、kube-system下Pod的日志
- 用户dukuan可以在default下的Pod中执行命令,并且可以删除Pod
创建查看命名空间的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-readonly
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- metrics.k8s.io
resources:
- pods
verbs:
- get
- list
- watch
创建删除pod的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-delete
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- delete
创建pod执行命令的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-exec
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
创建查看pod日志的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-log
rules:
- apiGroups:
- ""
resources:
- pods
- pods/log
verbs:
- get
- list
- watch
创建用户管理命名空间
kubectl create ns kube-users
绑定全局命名空间查看权限
kubectl create clusterrolebinding namespace-readonly \
--clusterrole=namespace-readonly --serviceaccount=system:serviceaccounts:kube-users
创建用户
kubectl create sa dotbalo dukuan -n kube-users
绑定权限
kubectl create rolebinding dotbalo-pod-log \
--clusterrole=pod-log --serviceaccount=kube-users:dotbalo --namespace=kube-system
kubectl create rolebinding dotbalo-pod-log \
--clusterrole=pod-log --serviceaccount=kube-users:dotbalo --namespace=default
kubectl create rolebinding dukuan-pod-exec \
--clusterrole=pod-exec --serviceaccount=kube-users:dukuan --namespace=default
kubectl create rolebinding dukuan-pod-delete \
--clusterrole=pod-delete --serviceaccount=kube-users:dukuan --namespace=default
评论区