K8s RBAC使用

 

 

1.RBAC简介

1.1 基本概念

    RBAC(Role-Based Access Control,基于角色的访问控制)在k8s v1.5中引入,在v1.6版本时升级为Beta版本,相对于其他访问控制方式,RBAC具有如下优势:

  1. 对集群中的资源和非资源权限均有完整的覆盖
  2. 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作
  3. 可以在运行时进行调整,无需重启API Server
  4. 要使用RBAC授权模式,需要在API Server的启动参数中加上--authorization-mode=RBAC

1.2 Role和ClusterRole 

Role是一系列的权限的集合,例如一个Role可以包含读取 Pod 的权限和列出 Pod 的权限, ClusterRole 跟 Role 类似,但是可以在集群中全局使用。

Role只能授予单个namespace 中资源的访问权限。

ClusterRole授权 >= Role授予(与Role类似),但ClusterRole属于集群级别对象:

集群范围的资源访问控制(如:节点访问权限)

非资源类型(如“/ healthz”)

所有namespaces 中的namespaced 资源(如 pod)

1.3RoleBinding和ClusterRoleBinding

RoleBinding是将Role中定义的权限授予给用户或用户组,引用该Role,Role有了权限,用户也就有了权限。RoleBinding在某个namespace 内授权,ClusterRoleBinding适用在集群范围内使用。

RoleBinding可以引用相同namespace下定义的Role。

Role和ClusterRole、RoleBinding和ClusterRoleBinding关系图

K8s RBAC使用

 

 使用RoleBinding去绑定ClusterRole:

 

如果有10个名称空间,每个名称空间都需要一个管理员,而这些管理员的权限都是一致的。那么此时需要去定义这样的管理员,使用RoleBinding就需要创建10个Role,这样显得很麻烦。为此当使用RoleBinding去绑定一个ClusterRole时,该User仅仅拥有对当前名称空间的集群操作权限,此时只需要创建一个ClusterRole就解决了以上的需求。

 

2.RBAC使用

2.1角色(Role)

一个角色就是一组权限的集合,这里的权限都是许可形式的,不存在拒绝的规则。在一个命名空间中,可以用角色来定义一个角色,如果是集群级别的,就需要使用ClusterRole了。角色只能对命名空间内的资源进行授权。

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

    namespace: default

    name: pod-reader

 

rules:

- apiGroups: [""]  # 空字符串表示核心API群

  resource: ["pods"]

  verbs: ["get", "watch", "list"]

rules中的参数:

apiGroup:支持的API组列表,例如:APIVersion: batch/v1、APIVersion: extensions:v1、apiVersion:apps/v1等

resources:支持的资源对象列表,例如:pods、deployments、jobs等

verbs:对资源对象的操作方法列表,例如:get、watch、list、delete、patch等

2.2集群角色(ClusterRole)

集群角色除了具有和角色一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权。

    -集群范围的资源,例如Node

    非资源型的路径,例如/healthz

  包含全部命名空间的资源,例如pods

集群角色授予用户有权访问任意一个或所有命名空间的secrets:

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: secret-reader

  # ClusterRole不受限于命名空间,所以省略了namespace name的定义

rules:

- apiGroups: [""]

  resources: ["secrets"]

  verbs: ["get", "watch", "list"]

2.3角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)

  角色绑定或集群角色绑定用来把一个角色绑定到一个目标上,绑定目标可以是User、Group或者Service Account。使用RoleBinding为某个命名空间授权,ClusterRoleBinding为集群范围内授权。

    RoleBinding可以引用Role进行授权,下例中的RoleBinding将在default命名空间中把pod-reader角色授予用户jane,可以让jane用户读取default命名空间的Pod:

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

  RoleBinding也可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。一种常见的做法是集群管理员为集群范围预先定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些ClusterRole。

使用RoleBinding绑定集群角色secret-reader,使dave只能读取development命名空间中的secret:

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

集群角色绑定中的角色只能是集群角色,用于进行集群级别或者对所有命名空间都生效的授权。

允许manager组的用户读取任意namespace中的secret:

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: read-secrets-global

subjects:

- kind: Group

  name: manager

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: ClusterRole

  name: secret-reader

  apiGroup: rbac.authorization.k8s.io

2.4对资源更细粒度的引用方式

 多数资源可以用其名称的字符串来表达,也就是Endpoint中的URL相对路径,例如pods。然后,某些Kubernetes API包含下级资源,例如Pod的日志(logs)。Pod日志的Endpoint是GET /api/v1/namespaces/{namespaces}/pods/{name}/log。

Pod是一个命名空间内的资源,log就是一个下级资源。要在一个RBAC角色中体现,则需要用斜线/来分割资源和下级资源。若想授权让某个主体同时能够读取Pod和Pod log,则可以配置resources为一个数组:

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

资源还可以通过名字(ResourceName)进行引用。在指定ResourceName后,使用get、delete、update、patch动词的请求,就会被限制在这个资源实例范围内。例如下面的声明让一个主体只能对一个叫my-configmap的configmap进行get和update操作:

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  namespace: default

  name: configmap-updater

rules:

- apiGroups: [""]

  resources: ["configmap"]

  resourceNames: ["my-configmap"]

  verbs: ["update", "get"]

3. K8s上下文(Context)

3.1context简介

在使用kubectl操作kubernetes集群的过程中,可能会遇到需要操作不同集群的问题,例如本地的集群和线上的部署集群,或是线上的测试集群和线上的部署集群。假设用户有两个集群,一个用于正式开发工作,一个用于其它临时用途(scratch)。 在 development 集群中,前端开发者在名为 frontend 的名字空间下工作, 存储开发者在名为 storage 的名字空间下工作。 在 scratch 集群中, 开发人员可能在默认名字空间下工作,也可能视情况创建附加的名字空间。 访问开发集群需要通过证书进行认证。 访问其它临时用途的集群需要通过用户名和密码进行认证。