互联网技术 / 互联网资讯 · 2023年12月14日

基于标签的权限控制的Kubernetes实现使用Webhook

Kubernetes支持名称空间级别的权限控制。在AkRAIno ICN项目中,我们有一些高级权限要求:多个用户可以在同一名称空间中创建,更新或删除一种资源,但不能更新或删除其他人创建的对象。

为了满足这一要求,我们使用Webhook在Kubernetes中设计并实现了基于标签的权限控制机制。Webhook通常用于验证资源或设置资源的默认值。在本文中,我们使用webhook来控制权限。

许可系统的设计

在Kubernetes中,用户或服务帐户可以绑定到一个或多个角色。每个角色定义其权限规则。例如,以下定义要求sdewan-test角色可以在默认名称空间中创建或更新类型为Mwan3Rule的自定义资源实例(CR),并且可以获取Mwan3Policy CR。

我们使用json格式的注释sdewan-bucket-type-permission扩展了角色。

在注释中,我们可以定义基于标签的权限。例如,下面显示的角色扩展了sdewan-test角色权限:sdewan-test只能创建/更新带有标签sdewan-bucket-type=app-intent或sdewan-bucket-type=k8s-service的Mwan3Rule(json键指定自定义资源类型)CR。而且它只能获得带有标签sdewan-bucket-type=app-intent的Mwan3Policy CR。

实际上,我们也支持通配符匹配。例如,我们可以使用Mwan3*来同时匹配Mwan3policies和Mwan3Rules。

Kubernetes Webhook负责解析角色注释。让我用简单的词来描述什么是准入webhook。我们可以将webhook视为Web服务,通常它在Kubernetes集群中作为pod运行。

当Kubernetes API收到请求时,kube-API可以在将对象保存到etcd中之前调用webhook API。如果webhook返回allowed=True,则kube-API继续将对象持久保存到etcd中。否则,kube-API拒绝该请求。

Webhook请求主体具有一个名为UserInfo的字段,该字段指示谁在发出Kubernetes API请求。从用户信息中,webhook可以获取角色信息,然后获取角色注释。通过将注释中描述的标签级别权限与CR标签进行比较,webhook可以决定是否允许该请求。

实施权限控制系统

我们已经通过AkRAIno ICN项目中的kubebuilder框架实现了基于标签的权限系统。这里的假设是已经实现了一些自定义资源定义(CRD)(例如Mwan3Policy和Mwan3Rule)和相应的控制器。

Kubebuilder可以生成基本的CRD,控制器代码和Webhook代码。要创建一个新的webhook,我们运行以下kubebuilder命令:

此命令利用controller-runtime builder来创建验证Webhook。该命令还会创建webhook server,该server接受来自kube-API服务器的https请求。它甚至生成解析http请求正文并将其转换为CRD结构实例的代码。

开发人员只需要编写代码来验证CRD实例内容。这对于大多数Webhook情况都是有用的。但这不能满足我们的要求,因为我们需要位于https请求正文中的UserInfo而不是CRD实例。

使用Webhook为Kubernetes实现基于标签的权限控制

我们重用了kubebuilder生成的webhook server,但自己实现了处理程序。处理程序接受“admission.request”作为输入,其中包含UserInfo。在处理程序中,我们获得用户角色信息和CR标签。

获取用户角色信息。

Userinfo在请求正文中。为了从Userinfo获取角色信息,处理程序必须向kube-API请求用户的角色信息。处理程序使用serviceaccount令牌作为身份验证将请求发送到kube-API。首先,处理程序发送一个请求以获取用户的角色绑定信息。然后,它发送第二个请求以从角色绑定信息中获取角色信息。默认情况下,角色绑定资源在“.subjects”字段上没有索引器,这意味着我们无法在kube-API请求中过滤角色绑定,除非我们为角色绑定添加以下索引器:

获取CR信息

来自用户的请求可能是创建,更新或删除资源。对于创建或更新请求,处理程序从请求正文中提取CR信息。对于删除请求,处理程序只能获取CR名称,而不能获取整个实例。因此需要调用kube-API来获取CR信息

考虑角色和ClusterRole

除了角色外,还可以在ClusterRole中定义用户权限。区别在于,角色始终在单个名称空间中定义权限,而ClusterRole可以在整个群集中定义权限。因此,我们还需要检查ClusterRole中的注释。解析角色信息时,我们只关心与CR具有相同名称空间的角色。

测试与实验

现在,我要介绍如何测试和试验基于标签的权限。在ICN中,此功能是通过kubebuilder与某些CRD/控制器一起开发的。Webhook支持https,但不支持http。因此,我们需要Webhook server的认证。

我们使用cert-Manager插件来填充Webhook server的证书。同时,我们还将证书注入到webhook配置中,以便kube-API在发送webhook请求时可以使用证书。对于开发或本地测试用例,其中Webhook从本地而不是Pod运行,我们需要手动配置证书。

一旦建立了网络连接,我们就可以为测试创建角色和角色绑定。让我们创建以下角色并将其绑定到用户。

允许用户创建标签为“sdewan-bucket-type:app-intent”的Mwan3policies,但不能创建其他标签。这里一个具体的例子是,用户可以创建下面左边的CR,而不是下面右边的CR。

如果我们尝试创建下面右边的CR,则会收到错误消息“ERROR FROM SERVER (Your Roles don’t have the permission): Error when creating “config/samples/BATch_v1alpha1_Mwan3policy.yaMl”。

使用Webhook为Kubernetes实现基于标签的权限控制

结论

Webhook是Kubernetes的一个很好的功能,它赋予Kubernetes更大的灵活性。开发人员可以使用它来实现许多有用的功能。

Controller-Runtime项目提供了builder工具,通过它我们可以轻松创建两种类型的Webhook:验证Webhook和Mutating Webhook。验证Webhook用于验证kube-API的资源,而Muting Webhook可以更新资源字段的值,例如设置默认值。

有时,这两种类型的Webhook都不符合我们的要求。在本文中,我们需要获取不在资源正文中的Userinfo。在这种情况下,我们需要自行开发大多数处理程序代码,而不是使用builder工具。

OpenMagic API

Need more than content? Move into the product flow.

If you are here for model access, pricing, developer docs, or the future API console, the dedicated product path now lives on api.openmagic.ai.

登录免费注册