kubernettes之RBAC基于角色的访问控制

一.RBAC的概念

基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。其在kubernetes 1.5版本引入,在1.6版本升级为beta版本,并成为kubeadm安装方式下的默认选项。要启用 RBAC,在启动 API 服务器时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC。

kube-apiserver --authorization-mode=Example,RBAC --<其他选项> --<其他选项>

RBAC API 声明了四种 Kubernetes 对象:RoleClusterRole、 ClusterRoleBinding、RoleBinding。你可以像使用其他 Kubernetes 对象一样使用kubectl操作这些资源。

Role 和 ClusterRole

RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则,这些权限是纯粹累加的(不存在拒绝某操作的规则)

两者的区别是Role是作用于命名空间的角色,ClusterRole是作用于整个集群的集群角色。在你创建 Role 时,你必须指定该 Role 所属的名字空间,这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。

ClusterRole也是可以作用于单个命名空间的,不仅仅用于整个集群作用域。

ClusterRole 有若干用法。你可以用它来:

  1. 定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限;
  2. 为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限;
  3. 为集群作用域的资源定义访问权限。

 Role 示例

下面是一个位于 "default" 名字空间的 Role 的示例,可用来授予对 pod的读访问权限

apiVersion: rbac.authorization.k8s.io/v1 #该资源的api版本,使用v1版本,其他版本在1.22上将被弃用
kind: Role  #资源类型为Role
metadata:   #元数据定义
  namespace: default #命名空间
  name: pod-reader   #Role的名称
rules:               #定义Role具体的权限
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]  #定义对哪些资源进行授权,比如pods,service等
  verbs: ["get", "watch", "list"] #可以执行的操作,还有create、delete、list、get、watch、deletecollection等

ClusterRole 示例

