kubernetes中的用户与RBAC

Posted by     "Richie" on Friday, January 25, 2019

Kubernetes 中的用户与RBAC中的关系图如下

rbac 接下来将依依讲述

Kubernetes 中的用户

Kubernetes 集群中包含两类用户:

用户类型 管理者
ServiceAccount(服务账户) 由Kubernetes API管理
User(普通用户) 由外部独立服务管理,k8s没有代表普通用户账户的对象

由于k8s没有代表普通用户账号的对象.无法通过api调用的方式向集群添加普通用户 ServiceAccount是由Kubernetes API 管理的账户. 它们都绑定到了特定的namespace, 并由API server自动创建,或者通过调用api手动创建.ServiceAccount关联了一套凭证, 存储在Secret,这些凭证同时被挂载到pod中, 从而允许pod与kubernetes API之间的调用.

API请求被绑定到普通用户(User) 或者ServiceAccount上, 或者作为匿名请求对待.这意味着 集群内部或者外部的每个进程,无论从在工作站上输入 kubectl的用户到节点的kubelet,到控制 平面的成员,都必须在向API Server发出请求是进行身份验证,或者被视为匿名用户. kubectl使用的kubeconfig,其中kubeconfig中的User使用的就是普通用户(证书认证),在k8s对象里面查不到

RBAC 基于角色的访问控制

Role与ClusterRole

在RBAC API 中, 一个角色包含了一套表示一组权限的规则. 权限是以累加的形式累计(没有"否定"的规则). 角色可以由命名空间(namespace)内的Role对象定义, 而整个kubernetes集群范围内有效的角色则通过ClusterRole对象实现.

一个Role对象只能用于授予对某一单一命名空间中资源的访问权限. 下面实例描述了"default"命名空间中的一个Role对象的定义, 用于授予对Role的读访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: test-pod-reader
  namespace: default

rules:
- apiGroups: [""] # 空字符串"" 表明使用core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list" ]

ClusterRole 对象可以授予与Role 对象相同的权限, 但由于它们属于集群范围对象, 也可以使用它们授权以下几种资源的访问权限:

  • 集群范围资源(例如: 节点, 即node)
  • 非资源类型endpoint(例如: “/healthz”)
  • 跨所有命名空间的命名空间范围资源(例如: pod, 需要运行命令: kubect get pods –all-namespaces来查询集群中所有的pod)

下面示例中的ClusterRole 定义可用于授权用户对某一特定命名空间, 或者所有命名空间中的secret(取决于其绑定方式)的读访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # 鉴于 ClusterRole是集群范围对象, 所有这里不需要定义"namespace" 字段
  name: test-secret-reader

rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding与ClusterRolebinding

角色绑定将一个角色中定义的各种权限授予一个或者一组用户. 角色绑定包含了一组相关主体(即subject,包括用户–User,用户组–Group, 或者服务账户–Service Account)以及对被授予角色的引用. 在命名空间中可以通过RoleBinding 对象授予权限, 而集群范围的权限授予则 通过ClusterRoleBinding 对象完成.

RoleBinding 可以引用在同一命名空间内定义的Role对象. 下面示例中定义的RoleBinding 对象 在"default" 命名空间中将"test-pod-reader" 角色授予用户"richie". 这一授权将允许用户"richie" 从"default" 命名空间中读取pod。

# 以下角色绑定定义将允许用户"richie" 从"default"命名空间中读取pod.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-read-pods
  namespace: default

subjects:
- kind: User
  name: richie
  apiGroup: rbac.authorization.k8s.io

roleRef:
  kind: Role
  name: test-pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding 对象也可以引用一个ClusterRole对象用于在RoleBding 所在的命名空间内授予用户对所引用的ClusterRole中定义的命名空间资源的访问. 这一点允许管理员在整个集群范围内首先定义一组通用的角色, 然后再在不同的命名空间中服用整个角色.

例如: 尽管下面示例中的RoleBinding 引用的是一个ClusterRole对象, 但是用户"zrq"(即角色绑定主体) 还是只能读取"development"命名空间中的 secret(即 RoleBinding所在的命名空间)

# 以下角色绑定允许用户"zrq" 读取"development" 命名空间中的secret
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-secrets
  namespace: development # 这里表明仅授权读取"development" 命名空间中的资源

subjects:
- kind: User
  name: zrq
  apiGroup: rbac.authorization.k8s.io

roleRef:
  kind: ClusterRole
  name: test-secret-reader
  apiGroup: rbac.authorization.k8s.io

最后, 可以使用ClusterRoleBinding 在集群级别和所有命名空间中授予权限. 下面示例中所定义的ClusterRoleBinding 允许用户组"manager"中的 任何用户都可以读取集群中任何命名空间中的secret.

