玩转 Kubernetes 权限控制 AuthN/Z

2017-10-18


摘要

AuthN/Z 是系统设计中相当重要的一环,它在很大程度上决定了 Kubernetes 能否成为一个企业级的解决方案。然而,严格的权限管理也给 Kubernetes 的使用带来了一定的麻烦,大大提高了 Kubernetes 的入门门槛。

本文旨在帮助大家系统地认识 Kubernetes 的 AuthN/Z 的功能和实现。希望大家在部署和使用 Kubernetes 的过程中不会掉入权限的泥沼。


Kubernetes AuthZ/N 系统简介

首先简单介绍一下 AuthN/Z 的异同及在 Kubernetes 内的实现。AuthN 系统主要用于认证 (Authentication),决定谁访问了系统。AuthZ 系统主要用于授权 (Authorization),决定访问者具有什么样的权限。



在 Kubernetes 系统中,AuthN 完成了用户的认证并且获取了用户的相关信息(如 Username,Groups 等)。而 AuthZ 则根据这些信息匹配预定义的权限规则,然后决定某个 API 请求是否被允许。


AuthN 系统

Kubernetes 的 AuthN 系统主要完成了以下工作:

  • 根据配置验证用户凭证,通常是 Bearer Token 或者 Basic Auth Password。
  • 解析用户信息,包括 Username,Groups,Uid 等。这些信息将用于之后的 Authz 系统授权。


X509 Client Certs —— Client Certs 模式

通过传入 --client-ca-file 到 Apiserver 开启。其中证书的 /CN (common name)表示用户名,/O (organization)表示 Groups。

Client Cert 模式通常用于某些受信任的组件访问 Apiserver,如 Kubernetes 各个组件访问 Apiserver。


Static Token File —— 静态 Token 文件模式

通过传入 --token-auth-file 到 Apiserver 开启。以下是其中一条记录的模版。HTTP 请求在 Header 中传入 Authorization: Bearer Token 来认证。


Static Password File —— 静态 Password 文件模式

通过传入 --basic-auth-file 到 Apiserver 开启。以下是其中一条记录的模版。HTTP 请求在 Header 中传入 Authorization:Basicbase64(user:password)来认证。


Service Account Tokens

Service Account Token 主要是用来给 Pod 提供访问 Apiserver 的权限。当 Pod 通过 Service Account 访问 Apiserver 时,用户名为 system:serviceaccount: (NAMESPACE):(SERVICEACCOUNT),并且属于system: serviceaccounts和system: serviceaccounts:(NAMESPACE) 这两个 Group。当一个 Pod 使用 InClusterConfig 创建 Client 访问 Apiserver 时,Client 会自动载入 Service Account 的 Token。


OIDC Token

OIDC 是除了 WebHook 外 Kubernetes 提供的唯一一个动态的 AuthN 方案。相比较于上面几种方案的小打小闹,OIDC 提供了标准的 AuthN 流程,真正能够作为 Kubernetes 系统用户认证的企业级解决方案。


OpenID Connect 协议是基于 Oauth2.0 协议之上的一个认证协议。OIDC 的认证流程跟 Oauth2.0 类似,不过除了返回 access_token 以外还返回了 id_token。Kubernetes 使用id_token 来认证用户。OIDC 协议中的 id_token 根据 JWT (Json Web Token) 协议标准实现。Kubernetes 通过 id_token 的 Claim 获取用户信息。比如 Groups, Username 等。


以下是 OIDC 认证的流程:


图片来自https://kubernetes.io/docs/admin/authentication


Apiserver 需要配置以下参数:



为了防止不同的 Issuer 导致的用户名冲突,当 --oidc-username-claim 取值不是 Email 时,AuthZ 所使用的真正的用户名会加上 Issuer 前缀,如下所示:

不过 1.8 后添加了 Claim Prefix 的参数 --oidc-username-prefix 和 --oidc-groups-prefix,显然上面这种丑陋的格式总是会让人很不高兴。


Webhook

当你需要外接一个用户系统的时候,你总是需要一个 Webhook。

通过传入 --authentication-token-webhook-config-file 开启,另外还要添加 

