授权

认证通过后通信的双方都确认了对方是可信的,可以相互通信。 Authrization 简单来说就是检查这个用户权限是否拥有操作K8S资源的权限,对哪些资源有操作权限,只要存在一个资源的操作权限正确,就允许通过而鉴权是确定请求方有哪些资源的权限。在Kubernetes中,默认使用的,也是使用较多的是RBAC(Role-Based Access Control)。

授权阶段判断请求是否有相应的权限,授权方式有多种:AlwaysDeny,AlwaysAllow,ABAC,RBAC,Node 等。API Server 启动时如果多种授权模式同时被启用,Kubernetes 将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。高版本 Kubernetes 默认开启的授权方式是 RBAC 和 Node。

kube-apiserver启动时需要配置:

--authorization-mode=Node,RBAC

目前k8s支持的授权模式主要有以下几种:

  • Node Authorization

  • ABAC Authorization

  • RBAC Authorization

  • Webhook Authorization

本文只描述Node Authorization 和 RBAC Authorization,

01.RBAC Authrization

基于角色的访问控制(Role-Based Access Control, 即 RBAC),是 k8s 提供的一种授权策略, 针对 RBAC 机制,k8s 提供了四种 API 资源:

  • Role

  • ClusterRole

  • RoleBinding

  • ClusterRoleBinding

这四种API资源的逻辑关系如下:

0101.角色(Role)

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

角色只能对命名空间内的资源进行授权,下面的例子中定义的角色具有读取 Pod 的权限:

rules中参数说明如下:

apiGroups:支持的 API 组列表,例如 “apiVersion: batch/v1” “apiVersion: extensions/v1beta1” "apiVersion: apps/v1beta1" 等。 resource:支持的资源对象列表,例如 pods、deployments、jobs 等。 verbs:对资源对象的操作方法列表,例如 get、watch、list、delete、replace、patch 等。

应该使用哪个 Group 和 Version?

0102.集群角色(Cluster Role)

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

  • 集群范围的资源,例如 Node(节点)。

  • 非资源型的路径,例如 “/healthz”。

  • 包含全部命名空间的资源,例如 pods(用于 kubectl get pods --all-namespaces 这样的操作授权)。

下面的集群角色可以让用户有权访问任意一个或所有命名空间的 secret:

0103.角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)

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

RoleBinding

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

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

例如下面的例子,虽然 secret-reader 是一个集群角色,但是因为使用了 RoleBinding,所以 dave 只能读取 development 命名空间的 secret:

ClusterRoleBinding

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

下面的例子允许 manager 组的用户读取任意 namespace 中的 secret:

0104.集群内置role和rolebinding

集群创建后 API Server 默认会创建一些 ClusterRole 和 ClusterRoleBinding 对象;这些对象以 system: 为前缀,这表明这些资源对象由集群基础设施拥有;修改这些集群基础设施拥有的对象可能导致集群不可用。 一个简单的例子是 system:node ClusterRole,这个 ClusterRole 定义了 kubelet 的相关权限,如果该 ClusterRole 被修改可能导致 ClusterRole 不可用。

所有的默认 ClusterRole 和 RoleBinding 都具有 kubernetes.io/bootstrapping=rbac-defaultslable

默认Role

一些默认的 Role 并未以 system: 前缀开头,这表明这些默认的 Role 是面向用户级别的。这其中包括超级用户的一些 Role( cluster-admin ),和为面向集群范围授权的 RoleBinding( cluster-status ),以及在特定命名空间中授权的 RoleBinding( admineditview )

Default ClusterRole

Default ClusterRoleBinding

Description

cluster-admin

system:masters group

允许超级用户对集群内任意资源执行任何动作。当该 Role 绑定到 ClusterRoleBinding 时,将授予目标 subject 在任意 namespace 内对任何 resource 执行任何动作的权限;当绑定到 RoleBinding 时,将授予目标 subject 在当前 namespace 内对任意 resource 执行任何动作的权限,当然也包括 namespace 自己

admin

None

管理员权限,用于在单个 namespace 内授权;在与某个 RoleBinding 绑定后提供在单个 namesapce 中对资源的读写权限,包括在单个 namesapce 内创建 Role 和进行 RoleBinding 的权限。该 ClusterRole 不允许对资源配额和 namespace 本身进行修改

edit

None

允许读写指定 namespace 中的大多数资源对象;该 ClusterRole 不允许查看或修改 Role 和 RoleBinding

view

None

允许以只读方式访问特定 namespace 中的大多数资源对象;该 ClusterRole 不允许查看 Role 或 RoleBinding,同时不允许查看 secrets,因为他们会不断更新

组件默认role

Default ClusterRole

Default ClusterRoleBinding

Description

system:kube-scheduler

system:kube-scheduler user