# 以下ClusterRoleBinding 对象允许在用户组"manager" 中的任何用户都可以读取集群中任何命名空间的secret.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global

subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io

roleRef:
  kind: ClusterRole
  name: test-secret-reader
  apiGroup: rbac.authorization.k8s.io

对资源的引用

大多数资源由代表其名字的字符串表示, 例如"pods", 就像它们出现在相关API endpoint的URL中一样. 然而, 有些Kubernetes API 还包含了"子资源", 比如 pod的logs 在Kubernetes中, pod logs endpoint的URL 格式为:

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

在这种情况下, “pods"是命名空间资源, 而"log"是pods的子资源. 为了在RBAC角色中表示出这一点, 我们需要使用斜线来划分 资源和子资源. 如果需要角色绑定主体读取pods以及pod log, 您需要定义以下角色:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-and-pod-logs-reader
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pod", "pods/log"]
  verbs: ["get", "list"]

通过resourceNames 列表, 角色可以针对不同种类的请求根据资源名称引用资源实例. 当指定了resourceName 列表时, 不同的 动作类型的权限, 如使用"get”, “delete”, “update"以及"patch"等动词的请求, 将被限定到资源列表中所包含的资源实例上. 例如,如果需要限定一个角色绑定主体只能"get” 或者"update" 一个configmap时, 您可以定义一下角色:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: configmap-updater
  namespace: default

rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

值得注意的是, 如果设置了 resourceNames, 则请求所使用的动词不能是list, watch, create或者deletecollection. 由于 资源名称不会出现在create, list, watch和deletecollection等API请求的URL中, 所以这些请求动词不会被设置了resourceNames的规则所允许, 因为规则中的resourceNames部分不会匹配这些请求.

一些角色定义的例子

以下示例中, 我们仅截取展示了rules部分的定义.

允许读取core API Group 中定义的资源"pods":

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

允许读写在"extensions" 和"apps" API Group中定义的"deployments":

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取"pods"以及读写"jobs":

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取一个名为"my-config"的configMap实例(需要将其通过RoleBinding绑定从而限制针对某一个命名空间中定义的一个ConfigMap实例的访问):

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

允许读取core API Group中的"nodes" 资源(由于Node是集群级别资源, 所以此ClusterRole 定义需要与一个ClusterRoleBinding绑定才能有效):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

允许对非资源endpoint “/healthz"及其所有子路径的"GET"和"POST” 请求(此ClusterRole 定义需要与一个ClusterRoleBinding绑定才能有效):

rules:
- nonResourcesURLs: ["/healthz", "/healthz/*"] # 在非资源URL中, '*' 代表后缀通配符
  verbs: ["get", "post"]

对角色绑定主体(Subject) 的引用

RoleBinding 或者ClusterRoleBinding 将角色绑定到角色绑定主体(Subject). 角色绑定主体可以是用户组(Group), 用户(User) 或者服务账户(Service Accounts).

用户由字符串来表示. 可以是纯粹的用户名, 例如: “richie”、电子邮件风格的名字, 如: “zrq@example.com"或者是用字符串表示的数字id. 有Kubernetes管理员配置认证以及产生所需格式的用户名. 对于用户名,RBAC授权系统不要求任何特定的格式.然而, 前缀system: 是为Kubernetes系统使用而保留的, 所以管理员应该确保用户名不会意外地包含这个前缀.

Kubernetes 中的用户组信息由授权模块提供. 用户组与用户一样由字符串来表示. Kubernetes 对用户组字符串没有格式要求, 但前缀system: 同样是被系统保留的.

服务账户(Service Account )拥有包含system:serviceaccount: 前缀的用户名, 并属于拥有system:serviceaccounts:前缀的用户组

角色绑定的一些例子

以下示例中, 仅截取展示了 RoleBinding的subjects字段.

一个名字为"zrq@example.com"的用户:

subjects:
- kind: User
  name: "zrq@example.com"
  apiGroup: rbac.authorization.k8s.io

一个名为"frontend-amins"的用户组:

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

kube-system命名空间中的默认服务账户:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

名为"galaxy” 命名空间中的所有服务账户:

subjects:
- kind: Group
  name: system:serviceaccount:galaxy
  apiGroup: rbac.authorization.k8s.io

在集群中的所有服务账户:

subjects:
- kind: Group
  name: system-serviceaccounts
  apiGroup: rbac.authorization.k8s.io