--runtime-config=authentication.k8s.io/v1beta1=true。

Webhook 的配置文件如下:


Webhook Service 需要实现 TokenReview 的接口:


AuthZ 系统

Kubernetes 的 AuthZ 系统主要完成了以下几件事情:

解析 HTTP 请求,获取请求的各种属性

根据属性和 AuthN 获取的用户信息,依次匹配 AuthZ 规则,如果成功则通过,如果全部失败则返回禁止访问。

不同于 AuthN 方案,AuthZ 方案在 Kubernetes 中和其 API 风格有相当大的关联。由于严格遵循 RESTful 标准定义 API,Kubernetes 在提取 HTTP 请求属性和定义 AuthZ 规则等方面有了极大的便利。

AuthZ 系统的核心接口如下:

(/apiserver/pkg/authorization/authorizer/interfaces.go)


每一个 http 请求都会创建一个 Attributes,从该接口的定义可以发现,Kubernetes 将 http 请求的 Path 参数解析并分解成 APIGroup, APIVersion 等属性。然后 Authorizer 根据这些属性匹配对应的规则完成 Authz。

下面是 Kubernetes 提供的两种 AuthZ 方案 —— ABAC 和 RBAC。


ABAC

ABAC 全称 Attribute Based Access Control(基于属性的访问控制)。通过 --authorization-mode=ABAC 开启,并且通过 --authorization-policy-file 指定策略文件。


以下是 ABAC 的一条记录的例子:


可以发现 ABAC 定义的字段基本上就是来自于上述的 Attributes 接口能够获取的信息。另外值得一提的是 Kubernetes 中的 ABAC 没有动态方案,修改策略文件后必须重启 Apiserver。


RBAC

RBAC 全称 Role Based Access Control(基于角色的访问控制), 通过 --authorization-mode=RBAC 开启。

目前和 RBAC 相关的 Resource 有以下 4 种:

Role

RoleBinding

ClusterRole

ClusterRoleBinding


Role 和 RoleBinding 是 NameSpace 下的资源,而 ClusterRole 和 ClusterRoleBinding 是系统级的资源。1.8 后 RBAC 所属的资源已经从 v1beta1 升级到 v1。


Role


Role 的例子如下:


ClusterRole

ClusterRole 的例子如下:


ClusterRole 可以用来定义全局的 Resource。当使用 ClusterRoleBinding 绑定时,表示能访问所有 NameSpace 下的资源(如上述的 secrets),当使用 RoleBinding 绑定时,表示只能访问 RoleBinding 所属的 NameSpace 下的资源。



RoleBinding

RoleBinding 的例子如下:

RoleBinding 负责绑定 Subjects 和某一个 Role 或者 ClusterRole。



ClusterRoleBinding

ClusterRoleBinding 的例子如下:

ClusterRoleBinding 能够绑定 Subjects 和 ClusterRole。



Subjects

Subjects 分为以下 3 种类型,Subjects 来自于 AuthN 的结果。

  • User
  • Group
  • ServiceAccount


Webhook

AuthZ 系统也可以通过 Webhook 实现。不过比起 AuthN,AuthZ 系统通常没有必要使用 Webhook。


通过传入 --authorization-webhook-config-file 开启,另外还要添加 

--runtime-config=authorization.k8s.io/v1beta1=true。



Webhook 的配置文件如下:


Webhook Service 需要实现 SubjectAccessReview 的接口


总结

Kubernetes 的 AuthN 系统主要是认证用户并获取用户对应的 Subject。比如 User,Group,ServiceAccount。而 AuthZ 系统主要是根据用户的 Subject 和 http 请求获取的属性依次匹配定义的规则(ABAC 或 RBAC)。


目前而言 Kubernetes 的 RBAC 系统能够较好的处理大部分的授权问题,不过也有一定的缺点,比如只能定义用户是否有 LIST 资源的权限,而无法定义用户 LIST 一部分资源的权限。在真正使用 Kubernetes 的 AuthZ 系统的时候建议以 NameSpace 为粒度做权限控制。

结合谷歌十年容器实践,基于国内大型企业落地经验打造 的容器集群智能云平台。

立即体验