查看原文
其他

玩转 Kubernetes 权限控制 AuthN/Z

刘搏 才云Caicloud 2020-02-25


刘搏

才云科技平台软件工程师


毕业于浙江大学

加入才云后先后从事 Kubernetes 监控和权限相关的工作


摘要

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 需要配置以下参数:


参数名

说明

–oidc-issuer-url

OIDC 服务访问地址,如 https://accounts.google.com

–oidc-client-id

OIDC 协议的 Client ID,和 Oauth2.0 的 Client_id 一样

–oidc-username-claim

用户名从哪个 Claim 获取,可以取 Sub, Email,  Name 等值

–oidc-groups-claim

用户所在的 Groups , 从 Groups 这个 Claim 里获取

–oidc-ca-file

用于信任 OIDC 服务的 https

为了防止不同的 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 为粒度做权限控制。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存