Kubernetes K8S之鉴权RBAC详解

 

Kubernetes K8S之鉴权概述与RBAC详解node

 

K8S认证与受权

 

认证「Authentication」

认证有以下几种方式:算法

一、HTTP Token认证:经过一个Token来识别合法用户。api

HTTP Token的认证是用一个很长的特殊编码方式的而且难以被模仿的字符串来表达客户的一种方式。每个Token对应一个用户名,存储在API Server能访问的文件中。当客户端发起API调用请求时,须要在HTTP Header里放入Token。frontend

二、HTTP Base认证:经过用户名+密码的方式认证测试

用户名:密码 用base64算法进行编码后的字符串放在HTTP Request中的Heather Authorization 域里发送给服务端,服务端收到后进行解码,获取用户名和密码。this

三、最严格的HTTPS证书认证:基于CA根证书签名的客户端身份认证方式编码

 

受权「Authorization」

认证只是确认通讯的双方都是可信的,能够相互通讯。而受权是肯定请求方有哪些资源的权限。API Server目前支持以下几种受权策略(经过API Server的启动参数 --authorization-mode 设置)spa

  • AlwaysDeny:表示拒绝全部请求。仅用于测试
  • AlwaysAllow:表示容许全部请求。若是有集群不须要受权流程,则能够采用该策略
  • Node:节点受权是一种特殊用途的受权模式,专门受权由 kubelet 发出的 API 请求
  • Webhook:是一种 HTTP 回调模式,容许使用远程 REST 端点管理受权
  • ABAC:基于属性的访问控制,表示使用用户配置的受权规则对用户请求进行匹配和控制
  • RBAC:基于角色的访问控制,默认使用该规则

 

RBAC受权模式

RBAC(Role-Based Access Control)基于角色的访问控制,在Kubernetes 1.5 中引入,现为默认标准。相对其余访问控制方式,拥有以下优点:插件

一、对集群中的资源和非资源均拥有完整的覆盖code

二、整个RBAC彻底由几个API对象完成,同其余API对象同样,能够用kubectl或API进行操做

三、能够在运行时进行操做,无需重启API Server

 

RBAC API类型

RBAC API 所声明的四种顶级类型【Role、ClusterRole、RoleBinding 和 ClusterRoleBinding】。用户能够像与其余 API 资源交互同样,(经过 kubectl API 调用等方式)与这些资源交互。

 

Role 和 ClusterRole

在 RBAC API 中,一个角色包含一组相关权限的规则。权限是纯粹累加的(不存在拒绝某操做的规则),即只能给权限累加,不存在给了XX权限,而后去掉XX01权限的状况。角色能够用 Role 来定义到某个命名空间(namespace)上, 或者用 ClusterRole 来定义到整个集群做用域(全部namespace)

一个 Role 只能够用来对某一命名空间中的资源赋予访问权限。

 

Role示例:

定义到名称为 “default” 的命名空间,能够用来授予对该命名空间中的 Pods 的读取权限:

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: Role
3 metadata:
4   name: pod-reader
5   namespace: default
6 rules:
7 - apiGroups: [""] # "" 指定核心 API 组
8   resources: ["pods"]
9   verbs: ["get", "watch", "list"]

ClusterRole 能够授予的权限和 Role 相同,可是由于 ClusterRole 属于集群范围,因此它也能够授予如下访问权限:

  • 集群范围资源 (好比 nodes访问)
  • 非资源端点(好比 “/healthz” 访问)
  • 跨命名空间访问的有名称空间做用域的资源(如 Pods),好比运行命令kubectl get pods --all-namespaces 时须要此能力

 

ClusterRole示例

可用来对某特定命名空间下的 Secrets 的读取操做受权,或者跨全部名称空间执行受权(取决于它是如何绑定的):

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: ClusterRole
3 metadata:
4   name: secret-reader
5   # 此处的 "namespace" 被省略掉是由于 ClusterRoles 是没有命名空间的。
6 rules:
7 - apiGroups: [""]
8   resources: ["secrets"]
9   verbs: ["get", "watch", "list"]

 

RoleBinding 和 ClusterRoleBinding

