目 录CONTENT

文章目录

颗粒度权限控制

简中仙
2023-06-13 / 0 评论 / 0 点赞 / 92 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-01-14,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

这篇学习笔记是基于杜宽老师在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 有若干用法。你可以用它来:

  1. 定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
  2. 为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
  3. 为集群作用域的资源定义访问权限。
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 字段的内容,必须删除重新创建绑定对象。

这种限制有两个主要原因:

  1. 针对不同角色的绑定是完全不一样的绑定。要求通过删除/重建绑定来更改 roleRef, 这样可以确保要赋予绑定的所有主体会被授予新的角色(而不是在允许修改 roleRef 的情况下导致所有现有主体胃镜验证即被授予新角色对应的权限)。
  2. 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
0

评论区