ClusterRole 同样可以用于授予 Role 能够授予的权限。 因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:

  • 集群范围资源(比如节点(Node)

  • 非资源端点(比如 /healthz

  • 跨名字空间访问的名字空间作用域的资源(如 Pod)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

 从以上配置可以看出,RoleClusterRole的yaml文件的配置区别不大,只是kind资源类型是Role还是ClusterRole。

RoleBinding 和 ClusterRoleBinding

角色绑定(Role Binding)是将角色中定义的权限赋予User、Group或者ServiceAccount。

RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。

一个 RoleBinding 可以引用同一的名字空间中的任何 Role,RoleBinding 也可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。

RoleBinding 示例

RoleBinding引用Role赋权

apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该命名空间中有一个名为 “pod-reader” 的 Role
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
  name: jane # "name" 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role        # 此字段必须是 Role 或 ClusterRole
  name: pod-reader  # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io

RoleBinding引用ClusterRole赋权,管理员可以为整个集群定义一组公用的ClusterRole,然后在多个命名空间重复使用。

apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "development" 名字空间中的 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

ClusterRoleBinding 示例

要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding,ClusterRoleBinding可用于在集群级别和所有命名空间中授予权限,比如下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问任何名字空间中的 Secrets。

apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
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 字段的内容,必须删除重新创建绑定对象。

对资源的引用

在 Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。 例如,对于 Pod 应使用 "pods"。 RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。 有一些 Kubernetes API 涉及 子资源(subresource),例如 Pod 的日志。 对 Pod 日志的请求看起来像这样:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这里,pods 对应名字空间作用域的 Pod 资源,而 log 是 pods 的子资源。 在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 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"]

 对于某些请求,也可以通过 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"]

聚合的 ClusterRole

 你可以将若干 ClusterRole 聚合(Aggregate) 起来,形成一个复合的 ClusterRole。 作为集群控制面的一部分,控制器会监视带有 aggregationRule 的 ClusterRole 对象集合。aggregationRule 为控制器定义一个标签选择算符供后者匹配应该组合到当前 ClusterRole 的 roles 字段中的 ClusterRole 对象

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 控制面自动填充这里的规则

 如果你创建一个与某个已存在的聚合 ClusterRole 的标签选择算符匹配的 ClusterRole, 这一变化会触发新的规则被添加到聚合 ClusterRole 的操作。 下面的例子中,通过创建一个标签同样为 rbac.example.com/aggregate-to-monitoring: true 的 ClusterRole,新的规则可被添加到 "monitoring" ClusterRole 中。

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"]

默认的面向用户的角色使用 ClusterRole 聚合。 这使得作为集群管理员的你可以为扩展默认规则,包括为定制资源设置规则, 比如通过 CustomResourceDefinitions 或聚合 API 服务器提供的定制资源。

例如,下面的 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"]

 Role 的rules规则示例

#允许读取在核心 API 组下的 "pods"
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
#允许在 "apps" API 组中读/写 Deployment(在 HTTP 层面,对应 URL 中资源部分为 "deployments")
rules:
- apiGroups: ["apps"]
  #
  # 在 HTTP 层面,用来访问 Deployment 资源的名称为 "deployments"
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
#允许读取核心 API 组中的 Pod 和读/写 "batch" API 组中的 Job 资源:
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  # 在 HTTP 层面,用来访问 Job 资源的名称为 "jobs"
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
#允许读取名称为 "my-config" 的 ConfigMap
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]
#允许读取在核心组中的 "nodes" 资源(因为 Node 是集群作用域的,所以需要 ClusterRole 绑定到 ClusterRoleBinding 才生效)
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Node 资源的名称为 "nodes"
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
#允许针对非资源端点 /healthz 和其子路径上发起 GET 和 POST 请求 (必须在 ClusterRole 绑定 ClusterRoleBinding 才生效)
rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # nonResourceURL 中的 '*' 是一个全局通配符
  verbs: ["get", "post"]

 对主体的引用

RoleBinding 或者 ClusterRoleBinding 可绑定角色到某 主体(Subject) 上。 主体可以是组,用户或者服务账户

Kubernetes 用字符串来表示用户名。 用户名可以是普通的用户名,像 "alice";或者是邮件风格的名称,如 "bob@example.com", 或者是以字符串形式表达的数字 ID。

前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求

服务账户(ServiceAccount) 的用户名前缀为 system:serviceaccount:,属于前缀为 system:serviceaccounts: 的用户组

#对于名称为 alice@example.com 的用户:
subjects:
- kind: User
  name: "alice@example.com"
  apiGroup: rbac.authorization.k8s.io
#对于名称为 frontend-admins 的用户组
subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io
#对于 kube-system 名字空间中的默认服务账户
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
#对于所有已经过身份认证的用户
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
#对于所有未通过身份认证的用户
subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io
#对于所有用户
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

下面的 ClusterRole 和 RoleBinding 将允许用户 user-1 把名字空间 user-1-namespace 中的 adminedit 和 view 角色赋予其他用户:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles"]
  verbs: ["bind"]
  # 忽略 resourceNames 意味着允许绑定任何 ClusterRole
  resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: user-1-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: user-1

 

一些创建RBAC相关资源命令行实现

1.创建Role kubectl create role

创建 Role 对象,定义在某一名字空间中的权限。例如:

  • 创建名称为 “pod-reader” 的 Role 对象,允许用户对 Pods 执行 getwatch 和 list 操作:

    kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
    
  • 创建名称为 “pod-reader” 的 Role 对象并指定 resourceNames

    kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
  • 创建名为 “foo” 的 Role 对象并指定 apiGroups

    kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
    
  • 创建名为 “foo” 的 Role 对象并指定子资源权限:

    kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
    
  • 创建名为 “my-component-lease-holder” 的 Role 对象,使其具有对特定名称的资源执行 get/update 的权限:

    kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component
    

2.创建ClusterRole  kubectl create clusterrole

创建 ClusterRole 对象。例如:

  • 创建名称为 “pod-reader” 的 ClusterRole 对象,允许用户对 Pods 对象执行 get、 watch 和 list 操作:

    kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
    
  • 创建名为 “pod-reader” 的 ClusterRole 对象并指定 resourceNames

    kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
  • 创建名为 “foo” 的 ClusterRole 对象并指定 apiGroups

    kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
    
  • 创建名为 “foo” 的 ClusterRole 对象并指定子资源:

    kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
    
  • 创建名为 “foo” 的 ClusterRole 对象并指定 nonResourceURL

    kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
    
  • 创建名为 “monitoring” 的 ClusterRole 对象并指定 aggregationRule

    kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"
    

3.创建RoleBinding kubectl create rolebinding

在特定的名字空间中对 Role 或 ClusterRole 授权。例如:

  • 在名字空间 “acme” 中,将名为 admin 的 ClusterRole 中的权限授予名称 “bob” 的用户:

    kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
    
  • 在名字空间 “acme” 中,将名为 view 的 ClusterRole 中的权限授予名字空间 “acme” 中名为 myapp 的服务账户:

    kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
    
  • 在名字空间 “acme” 中,将名为 view 的 ClusterRole 对象中的权限授予名字空间 “myappnamespace” 中名称为 myapp 的服务账户:

    kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
    

4.创建CllusterRoleBinding kubectl create clusterrolebinding

在整个集群(所有名字空间)中用 ClusterRole 授权。例如:

  • 在整个集群范围,将名为 cluster-admin 的 ClusterRole 中定义的权限授予名为 “root” 用户:

    kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
    
  • 在整个集群范围内,将名为 system:node-proxier 的 ClusterRole 的权限授予名为 “system:kube-proxy” 的用户:

    kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
    
  • 在整个集群范围内,将名为 view 的 ClusterRole 中定义的权限授予 “acme” 名字空间中名为 “myapp” 的服务账户:

    kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
    

kubectl auth reconcile

使用清单文件来创建或者更新 rbac.authorization.k8s.io/v1 API 对象。

尚不存在的对象会被创建,如果对应的名字空间也不存在,必要的话也会被创建。 已经存在的角色会被更新,使之包含输入对象中所给的权限。如果指定了 --remove-extra-permissions,可以删除额外的权限。

已经存在的绑定也会被更新,使之包含输入对象中所给的主体。如果指定了 --remove-extra-permissions,则可以删除多余的主体。

例如:

  • 测试应用 RBAC 对象的清单文件,显示将要进行的更改:

    kubectl auth reconcile -f my-rbac-rules.yaml --dry-run=client
    
  • 应用 RBAC 对象的清单文件,保留角色(roles)中的额外权限和绑定(bindings)中的其他主体:

    kubectl auth reconcile -f my-rbac-rules.yaml
    
  • 应用 RBAC 对象的清单文件,删除角色(roles)中的额外权限和绑定中的其他主体:

    kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忍冬行者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值