所有认证过的用户(version 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

所有未认证的用户(version 1.5+):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

所有用户(version 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

- kind: Group
  name: system.unauthenticated
  apiGroup: rbac.authorization.k8s.io

默认角色与默认角色绑定

API Server 会创建一组默认的ClusterRole和ClusterRoleBinding对象. 这些默认对象中有许多包含system:前缀, 表明这些资源由Kubernetes基础组件"拥有". 对这些资源的修改可能导致非功能集群(non-functional cluster).一个 例子是 system:node ClusterRoled对象. 这个角色定义了kubernetes的quanx.如果这个角色被修改, 可能会导致kubeletes无法正常工作.

所有默认的ClusterRole和ClusterRoleBinding对象都会被标记为kubernetes.io/bootstrapping=rbac-defaults.

自动更新

每次启动时, API Server 都会更新默认ClusterRole所缺乏的各种权限, 并更新默认ClusterRoleBinding所缺乏的各个角色绑定主体.这种自动更新机制允许集群修复一些意外的修改.由于权限和角色绑定主体在Kubernetes释出版本中可能变化, 这也能够确保角色和角色绑定始终保持是最新的.

如果需要禁用自动更新, 请将默认ClusterRole以及ClusterRoleBinding的rbac.authorization.kubernetes.io/autoupdate设置为false. 请注意, 缺乏默认权限和角色绑定主体可能会导致非功能性集群问题.

自Kubernetes 1.6+起. 当集群RBAC授权器(RBAC Authorizer) 处于开启状态时,可以启用自动更新功能.

发现类角色

默认ClusterRole 默认ClusterRoleBinding 描述
system:basic-user system:authenticated and system:unauthenticated groups 允许用户只读访问有关自己的基本信息
system:discovery system: authenticated and system:unauthenticated groups 允许只读访问API discovery endpoints,用于API级别进行发现和协商

面向用户的角色

一些默认角色并不包含system:前缀, 它们是面向用户的角色. 这些角色包含超级用户角色(cluster-admin),即旨在利用ClusterRoleBinding(cluster-status)在集群范围内授权的角色, 以及那些使用RoleBinding(admin, edit和view)在特定命名空间中授权的角色.

默认ClusterRole 默认ClusterRoleBinding 描述
cluster-admin system:masters group 超级用户权限, 允许对任何资源执行任何操作.在ClusterRoleBinding中使用是, 可以完全控制集群和所有命名空间中的所有资源. 在RoleBinding 中使用时, 可以完全控制RoleBinding所在的命名空间中的所有资源,包括命名空间自己.
admin None 管理员权限, 利用RoleBinding 在某一命名空间内部授予. 在RoleBinding 中使用时, 允许针对命名空间内大部分资源的读写访问, 包括在命名空间内创建角色与角色绑定的能力. 但不允许对资源配置(resource quota)或者命名空间本身的写访问
edit None 允许对某一个命名空间内大部分对象的读写访问, 但不允许查看或者修改角色或者角色绑定.
view Nonw 允许对某一个命名空间内大部分对象的只读访问. 不允许查看角色或者角色绑定. 由于可扩散性等原因, 不允许查看secret资源.

Core Component Roles

核心组件角色

默认ClusterRole 默认ClusterRoleBinding 描述
system:kube-scheduler system:kube-scheduler user 允许访问kube-scheduler 组件所需要的资源
system:kube-controller-manager system:kube-controller-manager user 允许访问kube-controller-manager组件所需要的资源.
system:node system:nodes group(deprecated in 1.7) 允许对kubelet组件所需要的资源的访问,包括读取所有secret和对所有pod的写访问。 自Kubernetes 1.7开始, 相比较于这个角色,更推荐使用Node authorizer 以及NodeRestriction admission plugin, 并允许根据调度运行在节点上的pod授予kubelets API访问的权限。 自Kubernetes 1.7开始,当启用Node授权模式时,对system:nodes用户组的绑定将不会被自动创建
system:node-proxier system:kube-proxy user 允许对kube-proxy 组件所需要资源的访问.

其他组件角色

默认ClusterRole 默认ClusterRoleBinding 描述
system:auth-delegator None 允许委托认证和授权检查. 通常由附加API Server用于统一认证和授权
system:heapster None Heapster 组件的角色
system:kube-aggregator None kube-aggregator 组件的角色
system:kube-dns kube-dns service account in the kube-sysemnamespace kube-dns 组件的角色
system:node-boostrapper None 允许对执行Kubelet TLS 引导(kubelet TLS boostrapping) 所需要资源的访问
system:node-problem-detector None node-problem-detector组件的角色
system: persistent-volume-provisioner None 允许对大部分动态存储卷创建组件(dynamic volume provisioner) 所需要资源的访问

「真诚赞赏,手留余香」

Richie Time

真诚赞赏,手留余香

使用微信扫描二维码完成支付