背景知识调查
K8s的多租户管理和资源控制
K8s使用namespace进行资源隔离,实现多个用户共享同一集群的目标。用户在请求K8s的APIServer时,需要先经过认证和授权两个步骤。认证授权通过之后会来到资源配额审核阶段,审核通过之后,用户的请求才会被接受。
K8s的认证与授权模式
认证的目的是为了验证请求的用户是其所声明的用户,授权的目的是判断用户是否有执行该API请求的权限。这里关心的重点是授权模式。K8s支持4种授权模式,分别为:始终允许、始终拒绝、Attribute-Based Access Control(ABAC)、WebHook。其中ABAC基于属性的访问控制是比较常用的授权访问控制模式。
ABAC授权模式
ABAC授权涉及到的属性有如下几个
- user 标识发起请求的用户。
- group 标示用户所属的组
- request 包括request path和request verb。
- resource 标示要访问的K8s资源的类型,仅针对于和资源相关的API请求
- namespace 标示要访问的资源对象所在的namespace,仅针对于和资源相关的API请求
- API group 用于标识API组,仅针对于和资源相关的API请求
在授权过程中就是将API中所携带的信息和访问控制规则文件中对应规则一条一条匹配的过程,匹配成功即该请求可以得到执行,和portainer的权限管理也有点相似。
RBAC授权模式
Role-Based Access Control (RBAC) 授权模式在《Docker 容器与容器云 第二版》中没有提到的,但是被工业界广泛使用的授权模式,一种基于企业中用户的角色来调节控制对计算机或网络资源的访问方法。授权思想如下:通过Role 和 ClusterRole 声明角色和角色所包含的权限。通过RoleBinding 和ClusterRoleBinding 将角色中定义的权限赋予给一个或者一组用户组(包含用户、组和服务账户)。参考文档
- Role 一个Role,只可以用来对某一命名空间中的资源赋予访问权限
- Cluster Role 可以授权的权限包含Role可以赋予的权限,此外还包括集群的权限。TODO
- RoleBinding 在指定的命名空间中给用户授予Role或者Cluster Role的权限
- ClusterRoleBinding 可以在集群的级别对所有的命名空间进行授权
K8s的多维资源管理机制
多维资源管理机制的思想和授权的思想类似,框架预留出了一个接口,用户可以在其中进行二次开发,也可以使用K8s提供的默认审核函数。涉及到的资源管理维度以及常见的默认函数,TODO
Rancher
Rancher是一个开源的企业级容器管理平台。通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。
Rancher组成
基础设施编排
Rancher提供的基础设施包括网络、存储、负载均衡、DNS和安全模块。
容器编排与调度
Rancher包含主流的容器编排调度引擎,其中就包括K8s和Docker Swam等。
应用商店
可以一键部署由多个容器组成的应用
企业级权限管理
Rancher支持Active Directory,LDAP, Github等认证方式,同时还支持在环境级别的角色访问控制,可以通过角色来配置某个用户或者用户组对开发环境或者生产环境的访问权限。
Rancher整体架构
Rancher接管集群的方式
通过查看Rancher提供的管理集群的配置文件,大概总结一下Rancher接管集群的方式,配置文件示例
- 创建了ClusterRole的角色,赋予了某些权限之后绑定到给了用户kube-apiserver
- 创建了名为cattle-system的命名空间
- 创建了ClusterRole的角色,拥有集群的所有权限,并绑定给了服务账号cattle
- 创建了Development的资源,名为cattle-cluster-agent,猜测是在Rancher和K8s之间的代理服务
- 创建了DaemonSet的资源,用于监管集群状态
Refunc权限相关情况 ! ! Refunc 已商用😢
目前从公共集群上能拉取到的个人认证信息是Rancher的连接信息,其中包含了集群的服务地址是Rancher的地址,用户的账号和密码信息也同样是Rancher的。
在使用kubectl创建xenvs类型的资源的时候,遇到的错误信息如下。
1 | Error from server (Forbidden): error when creating "https://github.com/refunc/lambda-python3.7-example/releases/download/v0.0.2/xenv.yaml": xenvs.k8s.refunc.io is forbidden: User "u-lb22b3ju55" cannot create resource "xenvs" in API group "k8s.refunc.io" in the namespace "refunc-play" |
查看创建Refunc环境时的配置文件中和授权相关的部分。Refunc创建了服务账号refunc并绑定了集群的管理权限,通过和Rancher类比,这个账号也使得Refunc得到了集群管理的权限。之前认为此处就是用户权限管理是错误的。
1 | apiVersion: v1 |
从Rancher服务的大致信息中猜测:通过配置文件中的配置使得代理服务cattle-cluster-agent有了可以管理K8s集群的最高权限,之后的用户角色与用户信息应该是Rancher代理传递到K8s集群中或者Rancher实现了授权的WebHook,从而直接接管K8s。
解决办法
从上述情况和背景知识中,可以从总结出,因为Refunc自定义了资源类型,在Rancher接管的时候,这些类型的资源的权限没有进行妥善的管理,从而导致了Rancher的用户即使拥有project 的Project Owner 的权限,也无法使用Refunc的自定义资源。解决办法:Security->Roles->Projects中添加新的Role, 命名为Refunc,继承Project Owner的基础上在赋予k8s.refunc.io API Groups的所有动作权限。最后将用户在Project中的Role改成Refunc,用户就可以拥有操作Refunc的权限。操作截图如下。
反思总结
至此Refunc在Rancher中的权限问题得到了解决,通过此次问题排查,了解到了K8s在权限管理中的架构,通过三层审核机制,很好控制了是谁、能做什么、能不能做。在了解Rancher的过程中,学习到了一个第三方服务在K8s基础上进行二次开发的大概思路:设置一个拥有K8s所有权限的账户,结合K8s留出的插件位置和创建自定义资源来进行开发。最后感慨一下Rancher的权限管理也是非常的丰富,从让人眼花缭乱的列表中可以见得,其中的管理权限的维度十分值得学习。