用户使用 kubectl、客户端库或构造 REST 请求来访问 Kubernetes API。 人类用户和 Kubernetes 服务账户都可以被鉴权访问 API。 当请求到达 API 时,它会经历多个阶段,如下图所示:

api-server 是访问和管理资源对象的唯一入口。任何一个请求访问 api-server,都要经过下面的三个流程:
所有 Kubernetes 集群都有两类用户:由 Kubernetes 管理的服务账号(Service Account )和普通用户(User Accounts)。
Kubernetes 假定普通用户是由一个与集群无关的服务通过以下方式之一进行管理的:
有鉴于此,Kubernetes 并不包含用来代表普通用户账号的对象。 普通用户的信息无法通过 API 调用添加到集群中。
尽管无法通过 API 调用来添加普通用户, Kubernetes 仍然认为能够提供由集群的证书机构签名的合法证书的用户是通过身份认证的用户。 基于这样的配置,Kubernetes 使用证书中的 ‘subject’ 的通用名称(Common Name)字段 (例如,“/CN=bob”)来确定用户名。 接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对某资源执行特定的操作
与此不同,服务账号是 Kubernetes API 所管理的用户。它们被绑定到特定的名字空间, 或者由 API 服务器自动创建,或者通过 API 调用创建。服务账号与一组以 Secret 保存的凭据相关,这些凭据会被挂载到 Pod 中,从而允许集群内的进程访问 Kubernetes API。
Service Account 在不指定时,会自动帮我们创建一个default账号。它下面有三个组件管理:
Service Account Admission Controller:通过 Admission Controller 插件来实现对 pod 修改,它是 apiserver 的一部分。创建或更新 pod 时会同步进行修改 pod。当插件处于激活状态(在大多数发行版中都默认情况)创建或修改 pod 时,会按以下操作执行:
Token Controller:TokenController 作为 controller-manager 的一部分运行。异步行为:
Service Account Controller:Service Account Controller 在 namespaces 里管理ServiceAccount,并确保每个有效的 namespaces 中都存在一个名为 “default” 的 ServiceAccount。Kubernetes 集群安全的关键点在于如何识别并认证客户端身份,它提供了 3 种客户端身份认证方式:
① HTTP Base 认证:
用户名+密码 的方式进行认证。用户名:密码 用 BASE64 算法进行编码后的字符串放在 HTTP 请求中的 Header 的 Authorization 域里面发送给服务端。服务端收到后进行解码,获取用户名和密码,然后进行用户身份认证的过程。② HTTP Token 认证:
③ HTTPS 证书认证:
Kubernetes 使用 API 服务器对 API 请求进行鉴权。 它根据所有策略评估所有请求属性来决定允许或拒绝请求。 一个 API 请求的所有部分都必须被某些策略允许才能继续。 这意味着默认情况下拒绝权限。
当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。 如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。 如果所有模块对请求没有意见,则拒绝该请求。 被拒绝响应返回 HTTP 状态代码 403。
AlwaysDeny:表示拒绝所有请求,一般用于测试。
AlwaysAllow:允许接收所有的请求,相当于集群不需要授权流程(Kubernetes 默认的策略)。
ABAC:基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
Webhook:通过调用外部REST服务对用户进行授权。
Node:是一种专用模式,用于对 kubelet 发出的请求进行访问控制。
RBAC:基于角色的访问控制( kubeadm 安装方式下的默认选项)。
RBAC(Role Based Access Control):基于角色的访问控制,主要是在描述一件事情:给哪些对象授权了哪些权限。
RBAC 模型:

Kubernetes 中的 RBAC 也是基于 RBAC 模型扩展的,涉及到如下的概念:
RBAC 引入了 4 个顶级资源对象:
说明:为什么 Kubernetes 要设计 Role 、 ClusterRole ?
答:有些资源对象本身就不是 namespace(名称空间)的 ,所以 Kubernetes 增加了 ClusterRole,并且 ClusterRole 也可以管理名称空间下的资源对象。
一个角色就是一组权限的集合,这里的权限都是许可形式的(白名单)。
Role 的资源清单文件:
# 名称空间角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: xudaxian-role
namespace: default # 所属的名称空间
rules: # 当前角色的规则
- apiGroups: [""] # "" 标明 core API 组,默认留空即可。
resources: ["pods"] # 资源类型
verbs: ["get", "watch", "list"] # 资源的动作类型
说明:
kubectl api-resources 查看kubectl api-resources -o wide 查看ClusterRole 的资源清单文件:
# 集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: xudaxian-clusterrole
rules:
- apiGroups: [""] # "" 标明 core API 组,默认留空即可。
resources: ["namespaces"]
verbs: ["get", "watch", "list"]
注意:ClusterRole 不需要设置 namespace。
角色绑定用来把一个角色绑定到一个目标对象上,绑定目标可以是 User、Group 或者 ServiceAccount。
RoleBinding 资源清单文件:
# 账号和角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: xudaxian-rolebinding
namespace: default
subjects:
- kind: ServiceAccount # 账户类型
name: xudaxian # 账户名字,"name" 是区分大小写的
roleRef:
kind: Role
name: xudaxian-role # Role的名字
apiGroup: rbac.authorization.k8s.io # Api组
ClusterRoleBinding 资源清单文件:
# 账号和集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: xudaxian-clusterrolebinding
subjects:
- kind: ServiceAccount
name: xudaxian # "name" 是区分大小写的
namespace: default # 如果资源是某个 namespace 下的,那么就需要设置 namespace
roleRef:
kind: ClusterRole
name: xudaxian-clusterrole
apiGroup: rbac.authorization.k8s.io
创建 ServiceAccount 的时候,系统会在底层默认一个含 ServiceAccount 名称的 Secret 。
# 名称空间角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: xudaxian-role
namespace: default # 所属的名称空间
rules: # 当前角色的规则
- apiGroups: [""] # "" 标明 core API 组,默认留空即可。
resources: ["pods"] # 指定能操作的资源 ,通过 kubectl api-resources 查看即可。
# resourceNames: [""] # 指定只能操作某个名字的资源
verbs: ["get", "watch", "list"] # 操作动作,通过 kubectl api-resources -o wide 查看即可。
---
# 集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: xudaxian-clusterrole
rules:
- apiGroups: [""] # "" 标明 core API 组,默认留空即可。
resources: ["namespaces"]
verbs: ["get", "watch", "list"]
---
# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: xudaxian # ServiceAccount 的名称
namespace: default
---
# 账号和角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: xudaxian-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: xudaxian # "name" 是区分大小写的
roleRef:
kind: Role
name: xudaxian-role
apiGroup: rbac.authorization.k8s.io
---
# 账号和集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: xudaxian-clusterrolebinding
subjects:
- kind: ServiceAccount
name: xudaxian # "name" 是区分大小写的
namespace: default # 如果资源是某个 namespace 下的,那么就需要设置 namespace
roleRef:
kind: ClusterRole
name: xudaxian-clusterrole
apiGroup: rbac.authorization.k8s.io
参考:
https://www.yuque.com/fairy-era/yg511q/by6f82#c5351a01