允许访问 kube-scheduler 所需资源

system:kube-controller-manager

system:kube-controller-manager user

允许访问 kube-controller-manager 所需资源;该 ClusterRole 包含每个控制循环所需要的权限

system:node

system:nodes group (deprecated in 1.7)

允许访问 kubelet 所需资源;包括对所有的 secrets 读访问权限和对所有 pod 的写权限;在 1.7 中更推荐使用 Node authorizerNodeRestriction admission plugin 而非本 ClusterRole;Node authorizer 和 NodeRestriction admission plugin 可以授权当前 node 上运行的具体 pod 对 kubelet API 的访问权限,在 1.7 版本中,如果开启了 Node authorization mode,那么 system:nodes group将不会被创建和自动绑定

system:node-proxier

system:kube-proxy user

允许访问 kube-proxy 所需资源

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-system namespace

kube-dns 相关权限

system:node-bootstrapper

None

允许访问 Kubelet TLS bootstrapping 相关资源权限

system:node-problem-detector

None

system:persistent-volume-provisioner

Node

允许访问 dynamic volume provisioners 相关资源权限

0105.最佳实践

010501.实践一

主要授权zhangsan可以访问develop namespace下的所有的权限

1.创建x509证书

由于使用X509方式时k8s将证书中的CN作为用户名, O作为组名,所以下面为的CSR文件为

创建 developer 凭证与私钥:

结果将产生以下两个文件:

2.创建kubeconfig文件

先确定apiserver对外提供服务的地址

  • 设置集群参数

  • 设置客户端认证参数

  • 设置上下文参数

  • 设置默认上下文

3.授权

由于k8s集群中默认已经创建了名称为 admin 的clusterrole, 所以我们只需要创建rolebinding, 指令如下:

创建namespace:

创建rolebinding:

4.验证

获取default namespace下的资源

获取develop下的资源

010502.实践二

用户张三可以操作develop namespace下的deployment、svc、ingresses资源, 对于其它资源没有操作权限。

请根据010501.实践一 完成x509证书和kubeconfig的相关部分

1.role yaml模版文件

执行如下指令获取role文件的字段名称已经文件结构:

根据上面文件的KING部分和Version部分获取了api版本, FIELDS部分可以获取到字段名称以及结构, yaml文件的结构如下:

2.获取deployments、services、ingress所属的apigroups

获取资源所属apigroups以及可以进行的操作

得出资源所对应的apigroup, 汇总如下表:

resource

apigroup

deployments

apps

services

k8s core

ingresses

extensions、 networking.k8s.io

最后role文件汇总

创建role:

3.授权

创建rolebinding:

4.验证

执行如下指令:

因为只授权了deployment, svc, ingress 相关的资源所以查看pods会提示没有权限

02.Node Authrization

下面文字摘自官方文档, 具体内部的工作逻辑找了很多文档也没有看出所以然, 只能说node authrization是 kubernetes 的内部机制

Node Authrization 是一种特殊目的的授权模式,主要用来让 kubernetes 遵从 node 的编排规则,实际上是 RBAC 的一部分,相当于只定义了 node 这个角色以及它的权限, 专门对 kubelet 发出的 API 请求进行鉴权。

要启用节点授权器,启用 Node 鉴权模式 (--authorization-mode=Node,RBAC) 和 NodeRestriction 准入插件

节点鉴权器允许 kubelet 执行 API 操作。包括:

读取操作:

  • services

  • endpoints

  • nodes

  • pods

  • secrets、configmaps、以及绑定到 kubelet 的节点的 pod 的持久卷申领和持久卷

写入操作:

  • 节点和节点状态(启用 NodeRestriction 准入插件以限制 kubelet 只能修改自己的节点)

  • Pod 和 Pod 状态 (启用 NodeRestriction 准入插件以限制 kubelet 只能修改绑定到自身的 Pod)

    事件

鉴权相关操作:

  • 对于基于 TLS 的启动引导过程时使用的 certificationsigningrequests API 的读/写权限

  • 为委派的身份验证/授权检查创建 tokenreviews 和 subjectaccessreviews 的能力

在将来的版本中,节点鉴权器可能会添加或删除权限,以确保 kubelet 具有正确操作所需的最小权限集。 为了获得节点鉴权器的授权,kubelet 必须使用一个凭证以表示它在 system:nodes 组中,用户名为 system:node:<nodeName>。 上述的组名和用户名格式要与 kubelet TLS 启动引导过程中为每个 kubelet 创建的标识相匹配。

要启用节点授权器,请使用 --authorization-mode = Node 启动 apiserver。

要限制 kubelet 具有写入权限的 API 对象,请使用--enable-admission-plugins=...,NodeRestriction,...启动 apiserver,从而启用 NodeRestriction 准入插件。

最后更新于

这有帮助吗?