角色绑定(RoleBinding)是将角色中定义的权限赋予一个用户或者一组用户。 它包含若干主体【subjects】(users、groups或 service accounts)的列表和对这些主体所得到的角色引用。

可使用 RoleBinding 在指定的命名空间中执行受权,或者在集群范围的命名空间使用 ClusterRoleBinding 来执行受权。

一个 RoleBinding 能够引用同一的命名空间中的 Role。

RoleBinding示例

将 “pod-reader” 角色授予在 “default” 命名空间中的用户 “jane”; 这样,用户 “jane” 就具备了读取 “default” 命名空间中 pods 的权限。

在下面的例子中,角色绑定使用 roleRef 将用户 “jane” 绑定到前文建立的角色 Role,其名称是 pod-reader

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 此角色绑定,使得用户 "jane" 可以读取 "default" 命名空间中的 Pods
 3 kind: RoleBinding
 4 metadata:
 5   name: read-pods
 6   namespace: default
 7 subjects:
 8 - kind: User
 9   name: jane # 名称大小写敏感
10   apiGroup: rbac.authorization.k8s.io
11 roleRef:
12   kind: Role #this must be Role or ClusterRole
13   name: pod-reader # 这里的名称必须与你想要绑定的 Role 或 ClusterRole 名称一致
14   apiGroup: rbac.authorization.k8s.io

roleRef 里的内容决定了实际建立绑定的方法。kind 能够是 Role 或 ClusterRole,name 是你要引用的 Role 或 ClusterRole 的名称。

RoleBinding 也能够引用 ClusterRole,这能够容许管理者在 整个集群中定义一组通用的角色,而后在多个命名空间中重用它们。

 

RoleBinding示例2

下面的例子,RoleBinding 引用的是 ClusterRole, “dave” (subjects区分大小写)将只能够读取在”development” 名称空间( RoleBinding 的命名空间)中的”secrets” 。

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 这个角色绑定容许 "dave" 用户在 "development" 命名空间中有读取 secrets 的权限。 
 3 kind: RoleBinding
 4 metadata:
 5   name: read-secrets
 6   namespace: development # 这里只授予 "development" 命名空间的权限。
 7 subjects:
 8 - kind: User
 9   name: dave # 名称区分大小写
10   apiGroup: rbac.authorization.k8s.io
11 roleRef:
12   kind: ClusterRole
13   name: secret-reader
14   apiGroup: rbac.authorization.k8s.io

最后,ClusterRoleBinding 可用来在集群级别并对全部命名空间执行受权。

 

ClusterRoleBinding示例
 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 这个集群角色绑定容许 "manager" 组中的任何用户读取任意命名空间中 "secrets" 3 kind: ClusterRoleBinding
 4 metadata:
 5   name: read-secrets-global
 6 subjects:
 7 - kind: Group
 8   name: manager # 名称区分大小写
 9   apiGroup: rbac.authorization.k8s.io
10 roleRef:
11   kind: ClusterRole
12   name: secret-reader
13   apiGroup: rbac.authorization.k8s.io

当咱们建立binding后,则不能修改binding所引用的Role或ClusterRole。尝试修改会致使验证错误;若是要改变binding的roleRef,那么应该删除该binding对象而且建立一个新的用来替换原来的。

 

Referring to resources【资源引用】

Kubernetes集群内一些资源通常以其名称字符串来表示,这些字符串通常会在API的URL地址中出现;同时某些资源也会包含子资源,例如pod的logs资源就属于pods的子资源,API中URL样例以下:

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

在这种状况下,”pods” 是有名称空间的资源,而 “log” 是 pods 的子资源。在 RBAC 角色中,使用”/“分隔资源和子资源

容许一个主体(subject)要同时读取 pods 和 pod logs,你能够这么写:

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: Role
3 metadata:
4   namespace: default
5   name: pod-and-pod-logs-reader
6 rules:
7 - apiGroups: [""]
8   resources: ["pods", "pods/log"]
9   verbs: ["get", "list"]

对于某些请求,也能够经过 resourceNames 列表按名称引用资源。

例如:在指定时,能够将请求类型限制到资源的单个实例。限制只能够 “get” 和 “update” 到单个configmap,则能够这么写:

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 kind: Role
 3 metadata:
 4   namespace: default
 5   name: configmap-updater
 6 rules:
 7 - apiGroups: [""]
 8   resources: ["configmaps"]
 9   resourceNames: ["my-configmap"]
10   verbs: ["update", "get"]

须要注意的是,create 请求不能被 resourceName 限制,由于在鉴权时还不知道对象名称。 另外一个例外是 deletecollection。

 

Referring to subjects【主体引用】

RoleBinding或ClusterRoleBinding绑定一个role到主体(subjects)。主体(subjects)能够是groups,users或ServiceAccounts。

Kubernetes将用户名表示为字符串。这些能够是:普通名称,好比“alice” ;邮件风格的名字,好比“bob@example.com” ;或表示为字符串的数字用户id。

注意:前缀 system: 是保留给Kubernetes系统使用的,所以应该确保不会出现名称以system: 开头的用户或组。除了这个特殊的前缀,RBAC受权系统不要求用户名使用任何格式。

ServiceAccounts具备前缀为system:serviceaccount: 的名称,属于具备前缀为system:serviceaccounts:的名称的组。

RoleBinding的示例

下面的示例只是展现 RoleBinding 中 subjects 的部分。

用户的名称为 “alice@example.com” :

1 subjects:
2 - kind: User
3   name: "alice@example.com"
4   apiGroup: rbac.authorization.k8s.io

 

组的名称为 “frontend-admins” :

1 subjects:
2 - kind: Group
3   name: "frontend-admins"
4   apiGroup: rbac.authorization.k8s.io

 

默认service account在 kube-system 命名空间中:

1 subjects:
2 - kind: ServiceAccount
3   name: default
4   namespace: kube-system

 

在名称为 “qa” 命名空间中全部的服务帐号:

1 subjects:
2 - kind: Group
3   name: system:serviceaccounts:qa
4   apiGroup: rbac.authorization.k8s.io

 

在任意名称空间的全部service accounts:

1 subjects:
2 - kind: Group
3   name: system:serviceaccounts
4   apiGroup: rbac.authorization.k8s.io

 

全部认证过的用户(版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:authenticated
4   apiGroup: rbac.authorization.k8s.io

 

全部未认证的用户(版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:unauthenticated
4   apiGroup: rbac.authorization.k8s.io

 

全部用户 (版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:authenticated
4   apiGroup: rbac.authorization.k8s.io
5 - kind: Group
6   name: system:unauthenticated
7   apiGroup: rbac.authorization.k8s.io

 

准入控制

准入控制是API Server的插件集合,经过添加不一样的插件,实现额外的准入控制规则。甚至于API Server的一些主要的功能都须要经过Admission Controllers实现,好比:ServiceAccount。

查看哪些插件是默认启用的:

kube-apiserver -h | grep enable-admission-plugins

 

在 1.17 中,它们是:

1 NamespaceLifecycle, LimitRanger, ServiceAccount, 
2 TaintNodesByCondition, Priority, DefaultTolerationSeconds, 
3 DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, 
4 MutatingAdmissionWebhook, ValidatingAdmissionWebhook, RuntimeClass, ResourceQuota

 

部分插件功能:

NamespaceLifecycle

该准入控制器禁止在一个正在被终止的 Namespace 中建立新对象,并确保使用不存在的 Namespace 的请求被拒绝。该准入控制器还会禁止删除三个系统保留的命名空间,即 default、kube-system 和 kube-public。

删除 Namespace 会触发删除该命名空间中全部对象(pod、services 等)的一系列操做。为了确保这个过程的完整性,咱们强烈建议启用这个准入控制器。

LimitRanger

该准入控制器会观察传入的请求,并确保它不会违反 Namespace 中 LimitRange 对象枚举的任何约束。

ServiceAccount

该准入控制器实现了 serviceAccounts 的自动化。 若是打算使用 Kubernetes 的 ServiceAccount 对象,强烈建议您使用这个准入控制器。

ResourceQuota

该准入控制器会监测传入的请求,并确保它不违反任何一个 Namespace 中的 ResourceQuota 对象中枚举出来的约束。

相关阅读

一、官网:使用 RBAC 鉴权

相关文章
相关标签/搜索